避免多重冲突解决的最佳方法 - Git 变基前软重置?
Best way to avoid multiple conflict resolutions - Git soft reset before rebase?
每当我有一个复杂的 rebase 时,因为我当前的功能分支有很多冲突,并且因为我的功能分支有很多小的提交,解决过程似乎很麻烦且效率低下。
我一直在寻找从本质上压制 before
变基发生的方法。一种解决方案似乎是将 sofr 重置为最后一次合并,然后从许多提交中创建一个提交,然后才进行 rebase。
但这个解决方案似乎有点老套。有没有更好的方法来处理这个问题。
编辑:
我指的是必须通过拉取请求完成合并并且我无法控制合并过程本身的情况。
正如您在评论中所做的那样,您可能需要 git rebase -i
工作流程。
运行 git rebase -i <commit-to-keep>
本质上告诉 Git:
- 列出当前分支上的提交,这些提交在
<commit-to-keep>
之后;
- 提出并指示 sheet 对每个此类提交说
pick <hash>
;
- 编辑指令 sheet 后,检查
<commit-to-keep>
然后按照说明进行操作;
- 完成指令后,使当前分支指向最后一个这样的复制(或压缩或其他)提交。
因此,如果您有一系列微小的提交 A1, A2, A3
,然后还有一些 B1, B2
,例如:
...--o--o <-- origin/feature
\
A1--A2--A3--B1--B2 <-- feature (HEAD)
和 运行 git rebase -i origin/feature
、Git 将所有五个提交哈希列为 pick
指令。将 A2
和 A3
指令更改为 squash
,并将 B2
指令更改为 squash
,并保存生成的命令序列,导致 Git 开始 pick-and-squash-ing 提交。 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]
一旦您编辑了提交消息,它会再次恢复并通过 "peeling the label" feature
完成分支更新,从旧链上移除并将其粘贴到新链上:
A--B <-- feature (HEAD)
/
...--o--o <-- origin/feature
\
A1--A2--A3--B1--B2 [abandoned - in reflog as feature@{1}]
请注意,如果存在冲突,Git 会以更大的暂停时间暂停变基(它实际上完全退出了 git rebase
命令,但在 [=37] 后面留下了很多跟踪文件=] 可以用来表明你还在变基的中间)。您必须修复冲突并 运行 git rebase --continue
才能恢复。如果你只是压缩一些提交,你不应该看到冲突,但如果你正在重新安排一堆分散的小提交——即,而不是最初将所有 A
分组,它们 是分散在各处,你把它们聚集在一起——你们可能有小冲突需要解决。
运行 git rebase -i
没有参数告诉 Git 查找当前分支的 "upstream" 设置。例如,如果 feature
的上游为 origin/feature
,则等价于 git rebase -i origin/feature
。你总是在一些指定的提交之后复制你选择的/编辑的 TODO 列表提交,但默认是 "the upstream you've already set".
请注意,您必须在 运行 宁 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
。您可以通过 运行ning git log --all --decorate --oneline --graph
(使用 "help from A DOG",All Decorate Oneline Graph)找到它的散列,或者您可以使用它在您的 origin/feature
reflog 中的事实作为 origin/feature@{1}
,通过以下方式验证:
git log --decorate --oneline --graph origin/feature@{1}..
("DOG" 仍然在那里,只是没有 --all
部分,以减少混乱。或者,您甚至可以使用 git merge-base
来定位提交 *
,但我们将把它留到另一个主题。:-) )
您可以使用 git merge --squash feature_branch
:
git checkout master
git merge --squash feature_branch
这会将 feature_branch
中的所有提交压缩为一个提交,并将这个提交添加到 master
。
例子
以下 repo 有一个分支 feature/1
,它基于 master
。在 feature/1
中有一些提交,在 master
中有一个提交。之后,我在 master
上做了一个 git merge --squash feature/1
,它创建了提交 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
。
软重置为上次合并,然后创建一个新的提交是最好的解决方案。这已被严重否决,但我认为这是不合理的,特别是在无法直接合并到 master 的情况下,因为它必须通过拉取请求完成。
每当我有一个复杂的 rebase 时,因为我当前的功能分支有很多冲突,并且因为我的功能分支有很多小的提交,解决过程似乎很麻烦且效率低下。
我一直在寻找从本质上压制 before
变基发生的方法。一种解决方案似乎是将 sofr 重置为最后一次合并,然后从许多提交中创建一个提交,然后才进行 rebase。
但这个解决方案似乎有点老套。有没有更好的方法来处理这个问题。
编辑: 我指的是必须通过拉取请求完成合并并且我无法控制合并过程本身的情况。
正如您在评论中所做的那样,您可能需要 git rebase -i
工作流程。
运行 git rebase -i <commit-to-keep>
本质上告诉 Git:
- 列出当前分支上的提交,这些提交在
<commit-to-keep>
之后; - 提出并指示 sheet 对每个此类提交说
pick <hash>
; - 编辑指令 sheet 后,检查
<commit-to-keep>
然后按照说明进行操作; - 完成指令后,使当前分支指向最后一个这样的复制(或压缩或其他)提交。
因此,如果您有一系列微小的提交 A1, A2, A3
,然后还有一些 B1, B2
,例如:
...--o--o <-- origin/feature
\
A1--A2--A3--B1--B2 <-- feature (HEAD)
和 运行 git rebase -i origin/feature
、Git 将所有五个提交哈希列为 pick
指令。将 A2
和 A3
指令更改为 squash
,并将 B2
指令更改为 squash
,并保存生成的命令序列,导致 Git 开始 pick-and-squash-ing 提交。 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]
一旦您编辑了提交消息,它会再次恢复并通过 "peeling the label" feature
完成分支更新,从旧链上移除并将其粘贴到新链上:
A--B <-- feature (HEAD)
/
...--o--o <-- origin/feature
\
A1--A2--A3--B1--B2 [abandoned - in reflog as feature@{1}]
请注意,如果存在冲突,Git 会以更大的暂停时间暂停变基(它实际上完全退出了 git rebase
命令,但在 [=37] 后面留下了很多跟踪文件=] 可以用来表明你还在变基的中间)。您必须修复冲突并 运行 git rebase --continue
才能恢复。如果你只是压缩一些提交,你不应该看到冲突,但如果你正在重新安排一堆分散的小提交——即,而不是最初将所有 A
分组,它们 是分散在各处,你把它们聚集在一起——你们可能有小冲突需要解决。
运行 git rebase -i
没有参数告诉 Git 查找当前分支的 "upstream" 设置。例如,如果 feature
的上游为 origin/feature
,则等价于 git rebase -i origin/feature
。你总是在一些指定的提交之后复制你选择的/编辑的 TODO 列表提交,但默认是 "the upstream you've already set".
请注意,您必须在 运行 宁 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
。您可以通过 运行ning git log --all --decorate --oneline --graph
(使用 "help from A DOG",All Decorate Oneline Graph)找到它的散列,或者您可以使用它在您的 origin/feature
reflog 中的事实作为 origin/feature@{1}
,通过以下方式验证:
git log --decorate --oneline --graph origin/feature@{1}..
("DOG" 仍然在那里,只是没有 --all
部分,以减少混乱。或者,您甚至可以使用 git merge-base
来定位提交 *
,但我们将把它留到另一个主题。:-) )
您可以使用 git merge --squash feature_branch
:
git checkout master
git merge --squash feature_branch
这会将 feature_branch
中的所有提交压缩为一个提交,并将这个提交添加到 master
。
例子
以下 repo 有一个分支 feature/1
,它基于 master
。在 feature/1
中有一些提交,在 master
中有一个提交。之后,我在 master
上做了一个 git merge --squash feature/1
,它创建了提交 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
。
软重置为上次合并,然后创建一个新的提交是最好的解决方案。这已被严重否决,但我认为这是不合理的,特别是在无法直接合并到 master 的情况下,因为它必须通过拉取请求完成。