这是我参与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
- git 执行
git pull –rebase后报错误如下:error: cannot pull with rebase: Your index contains uncommitted changes. error: please commit or stash them.
原因:如果有未提交的更改,是不能git pull的
解决:
先执行
git stash-->#可用来暂存当前正在进行的工作再执行
git pull –-rebase最后再执行
git stash pop-->#从Git栈中读取最近一次保存的内容
- 截图示例
② 防止冲突的有效操作
不要直接用
git pull拉取,而是分开操作,先拉取代码(拉取后可以先查看冲突部分取解决).随后再去合并
git fetch 别名(将修改同步到远程跟踪分支上)- git merge 远程跟踪分支
Git删除误提交的大文件历史记录
- 应用场景:在我们日常使用Git的时候,一般比较小的项目,我们可能不会注意到.git 这个文件。其实.git文件主要用来记录每次提交的变动,当我们的项目越来越大的时候,我们发现.git文件越来越大。很大的可能是因为提交了大文件,如果你提交了大文件,那么即使你在之后的版本中将其删除,但是
实际上记录中的大文件仍然存在。- 原因分析:为什么呢?仔细想一想,虽然你在后面的版本中删除了大文件,但是Git是有版本倒退功能的吧,那么如果大文件不记录下来,git拿什么来给你回退呢?
- 导致的问题:.git文件越来越大导致的问题是--每次拉项目都要耗费大量的时间,并且每个人都要花费那么多的时间。
- git给出了解决方案,使用git branch-filter来遍历git history tree, 可以永久删除history中的大文件,达到让.git文件瘦身的目的。
下面给出步骤(以下步骤非常危险,
操作需谨慎!,最好最好不要在公司项目中使用)
Ⅰ-列出仓库中最大的几个对象及其文件名
列出所有仓库中的对象(包括SHA值、大小、路径等),并按照大小降序排列,列出TOP 5(本人示例,你也可多展示)
- 命令示例
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}')"
- 图示
Ⅱ-将某文件从历史记录中删除
既然文件找到了(此处删除
杂记_其他(如破解与配置)的碎片化笔记/Typora笔记软件分享/tools/软件包/Typora.dmg),那么得将该文件从历史记录中删除,执行以下命令:
- 命令示例:
git log --pretty=oneline --branches -- "杂记_其他(如破解与配置)的碎片化笔记/Typora笔记软件分享/tools/软件包/Typora.dmg"
- 图示
Ⅲ-重写所有 commit,将该文件从 Git 历史中完全删除
上面的命令执行后只是从历史记录中移除,还没有完全删除它,我们需要重写所有 commit,将该文件从 Git 历史中完全删除:
- 代码示例:
git filter-branch --index-filter 'git rm --cached --ignore-unmatch "杂记_其他(如破解与配置)的碎片化笔记/Typora笔记软件分享/tools/软件包/Typora.dmg"' -- --all
- 图示
- 补充注意点:
如果你像我一样,工作区有新写的内容没有追踪与提交导致无法进行删除操作时,千万不要直接暂存
stash,否则这些没有暂存的内容就没了,要记得先git add .
Ⅳ-把该文件的引用完全删除
上面的命令执行后,此时历史记录中已经没有该文件了,此时是真正删除了它。 不过我们运行 filter-branch 产生的日志还是会对该文件有引用,所以我们还需要运行以下几条命令,把该文件的引用完全删除:
- 命令示例:
rm -rf .git/refs/original/ git reflog expire --expire=now --all git gc --prune=now git gc --aggressive --prune=now
- 图示
- 果真编程其实殊途同归,该学的都得学,这里就暴露的Linux没学好的弊端,所以暗下决心,争取今年内将linux系统学习一遍
Ⅴ-强制提交
现在我们再看 .git 文件的大小明显变小了,少了那个大文件,说明我们之前误提交的大文件已经删除了。 最后一步就是 push 代码了,不过就是需要强制 push
- 命令示例
git push --force
- 图示
Ⅵ-远程仓库GC
网上所能百度的方法中都没有说到要进行远程存储库GC,但是本人操作后发现,明明命令行中运行了
git gc,但你的远程仓库仍然会非常庞大甚至更加庞大,也许你本地已经删减至几十兆,但是远程仓库已经"爆仓"达到1300+兆,详见问题7
Ⅶ-删除前后.git大小对比
本人此时测试删除的文件正好为10M,成功删除
- 删除前截图
- 删除后截图
- 删除多个文件后
git出现文件夹后面跟@+数字问题
- 问题出现场景:本人欲将两个仓库代码合到一个仓库中,但是原本文件夹内还有.git,导致这些文件夹push后变成了子模块
- 问题场景图例-->具体出问题时并没有截图,此处截图提交时差别(原本应该是一大堆V1.0的文件,结果只有一个文件夹,后面跟着哈希值)
解决思路
删除原来的子文件夹的.git -->
rm -r .git,当然也可以手动删除删除本地git缓存 -->
git rm -r --cached fileName重新add,push
总结:由于篇幅问题,还有一些总结就在下一章,有兴趣可以看看哦