如何修改连续的提交,以便它们引用其他子模块的提交?

时间:2019-07-04 20:16:07

标签: git git-submodules

在子模块中修改了一些提交消息后,我认为我还应该更新父存储库的提交以修复损坏的引用。

因此,我在父存储库上进行了交互式基础更改。我想修改父存储库中的两个提交,这些提交引用子模块中的其他两个提交,如下所示:

---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 statuschanged 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那样准确地获得它,将相当复杂。

如何正确修改子模块引用?为什么以及在什么情况下重新部署会破坏这样的提交?

1 个答案:

答案 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 立即提交?

(我自己被这个绊倒了。我觉得这很烦人。)