如何修改连续提交,以便它们引用其他子模块提交?
How to amend successive commits such that they reference other submodule commits?
修改子模块中的一些提交消息后,我认为我还应该更新父存储库的提交以修复损坏的引用。
所以我在父存储库上做了一个交互式变基。我想修改父存储库中引用子模块中另外两个提交的两个提交,如下所示:
---A---B---C---D--- parent
| |
v v
---a---b--- sub
因此我 git rebase -i A^
并选择编辑 A 和 B:
edit A ...
edit B ...
pick C ...
pick D ...
现在我在提交 A。为了恢复正确的子模块提交 ID,我首先检查相关的子模块提交,然后修改父存储库中的提交。
$ cd sub/
$ git checkout a
$ cd ..
$ git add sub
$ git commit --amend
感觉不错,继续下一篇:
$ git rebase --continue
现在它抱怨无法合并。这是我对本地化消息的翻译:
Error merging submodule sub (Commits do not follow any merge base)
automatic merge of sub
CONFLICT (submodule): Merge conflict in sub
error: Could not apply B (B's commit message)
Resolve all conflicts manually, mark them as resolved with
"git add/rm ", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply B (B's commit message)
很公平。由于第一个提交中的子模块 ID 已更改,第二个提交已失去与第一个提交的连接。 git status
表示 changed by both: sub
。坚定不移,再次尝试修改:
$ cd sub/
$ git checkout b
$ cd ..
$ git add sub
$ git commit --amend
不幸的是,这不是我想要的。原因是错误的 git rebase --continue
以某种方式完全吃掉了提交 B。 B 的更改已放入暂存区,但提交已消失。因此第二个 git commit --amend
将修改 A 并将 B 的所有更改放入 A!现在我想我可以在那时创建一个新的提交,复制 B。但是要完全按照 B 进行复制会相当复杂。
如何正确修改子模块引用?为什么以及在什么情况下 rebase 会破坏这样的提交?
TL;DR:在没有 --amend
的情况下执行 git commit
使用 git rebase --continue
,这将在没有 [的情况下执行 git commit
=18=].
更长
让我们拿你的原始图表,减去与子模块的连接(因为它们很脆弱并且妨碍了:-)):
...--o--A--B--C--D <-- branch
你 运行 git rebase -i A^
并将 A
更改为 edit
(依此类推)。变基 cherry-picks A
到新副本 A'
:
...--o--A--B--C--D <-- branch
\
A' <-- HEAD
您进行更新,git add
,git commit --amend
进行更新 A"
,留下 A'
被遗弃:
A" <-- HEAD
/
...--o--A--B--C--D <-- branch
\
A'
现在,无论您为 B
的说明输入什么内容,Git 都会尝试 复制 B
但失败了。所以变基停止在:
A" <-- HEAD
/
...--o--A--B--C--D <-- branch
\
A'
在索引和 work-tree 中有一些未提交的更改。 还没有提交 B'
。 您现在可以做两件事。一种是自己做:
<fix the submodule>
git add sub
git commit
这将创建 B'
:
A"-B' <-- HEAD
/
...--o--A--B--C--D <-- branch
\
A'
现在您可以 git rebase --continue
让 Git 继续说明的下一部分(因此您最初不需要要求编辑 B
,您可以现在继续将 C
复制到 C'
:如果 Git 现在停止让您编辑 B'
,您可以告诉它继续)。
另一个——因为git commit
现在需要你输入一个提交消息——是设置一切,而不是git commit
,运行 git rebase --continue
制作 Git 制作 B'
:
<fix the submodule>
git add sub
git rebase --continue
--continue
步骤注意到所有冲突都已修复(如果没有,则抱怨并停止),然后执行 git commit
并继续,就像您所做的一样提交自己。
总结
你需要 edit
作为停止 rebase 的指令,让你 --amend
一个 cherry-pick 成功 。您 不需要 需要 edit
进行提交,其中 cherry-pick 将 失败 ,因为 Git 将没有首先提交就停止。
很难事先知道——在某些情况下,甚至不可能——知道哪些 cherry-picks 会成功,哪些会失败。因此,您最终不得不非常注意 git rebase
停止让您做某事之前出现的确切消息:它停止是因为 cherry-pick 失败了,还是因为你告诉它在 cherry-pick 成功后停止? 换句话说,是否有你现在应该 --amend
的提交,或者你应该(有 Git)现在进行 new 提交?
(我自己也被这个绊倒了,我觉得很烦人。)
修改子模块中的一些提交消息后,我认为我还应该更新父存储库的提交以修复损坏的引用。
所以我在父存储库上做了一个交互式变基。我想修改父存储库中引用子模块中另外两个提交的两个提交,如下所示:
---A---B---C---D--- parent | | v v ---a---b--- sub
因此我 git rebase -i A^
并选择编辑 A 和 B:
edit A ... edit B ... pick C ... pick D ...
现在我在提交 A。为了恢复正确的子模块提交 ID,我首先检查相关的子模块提交,然后修改父存储库中的提交。
$ cd sub/
$ git checkout a
$ cd ..
$ git add sub
$ git commit --amend
感觉不错,继续下一篇:
$ git rebase --continue
现在它抱怨无法合并。这是我对本地化消息的翻译:
Error merging submodule sub (Commits do not follow any merge base) automatic merge of sub CONFLICT (submodule): Merge conflict in sub error: Could not apply B (B's commit message) Resolve all conflicts manually, mark them as resolved with "git add/rm ", then run "git rebase --continue". You can instead skip this commit: run "git rebase --skip". To abort and get back to the state before "git rebase", run "git rebase --abort". Could not apply B (B's commit message)
很公平。由于第一个提交中的子模块 ID 已更改,第二个提交已失去与第一个提交的连接。 git status
表示 changed by both: sub
。坚定不移,再次尝试修改:
$ cd sub/
$ git checkout b
$ cd ..
$ git add sub
$ git commit --amend
不幸的是,这不是我想要的。原因是错误的 git rebase --continue
以某种方式完全吃掉了提交 B。 B 的更改已放入暂存区,但提交已消失。因此第二个 git commit --amend
将修改 A 并将 B 的所有更改放入 A!现在我想我可以在那时创建一个新的提交,复制 B。但是要完全按照 B 进行复制会相当复杂。
如何正确修改子模块引用?为什么以及在什么情况下 rebase 会破坏这样的提交?
TL;DR:在没有 使用 --amend
的情况下执行 git commit
git rebase --continue
,这将在没有 [的情况下执行 git commit
=18=].
更长
让我们拿你的原始图表,减去与子模块的连接(因为它们很脆弱并且妨碍了:-)):
...--o--A--B--C--D <-- branch
你 运行 git rebase -i A^
并将 A
更改为 edit
(依此类推)。变基 cherry-picks A
到新副本 A'
:
...--o--A--B--C--D <-- branch
\
A' <-- HEAD
您进行更新,git add
,git commit --amend
进行更新 A"
,留下 A'
被遗弃:
A" <-- HEAD
/
...--o--A--B--C--D <-- branch
\
A'
现在,无论您为 B
的说明输入什么内容,Git 都会尝试 复制 B
但失败了。所以变基停止在:
A" <-- HEAD
/
...--o--A--B--C--D <-- branch
\
A'
在索引和 work-tree 中有一些未提交的更改。 还没有提交 B'
。 您现在可以做两件事。一种是自己做:
<fix the submodule>
git add sub
git commit
这将创建 B'
:
A"-B' <-- HEAD
/
...--o--A--B--C--D <-- branch
\
A'
现在您可以 git rebase --continue
让 Git 继续说明的下一部分(因此您最初不需要要求编辑 B
,您可以现在继续将 C
复制到 C'
:如果 Git 现在停止让您编辑 B'
,您可以告诉它继续)。
另一个——因为git commit
现在需要你输入一个提交消息——是设置一切,而不是git commit
,运行 git rebase --continue
制作 Git 制作 B'
:
<fix the submodule>
git add sub
git rebase --continue
--continue
步骤注意到所有冲突都已修复(如果没有,则抱怨并停止),然后执行 git commit
并继续,就像您所做的一样提交自己。
总结
你需要 edit
作为停止 rebase 的指令,让你 --amend
一个 cherry-pick 成功 。您 不需要 需要 edit
进行提交,其中 cherry-pick 将 失败 ,因为 Git 将没有首先提交就停止。
很难事先知道——在某些情况下,甚至不可能——知道哪些 cherry-picks 会成功,哪些会失败。因此,您最终不得不非常注意 git rebase
停止让您做某事之前出现的确切消息:它停止是因为 cherry-pick 失败了,还是因为你告诉它在 cherry-pick 成功后停止? 换句话说,是否有你现在应该 --amend
的提交,或者你应该(有 Git)现在进行 new 提交?
(我自己也被这个绊倒了,我觉得很烦人。)