在“混帐合并”后保留提交历史记录 [英] Keep commits history after a 'git merge'

查看:118
本文介绍了在“混帐合并”后保留提交历史记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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



而不是,当我完成 Branch-B 的工作时,我尝试将它合并到 master Branch-A 已经合并了),我必须指定合并的提交消息(而对于第一个分支,我还没有被问到任何问题)。
如果我输入 git log ,则合并到 master 后,我看不到 Branch-B的提交在我的 master 分支的历史记录中 pre> **分支A **

提交09b2unfas9d781n2e
添加更多内容

提交8uj8masd89jas898a
添加内容

**分支B **

提交09b2unfas9d781n2e
添加功能设置

提交8uj8masd89jas898a
添加功能

我完成了

 <$ c 












$ 9b2unfas9d781n2e
添加更多内容

提交8uj8masd89jas898a
添加内容

提交34osd62dhc91123j8
我是以前从主提交的。
分支前的最后一个...

while 我想获得

  **主人** 

提交09b2unfas9d781n2e
添加功能设置

提交8uj8masd89jas898a
添加功能

提交09b2unfas9d781n2e
添加更多内容

提交8uj8masd89jas898a
添加的东西

提交34osd62dhc91123j8
我是一个以前提交'主'。
分支之前的最后一个...

...这将更准确地反映履行提交的历史。



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



如果没有那些隐藏/忽略合并提交的实际历史记录的 merge 提交,我该如何保持一切清晰? 解决方案

它看起来像第一个合并是一个快速前进,第二个合并是一个三路合并。



说明



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



快进合并(您可以通过选项 - ff-only 强制执行此操作,这将会当快进是不可能的时候导致合并失败)可以发生在被合并的提交在其历史中具有分支的当前位置时。例如:

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

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

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

您也不会有机会编辑合并提交因为没有。但是,一旦发生这种情况,您的其他分支将与主人分道扬((不只是在前方):

  A  -  B  -  C  - D  -  E  -  F  -  G < - 主要
\
E1 - E2 < - 分支 - b

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

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

如果您想要获得线性历史记录,那么您需要使用rebase,但要事先警告,如果其他人看到您的分支提交,可能会导致超出范围的问题这个答案使用rebase将涉及到两个步骤,重新绑定和快速合并,所以,不要合并你在 branch-b 上执行以下操作, git rebase master 这会创建新的提交,它们是旧提交的副本,即相同的变更集,作者信息和消息,但新的提交者信息和父历史记录(我将提交E1'和E2 '在插图中表明它们只是副本。)旧提交将存在,直到它们被垃圾收集为止除非你看到reflog,否则ut将不可访问。)

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

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



<$ p $ A-B-C -D -E-F -G-E1'-E2'<-master < - 分支-b
pre>

When I work on two different features (on two different branches created from the master) it is quite annoying that I will not have the commit history when I proceed with merging.

I'll explain better. When I finish work on Branch-A, I merge it into master. And that's fine, if I git log I see all the commits I made on Branch-A.

Instead, when I finish work on Branch-B and I try to merge it to master (after that Branch-A has been already merged), I have to specify a commit message for the merging (while for the first branch I have not been asked anything). And after the merging to master, if I type git log, I cannot see the commits of the Branch-B in the history of my master branch

Let's say I have

**Branch A**

commit 09b2unfas9d781n2e
    Add more stuff

commit 8uj8masd89jas898a
    Add stuff

**Branch B**

commit 09b2unfas9d781n2e
    Add feature setting

commit 8uj8masd89jas898a
    Add feature

I finish having

**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...

while I would like to obtain something like:

**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...

... that would reflect more exactly the history of the performed commits.

I don't get why I can keep the history from just one of the two branches.

How can I keep everything clear without those merge commits that hide/omit the real history of the merged commits?

解决方案

It looks like the first merge was a fast-forward, and the second one was a three-way merge.

Explanation

Git has two versions of merge: fast-forward and three-way. (There are other versions, but that is not what happened here.) The default behavior is to do a fast-forward merge when possible, and otherwise do a three-way merge.

A fast-forward merge (you can force this behavior with the option --ff-only, which will cause the merge to fail when fast-forward is impossible) can take place when the commit that is being merged has the current position of the branch in its history. For example:

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

Excecuting git merge (with default settings) will result in

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

You will also not get a chance to edit the merge commit because there is none. However, once this happens, your other branch will diverge from master (not just be ahead):

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

Therefore, Git cannot just move the pointer of master from G to E2 because that will get rid of the changes that were made in F and G. Instead a three-way merge happens, which create a commit that has two parents, and also has a commit message. Now, master can be moved to this commit. (Notice that in this situation, master and branch-b do NOT point to the same commit.

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

If you want to have a linear history then you need to use rebase, but be forewarned that if anybody else has seen your branch commits this may lead to issues that are beyond the scope of this answer. Using rebase will involve two steps, rebasing and then fast-forward merge. So, instead of merging you first execute the following while on branch-b, git rebase master. This creates new commits that are copies of the old commits, i.e., the same change-set, author information and message, but new committer information and parent history. (I call the commits E1' and E2' in the illustration to indicate that they are just copies.) The old commits will exist until they are garbage collected, but will not be reachable unless you look at the reflog.)

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

Executing git checkout master; git merge --ff-only branch-b will now fast-forward your changes into master, thereby giving you a linear history.

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

这篇关于在“混帐合并”后保留提交历史记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆