在'git merge'之后保留提交历史记录

时间:2015-02-09 09:57:33

标签: git github merge git-branch

当我处理两个不同的功能(在 master 创建的两个不同的分支上)时,当我继续合并时,我将不会有提交历史记录,这非常令人讨厌。

我会更好地解释。当我完成 Branch-A 的工作时,我将其合并到 master 中。这没关系,如果我git log我看到我在 Branch-A 上做的所有提交。

相反,当我完成 Branch-B 的工作时,我尝试将其合并到 master (之后分支 - 已经合并了),我必须为合并指定一个提交消息(而对于第一个分支,我没有被问到任何东西)。 在合并到 master 之后,如果我输入git log,我在 master <的历史记录中看不到 Branch-B 的提交/ em>分支

假设我有

**Branch A**

commit 09b2unfas9d781n2e
    Add more stuff

commit 8uj8masd89jas898a
    Add stuff

**Branch B**

commit 09b2unfas9d781n2e
    Add feature setting

commit 8uj8masd89jas898a
    Add feature

我完成了

**Master**

commit 6hf6h8hd871udjkdn
Merge: 09b2un 34osd6
    Merge branch 'Branch-B' into master

commit 09b2unfas9d781n2e
    Add more stuff

commit 8uj8masd89jas898a
    Add stuff

commit 34osd62dhc91123j8
    I'm a previous commit from 'master'.
    The last one before branching...

虽然我想获得之类的东西:

**Master**

commit 09b2unfas9d781n2e
    Add feature setting

commit 8uj8masd89jas898a
    Add feature

commit 09b2unfas9d781n2e
    Add more stuff

commit 8uj8masd89jas898a
    Add stuff

commit 34osd62dhc91123j8
    I'm a previous commit from 'master'.
    The last one before branching...

......这将更准确地反映所执行提交的历史记录。

我不明白为什么我可以将历史记录保留在两个分支中的一个。

如果没有那些隐藏/省略合并提交的真实历史记录的 merge 提交,我怎样才能保持一切清晰?

2 个答案:

答案 0 :(得分:25)

看起来第一次合并是快进,第二次合并是三次合并。

<强>解释

Git有两个版本的合并:快进和三向。 (还有其他版本,但这不是这里发生的事情。)默认行为是在可能的情况下进行快进合并,否则进行三向合并。

快进合并(您可以使用选项--ff-only强制执行此行为,这将导致合并在无法快进时失败)可以在合并的提交具有当前时发生分支在其历史中的位置。例如:

A - B - C - D <-master
             \
              E - F - G <- branch-a

超出git merge(使用默认设置)将导致

A - B - C - D - E - F - G <- branch-a <-master

您也没有机会编辑合并提交,因为没有。但是,一旦发生这种情况,你的另一个分支将与主人分道扬声(不仅仅是领先):

A - B - C - D  - E - F - G <-master
                  \
                   E1 - E2 <- branch-b

因此,Git不能只将主人的指针从G移动到E2,因为这会消除FG中所做的更改。而是发生三向合并,它创建一个具有两个父项的提交,并且还有一个提交消息。现在,master可以转移到此提交。 (请注意,在这种情况下,master和branch-b不会指向同一个提交。

A - B - C - D  - E - F - G - H <-master
                  \       /
                   E1 - E2 <- branch-b

如果您想拥有线性历史记录,那么您需要使用rebase,但要预先警告,如果其他人看到您的分支提交,这可能会导致超出此答案范围的问题。使用rebase将涉及两个步骤,rebased然后快进合并。因此,在 branch-b git rebase master上,首先执行以下操作,而不是合并。这将创建新提交,这些提交是旧提交的副本,即相同的更改集,作者信息和消息,但是新的提交者信息和父历史记录。 (我在插图中调用提交E1和#E2;以及E2&#39;表示它们只是副本。)旧提交将一直存在,直到它们被垃圾收集,但除非你查看reflog,否则将无法访问。)

A - B - C - D  - E - F - G <-master
                  \       \
                   E1 - E2 \ 
                            E1' - E2' <- branch-b

执行git checkout master; git merge --ff-only branch-b现在可以将您的更改快进到母版,从而为您提供线性历史记录。

A - B - C - D  - E - F - G - E1' -E2' <-master <- branch-b

答案 1 :(得分:4)

使用rebase代替merge。来自tutorial

  

如果检查一个重新分支的分支的日志,它看起来像一个线性   历史:看起来所有的工作都是连续发生的,即使是这样   最初并行发生。

我认为您Branch-B的更改无法使用快进合并到master中进行合并。在这种情况下,three-way-merge完成了:

  

Git不是只向前移动分支指针,而是创建一个新的   由此三向合并自动生成的快照   创建一个指向它的新提交。这被称为合并   提交,并且特别之处在于它有多个父级。

在将它们提交到master以保持线性历史记录之前,我总是会重新提交我的提交。