避免多个冲突解决方案的最佳方法 - 在rebase之前进行Git软复位?

时间:2017-11-06 13:45:11

标签: git rebase squash

每当我有一个复杂的rebase因为我当前的功能分支有很多问题,并且因为我的功能分支有很多小提交,解决过程似乎很麻烦且效率低下。

我一直在寻找固定壁垒before的方法。一个解决方案似乎是对最后一次合并进行更软化的重置,然后在多次提交中创建一个提交,然后才进行rebase。

但是这个解决方案看起来有点笨拙。有没有更好的方法来解决这个问题。

编辑: 我指的是必须通过pull请求进行合并的情况,我无法控制合并过程本身。

3 个答案:

答案 0 :(得分:4)

正如您在评论中所做的那样,您可能需要git rebase -i工作流程。

正在运行git rebase -i <commit-to-keep>告诉Git:

  1. <commit-to-keep>;
  2. 之后的当前分支上的列表提交
  3. 提出并向每个此类提交的pick <hash>说明说明;
  4. 编辑说明书后,请查看<commit-to-keep>,然后按照说明操作;
  5. 完成说明后,将当前分支点指向最后一次复制(或压扁或其他)提交。
  6. 因此,如果您有一系列微小的提交A1, A2, A3,然后还有一些B1, B2,例如:

    ...--o--o   <-- origin/feature
             \
              A1--A2--A3--B1--B2   <-- feature (HEAD)
    

    并运行git rebase -i origin/feature,Git会将所有五个提交哈希值列为pick指令。将A2A3指令更改为squash,并将B2指令更改为squash,并保存生成的命令序列,会导致Git开始选择 - 并且压缩提交。 Git在A组的最后一个位置停了一下,让您编辑提交消息,在编辑器上显示A的新提交A1+A2+A3的消息:

              A   <-- HEAD [in progress / being rebuilt]
             /
    ...--o--o   <-- origin/feature
             \
              A1--A2--A3--B1--B2   <-- feature [being rebased]
    

    它现在自动恢复列表,该列表归结为B提交的指令。它再次暂停,启动你的编辑器,用于提交新的一体化B

              A--B   <-- HEAD [in progress / being rebuilt]
             /
    ...--o--o   <-- origin/feature
             \
              A1--A2--A3--B1--B2   <-- feature [being rebased]
    

    一旦您编辑了提交消息,它就会再次恢复并通过&#34;剥离标签来完成分支更新&#34; feature离开旧链并将其粘贴到新链上:

              A--B   <-- feature (HEAD)
             /
    ...--o--o   <-- origin/feature
             \
              A1--A2--A3--B1--B2   [abandoned - in reflog as feature@{1}]
    

    请注意,如果存在冲突,Git会暂停更大的暂停(实际上它会完全退出git rebase命令,但会留下很多git status可以用来显示的跟踪文件你仍然处于变革的中间)。您必须修复冲突并运行git rebase --continue以恢复冲突。如果你只是压缩一些提交,你不应该看到冲突,但是如果你重新安排一堆分散的小冲突 - 也就是说,而不是最初将你的所有A组合在一起,他们 分散在各地,你把它们聚集在一起 - 你可能会有小的冲突要解决。

    在没有参数的情况下运行git rebase -i告诉Git查找当前分支&#34;上游&#34;设置。例如,如果feature上游有origin/feature,则相当于git rebase -i origin/feature。你总是在经过一些指定的提交之后复制你选择/编辑过的TODO列表提交,但默认是#34;你已经设置的上游&#34;。

    请注意,在运行git fetch之前,您必须执行所有此操作,因为git fetch会更新origin/feature。如果您确实运行了git fetch,并且确实更新了origin/feature,那么您现在可以:

              o--o--o   <-- origin/feature
             /
    ...--o--*   [remembered in your reflogs as origin/feature@{1}]
             \
              A1--A2--A3--B1--B2   <-- feature (HEAD)
    

    如果是这种情况,您需要在提交git rebase -i时明确*。您可以通过运行git log --all --decorate --oneline --graph(使用&#34;来自A DOG&#34;来自所有装饰Oneline图表的帮助)找到它的哈希,或者您可以使用它在{{1}中的事实} reflog为origin/feature,通过以下方式验证:

    origin/feature@{1}

    (&#34; DOG&#34;仍然在那里,而不是git log --decorate --oneline --graph origin/feature@{1}.. 部分,以减少混乱。或者,您甚至可以使用--all来找到提交{{ 1}},但我们将其留给另一个主题。:-))

答案 1 :(得分:1)

您可以使用git merge --squash feature_branch

git checkout master
git merge --squash feature_branch

这将从feature_branch将所有提交压缩为一个提交,并将此提交添加到master

实施例

以下repo的分支feature/1基于masterfeature/1中有一些提交,master上有一个提交。之后,我在git merge --squash feature/1上创建了master,创建了提交5497776,其中包含feature/1上树提交的更改。

* 5497776 (HEAD, master) merge --squash feature/1
* 46059c7 Change 2 on master
| * b080e96 (feature/1) Change 3 on feature branch
| * 6caf662 Change 2 on feature branch
| * 69d9993 Change 1 on feature branch
|/  
* b39b078 Change 1

顺便说一下,我明确地引发了合并冲突。您可以在合并过程中解决它们,然后暂存更改以将冲突标记为已解决,并继续git commit

答案 2 :(得分:0)

软复位到最后一次合并然后创建一个新的提交是最好的解决方案。这已被大量投票,但我不认为这是合理的,特别是在无法直接合并的情况下,因为它必须通过拉取请求来完成。