美文网首页
关于多个parent commit的场景以及cherry-pic

关于多个parent commit的场景以及cherry-pic

作者: CodingCode | 来源:发表于2020-04-21 03:17 被阅读0次

git里面的每一个commit都有一个parent commit,所有的commit构成一个commit树(tree)

  1. 对于multiple parent commit的场景

普通commit只有一个parent commit,而merge commit会有多个parent commit,取决于从多少个分支进行merge,如果从两个分支merge则有两个parent commit,如果从三个分支merge则有三个parent commit,。。。

举例来说:

  1. 主干分支master有A,B,C三个commit
  2. 拉出一个开发分支developer,并且在开发分支上产生D,E两个commit。
  3. 同时主干分支上又有了F,G,H三个commit。
image.png

此时我们要把开发分支developer合并回主干master分支:

  1. 产生一个新的merge commit: M
  2. M包含两个parent commit,即E,和H
image.png

很多人会有疑问,为什么要生成merge commit,它其实没有任何实效的代码变化,为什么不把分支developer和master拉直,比如:


image.png

或者


image.png

这样做是需要更改历史commit的,或者把commit D的parent commit的改掉,或者把commit F的parent commit改掉,这都是不被允许的,即修改历史信息。所以只能添加一个新的commit M,它包含两个parent commit分别指向E和H,那么以后的commit也只需要一个parent commit即M就可以了。

git cherry-pick -m的使用

还是从前面的例子继续来说。
假设之前还有一个分支feature从G拉出,并且已经生成提交G1,G2两次提交:


image.png

此时发现需要把分支developer的改动(D和E)合并进来,怎么办呢:

  1. 分支developer已经删除了。
  2. 不能从master分支merge,因为不要commit H。

可以把commit D和E一个一个cherry-pick进来;但是如果developer上的commit数目很多,就会很麻烦,那么能不能通过把commit M合并进来了,是可以的,但是必须指定-m <parent>选项。

查看master分支的提交历史:

$ git checkout master
$ git log --oneline
<hash M> Merge pull request # in <repo> from developer to master
<hash E> Comment of commit E
<hash D> Comment of commit D
<hash H> Comment of commit H
...

再查看merge commit M的信息:

$ git cat-file -p <hash M>
tree <hash tree>
parent <hash E>
parent <hash H>
author ...
committer ..

Merge pull request #4 in <repo> from <developer> to <master>

* commit '<hash E>':
  ...

很清楚的看到commit M有两个parent commit,即H和E,(是谁排先谁排后,还不清除呢,待研究)

此时使用使用git cherry-pick -m 1 <hash M>就会把commit D和E的内容复制到分支feature上面来。(注意parent 的序号从1开始)

另外需要特别说明的是,用这种产出的commit会抹去之前的提交历史,我们看命令输出:

$ git checkout feature
$ git log --oneline
dc54985 Merge pull request #4 in <repo> from <developer> to <master>
...
$ git cat-file -p dc54985
tree <hash>
parent <hash G2>
author ...
committer ...

Merge pull request #4 in <repo> from <developer> to <master>

* commit 'Hash E':
  ...
image.png

也就是说cherry-pick之后生成了一个新的commit N ‘hash=dc54985’,这个新的commit包含之前D和E的改动,但是D和E的提交历史并没有带进分支feature,用git log并不能看到D和E的提交过程,而且新commit E并不是作为一个merge commit而存在,它只有parent commit G2,只是左右一个普通commit存在。

相关文章

网友评论

      本文标题:关于多个parent commit的场景以及cherry-pic

      本文链接:https://www.haomeiwen.com/subject/abveihtx.html