合作解决合并冲突

11

场景:

在git中为每个(活动)版本发布一个分支,

步骤如下:

  1. Bob对R1进行更改,提交,从共享库中拉出R1并将其推送到共享库。不更新共享库中的R2
  2. Jane对R1进行更改,提交。
  3. Jane从共享库中拉取R1,处理任何冲突,并推送R1
  4. 重复执行步骤1数次
  5. Jane被告知需要使用来自R1的修复将R2更新到最新版本
  6. Jane从共享库中拉取R1R2
  7. Jane在本地将R1合并到R2中。在Bob工作过的某些代码区域中有合并冲突。

Jane必须从共享库中获取R2并处理合并,然后才能推送。但是,她不知道如何处理Bob的更改。

分支:R1R2

 State of Shared Repository

 C1    - Bob
 |
 C2-+  - Jane
 |  |
 |  C3 - George
 |  |
 |  C4
 C5 |  - Bob
 |  |
 C6 |  - Jane  [R1]
    |
    C7 - Alice [R2]

Bob和Jane对R1进行更改。

Jane希望将R1合并到R2以更新最新版本。她解决了由她的更改引起的合并冲突,但不知道如何解决由Bob所做的更改引起的冲突。

Jane是否可以使用Git让Bob完成合并呢?

我知道理想情况下,Bob应该已经将他的更改合并到R2中,但假设这不是这种情况。

可能的解决方法(正在寻找更好的方法)

  1. Jane请Bob过来一起解决冲突。如果远程工作,则较困难。
  2. Jane保存有冲突的文件并通过电子邮件发送给Bob,之后Bob修复文件并通过电子邮件返回给Jane,然后Jane在提交时使用这些文件。

@Justinᚅᚔᚈᚄᚒᚔ 请参考上面的共享存储库状态示例。Jane 进行了一次获取操作。她希望将共享存储库 R2 分支更新为来自 R1 的更改(例如,将之前版本中的错误修复合并到当前版本中)。 - Joseph Kingry
4个回答

9
假设Bob被阻塞了,Jane急于推进问题,她尽力进行合并。
以上wip代表正在进行的工作,这是一种向团队发出信号的惯例,表示树和历史记录可能会发生重大变化。也许Jane真的希望Bob在将其集成到基线之前审查影响他的R1代码的解决方案。 (注意:这是一种反模式;更好的方法是拥有自动化测试,以保护R1中新代码的期望行为,并允许不是Bob的开发人员自信地进行合并。)
Jane尽最大努力进行合并。
wip / R2-with-R1分支甚至可能包含多个检查点式提交。每个都应该包含一个良好的信号,以让团队知道它是投机的。
当她准备好让Bob查看时,她将其推送到他们都可以看到的存储库
--set-upstream选项存在,以防需要共同在新分支上工作。
然后她启动邮件用户代理。
经过Bob的修复和提取后,历史记录将类似于
此时,Jane想保留合并,但不想保留丑陋的检查点提交。压缩回合并提交只需要稍微小心一点。
$ echo 将R1合并到R2中 | \
  git commit-tree origin/wip/R2-with-R1^{tree} \
  -p $(git rev-parse origin/R1) -p $(git rev-parse origin/R2)
84b177c498bc635612b66932f3d41096999e6d3f

$ git checkout R2
切换到分支 'R2'

$ git merge --ff-only 84b177c498bc635612b66932f3d41096999e6d3f
更新 137b39d..84b177c
快进
...

这将留下一个历史记录

$ git lola
*   84b177c (HEAD, R2) 合并R1进入R2
|\
| | * 77d472c (origin/wip/R2-with-R1) Bob的修复
| | * ba1eb24 FIXME: 合并2
| | *   80c207d (wip/R2-with-R1) FIXME: 合并1
| | |\
| |/ /
| | /
| |/
|/|
* | 2cf6ad4 (origin/R1, R1) R1 #2
| * 137b39d (origin/R2) R2 #2
| * cb9a761 R2
...

通过构造,现在R2拥有与Bob最终树相同的树。


3

我们处于类似的情况。

以下是我们在多次失败尝试后发现可行的方法。 重点在于如何在远程存储库中共享有冲突的补丁段。

  1. Jane creates two branches from the tip of R2 and merge R1 onto them with a set of 'complementary' merge strategies;

    $ git branch wip/reference R2
    $ git checkout wip/reference
    $ git merge -s recursive -X theirs R1
    
    $ git branch wip/merging R2
    $ git checkout wip/merging
    $ git merge -s recursive -X ours R1
    
  2. Now

    $ git diff wip/reference..wip/merging
    

    shows how R1 would have conflicted with R2 because '-s recursive -X ours/theirs' merge strategy "forces conflicting hunks to be auto-resolved cleanly by favoring our/their version."

  3. Jane makes necessary changes on wip/merging so to solve the 'virtual' conflicts caused by her previous changes and leaves Bob's untouched.

  4. Then Jane pushes wip/reference and wip/merging and call/IM/email/owlpost Bob to fetch them.

  5. Bob checks the virtual conflicts and the halfway resolution Jane made and makes further changes against the conflicts his past change caused.

  6. Then he merges wip/merging back to R2 if he feels everything looks good or optionally ask George/Alice to make further resolutions.

我们仍在调查这如何影响以后的合并(即git rerere是否正常工作)。

3
除了简向鲍勃展示修改内容以外,我认为这不能在git中完成。
当解决合并冲突时,您正在创建一个新的提交,所有这些都是在本地进行的。简可能进行合并并决定不将更改推送到远程。在推送合并提交之前,无法知道其他人是否合并了其副本。简必须解决提交才能完成合并,这仅在本地发生。
在远程存在未合并的更改似乎也是不好的想法。假设我开始使用repo并在鲍勃解决冲突之前拉取更改。那接下来呢?
简要了解自己是否解决提交的另一种方法是她有一个测试套件要运行。然后,当测试失败时,她就知道自己犯了错误。

是的,“到桌子旁边来”协议是我们过去使用的。但对于远程人员来说有点困难。 - Joseph Kingry
我能理解。但是如果你有关于冲突的问题,你需要以某种方式与Bob联系(电子邮件、电话、Skype、信鸽)。但这将不在Git范围内。否则,请尽力解决冲突,并在稍后的提交中撤销任何不正确的更改。 - Schleis
是的,我只是希望能够以某种方式将解决工作保存到Git中,作为另一个分支,然后让Bob检查并完成它。 - Joseph Kingry
2
这就是为什么Git的方式建议不要让多个人同时在一个分支上工作。每个贡献者都应该有自己的私有分支来进行工作。 - twalberg

1
如果我正确理解了操作的顺序,那么如下所示:
1. Bob 修改 R1,提交更改,将其与他的 R2 副本合并并推送到共享存储库。 2. Jane 修改 R1,提交更改,将其与她的 R2 副本合并并尝试推送到共享存储库,但遇到了过时错误。 3. Jane 必须从共享存储库获取 R2 并处理合并,然后才能推送。但是,她不知道该如何处理 Bob 的更改。
在这种情况下,Jane 和 Bob 可以执行以下操作:
  1. Jane可以在共享分支上创建一个包含她对R2的更改的分支:

    git push origin R2:R2-from-Jane
    
  2. Jane随后可以打电话/发邮件/IM给Bob,请求他合并更改。
  3. Bob感到不满地叹了口气,然后从服务器解决了与Jane分支的合并:

    git fetch origin R2-from-Jane
    git checkout R2
    git merge R2-from-Jane
    git push
    git branch -d R2-from-Jane
    
  4. Bob回复Jane,让她知道合并已完成。
  5. Jane从服务器删除了她的临时分支:

    git push origin :R2-from-Jane
    

    然后回复Bob以表示感谢。

< p > < em >(显然,Bob 也可以处理在服务器上删除 Jane 的临时分支,但这与叙述不太符合。)


我明确地编写了一个序列。我认为这个问题的原因是Bob(和Jane)懒惰,没有每次更新R2。 - Joseph Kingry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接