0

我有一个历史悠久的初级开发分支(A)。A 中的所有发布提交都被标记为这样。我检查了 A 的根提交,并分支到测试 (B)。

所以我有一个主分支 A,分支 B 的负责人指向 A 的根提交。我的目标是通过将每个标记的提交从 A 合并到 B 来创建所有版本的历史记录。

从 A 到 B 的第一次合并按预期工作,没有冲突。

$git checkout B
$git merge [release-commit-ID] --squash
$git commit -m "release#"

第一次提交效果很好,但所有其他提交都将所有合并提交视为完全冲突。我看到 B 的根与 A 的根相同,但是在从 A 中的第一个发布提交到 B 的第一次压缩合并提交后,没有识别到​​共享历史。是什么导致了冲突以及如何获取共享历史被认可?

4

1 回答 1

1

是什么导致了冲突,我如何才能识别共享历史?

没有共享的历史(或者更确切地说,还不够)。没有什么可承认的,这就是为什么会有冲突。

关键是--squash国旗:

$ git checkout B
$ git merge [release-commit-ID] --squash

第一步将您附加HEAD到分支名称B,检查名称B标识的任何提交:

...--*--C--D--E   <-- B (HEAD)
      \
       F--G--H   <-- somebranch

这里名称B标识了提交E(这些字母中的每一个都代表真正的哈希 ID)。提交*(我会命名为B,但您为您的分支使用了该名称)是两个开发流分歧的点,这意味着当我们向后工作时(如 Git 所做的那样),这是它们汇合的点。你现在运行git merge --squash <hash>where <hash>identify commit F, or G, or H,所以 Git 比较 commit*的内容和 commit 的内容E来找出你改变了什么:

git diff --find-renames <hash-of-*> <hash-of-E>   # what we changed

并重复,说,G

git diff --find-renames <hash-of-*> <hash-of-G>   # what they changed

Git 现在将这两组更改组合在一起,将组合的更改应用于 commit*的内容,并进行新的提交。

如果您使用,Git 会使用两个--squash项记录新提交:

...--*--C--D--E--I   <-- B (HEAD)
      \         /
       F-------G--H   <-- somebranch

现在这两行之间最近的共同起点是 commit G。但如果你确实使用了 ,Git 只记录一个--squash级的新提交:

...--*--C--D--E--I   <-- B (HEAD)
      \
       F--G--H   <-- somebranch

现在共同的起点不变。所有的工作G都在 commit 中I,但是 commitI记得 为什么工作在那里。来自 commit的未来必须git merge从 commitH重新开始*

Git 不会阻止你在 branch 上进行开发somebranch,但一般来说,在 a 之后git merge --squash,你应该认为你合并的分支“死的”并且完全停止使用它。一旦我们与我们合并Ggit merge --squash我们应该完全停止使用FG。这意味着我们也必须H完全停止使用。如果H有用,我们应该将它复制到一个新的、不同的提交中:

$ git checkout -b newbranch B

给我们:

...--*--C--D--E--I   <-- B, newbranch (HEAD)
      \         /
       F-------G--H   <-- somebranch

其次是:

$ git cherry-pick somebranch   # or <hash of H>

复制H到一个非常相似但不相同的提交H'

                   H'   <-- newbranch (HEAD)
                  /
...--*--C--D--E--I   <-- B
      \         /
       F-------G--H   <-- somebranch

我们现在可以丢弃somebranch

$ git branch -D somebranch

如果我们愿意,可以重命名newbranch为。somebranch

git rebase --onto(请注意,我们可以使用, with一步完成复制名称移动的事情git checkout somebranch; git rebase --onto B <hash of G>。但是,无论您如何操作,请注意git cherry-pick不能复制合并提交,以及任何使用我们想要杀死的提交的人off-here the F-G-Hchain-必须执行这种杀死-复制-保存-保存的事情。所以在使用之前--squash,请确保您了解所有含义。)

于 2018-10-15T20:17:51.457 回答