在重新提交许多提交时如何防止许多 git 冲突?

Posted

技术标签:

【中文标题】在重新提交许多提交时如何防止许多 git 冲突?【英文标题】:How to prevent many git conflicts when rebasing many commits? 【发布时间】:2011-11-06 16:29:26 【问题描述】:

故事:在一个项目的中间,我的同事从 master 创建了一个新分支,并开始进行繁重的重构工作。我从 master 创建了我的分支,并开始在页面上做新的事情。我们定期提交,但只有我可以将代码 rebase 到 master(因为同事更改太重,还不能从 master 部署)。不幸的是,我们的一些工作依赖于相同的文件。因此,经过几天的工作,当她最终想将她的更改重新设置为 master 时,她遇到了很多 git 冲突。

my_branch    #---#----#-#-------#----#--#-----#---#----#----#
            /     \              \   \   \              \    \
master     *-------*--------------*---*---*--------------*----*----*
            \                                                     /
her branch   #------#-------#-----------#-----------#------------#

问题一是:当我们处理相同的文件时,如何防止大量的 git 冲突? (或者在这种情况下最好的做法是什么?)

但这不是我们问题的结束,...绝对正确,她尝试从 master 到她的分支进行变基(我提交了更改),所以提交映射应该是这样的

my_branch    #---#----#-#-------#----#--#-----#---#----#----#
            /     \              \   \   \              \    \
master     *-------*--------------*---*---*--------------*----*----*
            \                   \            \                    /
her branch   #------#-------#----*------#-----*-----#------------#

这就是困扰我们的地方。在这些变基期间,她正在解决这些冲突。但是 git 不记得她对冲突修复的决定,所以当她从 masterher-branch 进行另一个 git rebase 时,她必须修复相同的 git 冲突再次她在以前的变基中修复。

问题 2 是:如何告诉 git 在 master 分支的 git rebase 之后记住 git conflict fix,所以在下一次 rebase 之后我们不必修复相同的问题又冲突了?

【问题讨论】:

哦,我忘了,我的git版本:1.7.4.1,她应该是一样的 我想问的确切问题! 再更新一次 - 过去几年我只使用git merge 而不是git rebase。是的,有些人说使用merge 您没有正确的历史记录,这是不正确的。观看 youtube.com/watch?v=1ffBJ4sVUb4 以了解 git 中的一切是如何工作的(+ rebase 实际上可能具有破坏性)我的观点是 git merge 更有效率。我想这就是为什么 github 在处理拉取请求时也在他们的 Web 界面中使用 merge 的原因 @equivalent8 虽然它会让你的分支历史变得一团糟,但我更喜欢变基,因为它为我工作的功能分支创建了一个干净的 git 历史。 Git 合并非常适合拉取请求,因为它可以直观地表示拉取请求何时合并到主请求中。 @D.Foley 我完全同意,它更干净。对于超小型项目和我独自工作的项目,我也使用 rebase。但是对于有很多开发人员频繁提交的项目来说,使用merge 更为务实,否则每个人 10% 的时间将只是解决 rebase 冲突 【参考方案1】:

幸运的是,git 有一种机制可以准确地处理这个问题,称为git rerere - 本质上,如果您启用了git rerere,那么每次您解决冲突时,您以特定方式解决了该确切冲突的事实是记得。如果再次出现相同的冲突,则会自动使用相同的解决方案。下面有一些有用的文章:

http://scottchacon.com/2010/03/08/rerere.html(博文) http://git-scm.com/docs/git-rerere.html(手动输入) Are there any downsides to enabling git rerere?(*** 中的问题) http://progit.org/2010/03/08/rerere.html(原答案链接:好像坏了)

...但基本上你可以这样做:

git config --global rerere.enabled 1

...忘记它,同时享受更轻松的变基/合并:)

【讨论】:

只是为了添加您可能还想git config --global rerere.autoupdate true。此外,如果您希望团队中的其他人使用这些记录的解决方案,您可以与他们共享您的 .git/rr-cache 文件夹。干杯。 启用全局配置设置有什么缺点吗? @bryanbraun:是的,如果您以特定方式记录冲突的解决方案,它将在您下次看到确切的冲突时自动解决 - 如果您在一次错误的方式(无论可能是什么),您甚至可能不会注意到它在未来再次以这种方式自动解决...... 可以针对特定的分支进行吗?我不希望在整个项目中都使用冲突解决方案,但是如果我可以为此选择分支会感觉更安全【参考方案2】:

确保您始终使用--onto 开关进行变基。

为防止冲突,请使用浮动开发分支。每个开发人员都会不断地重新调整他们的开发分支。这很容易,因为开发人员知道他刚刚实现了什么并且解决冲突不应该有问题。而不是变基,只需合并最终版本(它已经变基了)。

【讨论】:

【参考方案3】:

您可以压扁她的分支以防止连续冲突解决。当您在从 master 创建到一个提交后将她的分支中的所有提交压缩到一个提交中时,可以一步解决冲突。

如果你想从头开始编写新的提交消息,这就足够了:

git reset --soft HEAD~3 &&
git commit

在本例中,我们将压缩最后 3 次提交。

为防止将来出现此问题,我建议您在每次提交后使用源分支重新定位您的分支。

【讨论】:

【参考方案4】:

让我分享一种解决变基冲突的可能方法。我称之为rebase via merge。如果您想对具有许多提交和预期许多冲突的分支进行变基,它会有所帮助。

首先,让我们创建一个temp 分支并强制所有冲突通过常规合并显示

git checkout -b temp
git merge origin/master

以常规方式解决所有冲突并完成合并。

所以temp 分支现在显示了正确解决所有冲突后项目的外观。

现在让我们检查你未修改的分支(让它成为alpha)。

git checkout alpha

并使用机械冲突自动解决进行变基以支持当前分支。

git rebase origin/master -X theirs

此时项目代码可能已损坏或无效。没关系,最后一步是通过一个额外的提交从temp 分支恢复项目状态

git merge --ff $(git commit-tree temp^tree -m "Fix after rebase" -p HEAD)

基本上,这一步使用低级 git 命令创建一个与temp 分支具有完全相同的项目状态(树)的新提交。新的提交会立即被合并。

就是这样。我们刚刚通过隐藏合并做了一个变基。并且temp分支可以删除。

git branch -D temp

此外,还有一个脚本可以交互地执行相同的操作。可以找到 here

【讨论】:

以上是关于在重新提交许多提交时如何防止许多 git 冲突?的主要内容,如果未能解决你的问题,请参考以下文章

git 提交冲突怎么办

git 把某次提交的代码重新提交到其他的分支

用于防止双重提交的纯 Java/JSF 实现

git如何避免代码冲突

如何在 git 中编辑不正确的提交消息(我已推送)?

如何在表单提交时防止表单在刷新时重新提交