git操作问题总结(一)

2,337 阅读7分钟

这是我参与2022首次更文挑战的第21天,活动详情查看:2022首次更文挑战

前言

今天我们总结一下Git操作时碰到的问题和解决办法,我们一起来看看吧!

commit报错无法提交

> running pre-commit hook: lint-staged
[STARTED] Preparing...
[FAILED] warning: LF will be replaced by CRLF in sh.exe.stackdump.
[FAILED] The file will have its original line endings in your working directory.
[STARTED] Running tasks...
[SKIPPED] Skipped because of previous git error.
[STARTED] Applying modifications...
[SKIPPED]
[SKIPPED]   × lint-staged failed due to a git error.
​
 × lint-staged failed due to a git error.
[STARTED] Cleaning up...
[SKIPPED]   × lint-staged failed due to a git error.
 Any lost modifications can be restored from a git stash:
​
​
pre-commit hook failed (add --no-verify to bypass)

解决方式

执行npm run lint, 根据提示修改错误(推荐)
git commit -m "" --no-verify 绕过了lint的检查

Git提交时出现(合并提示)Merge branch 'master' of ...之解决方法

多人协作开发项目,在上传代码时通常会先pull一下远程代码,使本地与远程同步更新,但是如果远程此时与自己代码存在冲突,在解决冲突后提交有时会出现“Merge branch ‘master’ of …”这条信息。这是因为pull其本质是fetch+Merge的结合。通常会分为以下两种情况:

1.如果远程分支超前于本地分支,并且本地也没有commit操作,此时pull会采用’fast-forward’模式,该模式不会产生合并节点,也即不产生"Merge branch ‘master’ of …"信息。

2.如果本地有commit提交,此时若存在冲突,pull拉取代码时远程和本地会出现分叉,会进行分支合并,就会产生"Merge branch ‘master’ of …"信息。

解决方法

使用git pull --rebase命令,如果没有冲突,则会直接合并,如果存在冲突,手动解决冲突即可,不会再产生那条多余的信息。如果你不想每次都rebase,可以在git bash里执行

git config --global pull.rebase true

这个配置就是告诉git在每次pull前先进行rebase操作。

① 可能出现的相关报错error:Cannot pull with rebase

  1. git 执行git pull –rebase后报错误如下:
error: cannot pull with rebase: Your index contains uncommitted changes.
error: please commit or stash them.
  1. 原因:如果有未提交的更改,是不能git pull的

  2. 解决:

  • 先执行git stash -->#可用来暂存当前正在进行的工作

  • 再执行git pull –-rebase

  • 最后再执行git stash pop -->#从Git栈中读取最近一次保存的内容

  1. 截图示例

image-20210705115521085

防止冲突的有效操作

不要直接用git pull拉取,而是分开操作,先拉取代码(拉取后可以先查看冲突部分取解决).随后再去合并

  1. git fetch 别名(将修改同步到远程跟踪分支上)
  2. git merge 远程跟踪分支

Git删除误提交的大文件历史记录

  1. 应用场景:在我们日常使用Git的时候,一般比较小的项目,我们可能不会注意到.git 这个文件。其实.git文件主要用来记录每次提交的变动,当我们的项目越来越大的时候,我们发现.git文件越来越大。很大的可能是因为提交了大文件,如果你提交了大文件,那么即使你在之后的版本中将其删除,但是实际上记录中的大文件仍然存在
  2. 原因分析:为什么呢?仔细想一想,虽然你在后面的版本中删除了大文件,但是Git是有版本倒退功能的吧,那么如果大文件不记录下来,git拿什么来给你回退呢?
  3. 导致的问题:.git文件越来越大导致的问题是--每次拉项目都要耗费大量的时间,并且每个人都要花费那么多的时间。
  4. git给出了解决方案,使用git branch-filter来遍历git history tree, 可以永久删除history中的大文件,达到让.git文件瘦身的目的。

下面给出步骤(以下步骤非常危险,操作需谨慎!,最好最好不要在公司项目中使用)

Ⅰ-列出仓库中最大的几个对象及其文件名

列出所有仓库中的对象(包括SHA值、大小、路径等),并按照大小降序排列,列出TOP 5(本人示例,你也可多展示)

  1. 命令示例
git rev-list --all --objects | grep "$(git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -n 5 | awk -F ' '  '{print $1}')"
  1. 图示

image-20210508171542001

Ⅱ-将某文件从历史记录中删除

既然文件找到了(此处删除杂记_其他(如破解与配置)的碎片化笔记/Typora笔记软件分享/tools/软件包/Typora.dmg),那么得将该文件从历史记录中删除,执行以下命令:

  1. 命令示例:
git log --pretty=oneline --branches -- "杂记_其他(如破解与配置)的碎片化笔记/Typora笔记软件分享/tools/软件包/Typora.dmg"
  1. 图示

image-20210508171916951

Ⅲ-重写所有 commit,将该文件从 Git 历史中完全删除

上面的命令执行后只是从历史记录中移除,还没有完全删除它,我们需要重写所有 commit,将该文件从 Git 历史中完全删除:

  1. 代码示例:
git filter-branch --index-filter 'git rm --cached --ignore-unmatch  "杂记_其他(如破解与配置)的碎片化笔记/Typora笔记软件分享/tools/软件包/Typora.dmg"' -- --all
  1. 图示

img

  1. 补充注意点:

如果你像我一样,工作区有新写的内容没有追踪与提交导致无法进行删除操作时,千万不要直接暂存stash,否则这些没有暂存的内容就没了,要记得先git add .

Ⅳ-把该文件的引用完全删除

上面的命令执行后,此时历史记录中已经没有该文件了,此时是真正删除了它。 不过我们运行 filter-branch 产生的日志还是会对该文件有引用,所以我们还需要运行以下几条命令,把该文件的引用完全删除:

  1. 命令示例:
rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now
git gc --aggressive --prune=now
  1. 图示

image-20210510183253770

  1. 果真编程其实殊途同归,该学的都得学,这里就暴露的Linux没学好的弊端,所以暗下决心,争取今年内将linux系统学习一遍

Ⅴ-强制提交

现在我们再看 .git 文件的大小明显变小了,少了那个大文件,说明我们之前误提交的大文件已经删除了。 最后一步就是 push 代码了,不过就是需要强制 push

  1. 命令示例
git push --force
  1. 图示

img

Ⅵ-远程仓库GC

网上所能百度的方法中都没有说到要进行远程存储库GC,但是本人操作后发现,明明命令行中运行了git gc,但你的远程仓库仍然会非常庞大甚至更加庞大,也许你本地已经删减至几十兆,但是远程仓库已经"爆仓"达到1300+兆,详见问题7

image-20210510180757993

Ⅶ-删除前后.git大小对比

本人此时测试删除的文件正好为10M,成功删除

  1. 删除前截图
  1. 删除后截图
  1. 删除多个文件后

git出现文件夹后面跟@+数字问题

  1. 问题出现场景:本人欲将两个仓库代码合到一个仓库中,但是原本文件夹内还有.git,导致这些文件夹push后变成了子模块
  2. 问题场景图例-->具体出问题时并没有截图,此处截图提交时差别(原本应该是一大堆V1.0的文件,结果只有一个文件夹,后面跟着哈希值)

image-20210510171915185

  1. 解决思路

删除原来的子文件夹的.git -->rm -r .git,当然也可以手动删除

删除本地git缓存 -->git rm -r --cached fileName

重新add,push

总结:由于篇幅问题,还有一些总结就在下一章,有兴趣可以看看哦