在子模块中修改了一些提交消息后,我认为我还应该更新父存储库的提交以修复损坏的引用。
因此,我在父存储库上进行了交互式基础更改。我想修改父存储库中的两个提交,这些提交引用子模块中的其他两个提交,如下所示:
---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那样准确地获得它,将相当复杂。
如何正确修改子模块引用?为什么以及在什么情况下重新部署会破坏这样的提交?
答案 0 :(得分:1)
TL; DR:不使用git commit
的{{1}}使用--amend
,不使用git rebase --continue
的{{1}}。
让我们看一下原始图,减去与子模块的连接(因为它们很脆弱并且妨碍了:-)):
git commit
您运行--amend
,并将...--o--A--B--C--D <-- branch
更改为git rebase -i A^
(依此类推)。将Cherry-pick A
重新设置为新副本edit
:
A
您进行更新,A'
和...--o--A--B--C--D <-- branch
\
A' <-- HEAD
来创建新的git add
,而将git commit --amend
保留为废弃:
A"
现在,无论您为A'
输入什么指示,Git 尝试复制 A" <-- HEAD
/
...--o--A--B--C--D <-- branch
\
A'
但都会失败。因此,重新定位在以下位置停止:
B
在索引和工作树中有一些未提交的更改。 尚无提交B
。,您现在可以做两件事。一种是自己制作:
A" <-- HEAD
/
...--o--A--B--C--D <-- branch
\
A'
这将创建B'
:
<fix the submodule>
git add sub
git commit
,现在您可以B'
继续执行Git的下一部分说明(因此,您无需先要求编辑 A"-B' <-- HEAD
/
...--o--A--B--C--D <-- branch
\
A'
即可,您可以继续复制{从{1}}到git rebase --continue
:如果Git现在停止让您编辑B
,您可以告诉它继续)。
另一个原因是C
现在要求您输入提交消息,因此是进行所有设置,而不是C'
,运行B'
来使Git成为{{1 }}:
git commit
git commit
步骤会注意到所有冲突都已解决(如果不是,则进行投诉并停止),然后执行git rebase --continue
并继续进行,就像您进行了提交一样你自己。
您需要使用B'
作为停止变基的指示,并让您<fix the submodule>
git add sub
git rebase --continue
成功摘机。您不需要进行--continue
提交,而樱桃选择将失败,因为Git会停止而无需首先进行提交。< / p>
很难事先知道(在某些情况下,这甚至是不可能的),要知道哪些樱桃小菜将成功,哪些樱桃小菜将失败。因此,您不得不注意git commit
停止之前发出的确切消息,以使您能够执行某些操作:它停止运行的原因是因为摘樱桃失败,还是是因为您让它在摘樱桃成功之后停止而停止了吗?换句话说,是否存在您现在应该edit
的提交,还是应该(让Git)做出 new 立即提交?
(我自己被这个绊倒了。我觉得这很烦人。)