本站 2024 年招商持续进行中,欢迎各位老板前来投放:
https://blog.meathill.com/ad/advertise-on-this-site.html
刚才,群里有位同学提问:
我把我的分支合到 B 分支上了,然后另外一个同事将他的代码合到 B 分支将我的代码覆盖了,然后 B 分支又有很多提交记录,不能回退了,我的分支再合到 B 分支不显示冲突和修改了
大佬们,这种情况怎么解决呀
可能大家都有过被同事误操作丢失代码的经验吧,群里群情激愤,纷纷谴责起这位同事。也有不少同学七嘴八舌的开始支招,有说找责任人的,有说一个一个还原的,有说 rebase 的。大家很热心,可惜都没说到点子上。
要用好 Git,绝对不能靠背套路,更不能瞎试,成了也不知道咋成的,败了也不知道为啥不行。要理解 Git 的设计和实现,遇到问题先分析,再寻找最佳方案,然后小心谨慎的实施。
我们先分析一下问题的原因:
- 最大的可能是,同事合并代码时,遇到冲突,他在解决冲突时,选择保留自己的代码,丢弃了同学的代码(最恶心的情况)。
- 我们不考虑归责。同学现在要提交自己的代码,但是因为他的代码版本比较“旧”,所以 git 拒绝合并。也无法提交新的 PR。
- 如果前面推测没错,那么同事就不是用的
push -f
。 - 所以同学的代码应该有一部分在库里,只是冲突的部分可能没了。
如此一来,除了一个文件一个文件比对(效率太低),那么就是把所有修改全部找出来,然后做成新的提交。因为部分代码已经在库里,这部分代码大概率会直接被 git 接受;只有少部分之前冲突的代码需要解决之后才能提交,总量应该不多。所以,这该会是最快的方法。
想清楚该怎么做之后,就该制定方案了:
- 先备份代码。
- 回退到启动开发时,切出来的分支。假设 commit 是 b1:
git reset b1 --mixed
。这一步会将 b1 之后的变更,作为未提交的部分,集中起来,排除版本信息。 - 保留这部分的代码到暂存区:
git stash
。 - 切到开发分支的最新版本:
git checkout B
。 - 弹出暂存的代码
git stash pop
。 - 可能会失败,因为存在冲突。那就解决冲突。
- 解决冲突后,重新提交 PR,然后合并分支。
总结一下。Git 原理很简单:
- 按行对比。
- 每次提交都会产生新版本。
- 版本是单向的,Git 负责维护版本历史。
- 两个无法分辨先后的版本修改了同一行,就有冲突。Git 无法解决冲突,会交给人处理。
- 人处理后,产生新版本。
- 分支是指针,指向某个版本,并随提交自动前进。
在此基础上,可能衍生出各种问题,比如开头的那一幕。但是不管问题如何,都离不开根本原理。所以我们面对 Git 问题,不要背套路,要认真分析前因后果,然后选择解决方案,再根据方案制定流程。
希望这次分享对大家有帮助。如果你对 Git 操作还有什么不清楚不明白的,欢迎提问。如果我上文有错误,也欢迎指出。希望 2024,大家共同进步,再没有会乱搞别人代码的同事。
发表回复