处理从开发到掌握时的冲突

时间:2013-10-22 11:03:07

标签: git merge conflict git-merge merge-conflict-resolution

我开始了一个工作流程,我的目标是在development分支中执行所有新功能,master分支仅用于生产就绪代码。

执行以下操作后:

git checkout master
git merge staging

我收到了一堆看起来像这样的冲突:

CONFLICT (rename/add): Rename app/assets/stylesheets/mobile.css->app/assets/stylesheets/application.css in HEAD. app/...
CONFLICT (modify/delete): app/views/organizers/mobile.html.erb deleted in HEAD and modified in staging. Version stagi...
CONFLICT (modify/delete): app/views/events/mobile.html.erb deleted in HEAD and modified in staging. Version staging of app/v...

当我现在一直在谷歌搜索时,我读到的只是审查每个文件,解决冲突并提交更改。但是我没有看到做这一切的任何意义,因为我知道代码并且它只是相同代码集的进步。

如何以简单的方式将staging中所做的更改合并到master,而无需审核并解决每项更改?

4 个答案:

答案 0 :(得分:4)

这是一个复杂的问题,因为它基本上意味着git无法直观地弄清楚如何组合这两个分支。似乎某些文件已在master上删除,然后在staging中进行了修改(因此被master修改,而另一个文件已在staging中重命名,但已添加到git上。以下内容主要是在黑暗中拍摄,而您可能仍需要手动解决一些(但希望更少)冲突。

-s recursive可以选择合并的许多不同算法,因此我们将使用最简单,易于定制且通常默认使用的算法:递归策略。我们将使用git选项强制使用它。

帮助-Xdiff-algorithm=histogram的第一步是让它花更多时间来修改补丁,因此我们将使用选项git-merge。这将花费最长时间,但它会强制git-merge产生更好的差异输出(这有望减少冲突)。

下一步是告诉-Xpatience花更多时间进行正确的合并。我们将使用master选项来执行此操作。

由于staging将取决于重命名/修改的文件,而git将取决于旧文件,我们可以尝试欺骗-Xrename-threshold=100%认为文件不是真的使用选项100%重命名(以便文件必须相同才能被视为重命名)。请注意,您可能遗留了一些冗余文件,并且对需要知道其他文件名的文件所做的任何更改都不会记录旧名称(只是新名称),因此您可能需要返回并修复这些文件。我们完成了合并。您还可以将50%调整为更小的值(默认值为staging,这是当前导致问题的原因。)

现在要包含-Xtheirs所需的文件,我们可以使用以下选项强制添加它们:staging警告:此选项将默默忽略所有合并冲突,并默认使用git reset --hard HEAD^的内容。确保运行完整的测试套件以检查是否存在任何不一致。如果在合并后确实在测试套件中出现问题,请使用git checkout master git merge staging -s recursive -Xdiff-algorithm=histogram -Xpatience -Xrename-threshold=100% -Xtheirs 将其撤消,并在没有此选项的情况下重做合并。你可能会有少量的合并冲突,你必须手动解决,但你会知道错误的来源是其中一个(有限多个)冲突,这是从前面猜测的巨大飞跃调试器。

最后,我们把它们放在一起得到

master

最后,我建议你玩这些选项。花在合并上的额外时间可能会使最后两个选项无效(甚至使其变得更糟)。

将来,我建议您定期将git中的所有更改添加到您的主题分支。这不仅会更早地呈现冲突(因此一次冲突的次数也会更少),但它也会使您保持最新状态,甚至可以在冲突发生之前解决冲突。这是好的另一个原因是因为git-rerere有一个名为{{1}}的功能,它记录您手动解决的冲突,然后学习如何自动解决这些相同的冲突后来。因此,一旦您解决了一次,您将不必再次解决相同/类似的冲突。

答案 1 :(得分:3)

使用git merge选项,称为"策略" -s ours(或他们的)。这意味着git将更喜欢来自开发分支(或来自master)的更改。这意味着如果您在主服务器和临时表中有一个不同的代码字符串更改,则会进行暂存更改。 此外,我建议您使用--no-commit选项,这样您就可以在提交合并之前检查一次代码(不是每次更改)。

答案 2 :(得分:2)

我使用下一个策略。 首先,从develop分支checkout到other:

  git checkout -b feature/resolve-conflicts

下一步,您必须将代码从 master 拉入功能分支:

  git pull origin master

接下来解决冲突并将功能分支推送到git中:

  git add --all
  git commit -am 'resolve conflicts'
  git push -u origin feature/resolve-conflicts

然后创建拉取请求并将功能/解决冲突与主分支进行比较。在不同的平台上,它以不同的方式制作。将 feature 分支合并到 master 之后,然后创建新的 pull request 将 develop 分支合并到 master 分支。

现在,develop 中的更改通常必须通过提交合并到 master 分支中。

它对我有用,希望我能帮上忙。

答案 3 :(得分:0)

这是一个非常常见的问题,有一个简单的解决方案。一旦发生合并冲突,您可以通过

在文件到文件的基础上执行此操作
Keep master's file
git checkout --ours myfile.html

Keep development's file
git checkout --theirs myfile.html

很容易将其应用于整个文件夹

git checkout --ours ./
git checkout --theirs ./

这比git merge更好,因为你也可以看到冲突的文件。 更多详情请访问https://www.kernel.org/pub/software/scm/git/docs/git-checkout.html