【问题标题】:Keep commits history after a 'git merge'在“git merge”之后保留提交历史
【发布时间】:2015-04-09 00:43:30
【问题描述】:

当我处理两个不同的特性时(在从 master 创建的两个不同的分支上),当我继续合并时,我将没有提交历史记录,这很烦人。

我会解释得更好。当我完成Branch-A 的工作后,我将它合并到master。这很好,如果我 git log 我看到我在 Branch-A 上所做的所有提交。

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

假设我有

**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 提交,我怎样才能保持一切清晰?

【问题讨论】:

    标签: git github merge git-branch


    【解决方案1】:

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

    说明

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

    当被合并的提交的当前位置为其历史上的分支。例如:

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

    执行git merge(使用默认设置)将导致

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

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

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

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

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

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

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

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

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

    【讨论】:

    • 当我对两者都有更改时,我需要将 master 合并到 branch-b。我如何重写branch-b,就像它是从提交G而不是E开始的一样?但是保留branch-b 的提交历史并将更改提交到branch-b,这是冲突的。假设我只是知道branch-b的人。
    • Nvm 是准确的git rebase master
    【解决方案2】:

    使用rebase 而不是merge。来自tutorial

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

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

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

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

    【讨论】:

    • 我刚得到一个赞成票,我必须说:3 年后,我在合并之前不再与 master 变基!
    • 为什么?很好奇,因为我看到了朝着这个方向发展的普遍趋势......?也许不要泄露有关分支机构的信息?那些合并提交不会让您对可读性感到厌烦吗?
    • 我不能说为什么,但是变基改变了 git 的历史并且可能让其他人感到困惑! :)
    • 如果您在将其合并到主分支之前 重新设置本地工作分支的基础,那么就不会有混淆 - 因为没有人使用您的本地分支。就算是你,在它曾经幸福地加入了主人之后。
    猜你喜欢
    • 2019-07-28
    • 1970-01-01
    • 1970-01-01
    • 2015-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-19
    • 2014-06-29
    相关资源
    最近更新 更多