必杀技
是什么让Git 从众多版本控制系统中脱颖而出,独领风骚,当然是其分支模型。正因如此,人称分支模型为Git的“必杀技”,如果不能熟练的运用Git的分支技巧,那就远离了Git的精华。
困惑
我们可以随心所欲的创建分支,合并分支,享受Git带给全世界开发人员的便利。可是,曾几何时你是否也有过以下困惑。
- 你和同事分别负责软件的不同部分,并在不同分支上开发。可是你们需要一个共同的接口文件,或者说数据结构。例如你们分别负责前端和后台的开发,或者是两个component之间需要通讯之类的。同事已经把数据结构写好了,并且做了commit,这个commit的ref暂且称之为
H1 ,可是之后他又进行了其他工作,于是他的分支上又有了H2 ,H3 …,现在你想merge同事分支上的接口部分,但是又不想两个分支合并,因为时机还不成熟,那怎么办? - 你在开发一个新的feature的过程中,发现了mater分支上一个潜在的bug,而且你开发分支上某个commit恰好能fix这个潜在的bug。怎么办?新的feature还在开发中,尚不成熟,不能merge到master
cherry-pick
我们可以通过git cherry-pick 解决以上困惑,上边的场景也往往是此命令使用的典型场景。总而言之,我们可以使用此命令merge 任意我们制定的一个或者多个commit,这些个commit可以连续,也可以离的比较远,没关系。另外,cherry-pick 从行为表现上更像rebase 一点,而不是merge的分支合流。
下边我们通过一个例子来看看这个命令怎么用,他的效果是怎么样的,又有什么危害。
- 首先我们新建一个分支,并胡乱做一些更改,依次创建
f1 ,f2 ,f3 三个commit,然后我们用git log -3 查看一下第二个commit的ref (cc5889b1cf035 ),下边我们就应用一下f2 这个commit
如果这里用merge的话,f1 f2 都会merge到我们的当前分支
$ git cherry-pick cc5889b1cf035
[demo5 f07f847] f2
Date: Mon Nov 15 10:24:00 2021 +0800
1 file changed, 2 insertions(+)
- 完成了,我们看一下当前分支的状态。发现只有
f2 已经应用到当前分支,而且当前分支并没有跟目标分支产生任何交联
$ git logga -6
* f2 - (HEAD -> demo5) (2021-11-15 10:25:23 +0800) <H179378> f07f847
| * f3 - (demo6) (2021-11-15 10:24:23 +0800) <H179378> 3b0dfdd
| * f2 - (2021-11-15 10:24:00 +0800) <H179378> cc5889b
| * f1 - (2021-11-15 10:23:39 +0800) <H179378> a5f8451
|/
* Update version to b34d - (origin/demo5, origin/HEAD) (2021-11-09 11:19:39 -0700) <rtklibexplorer> 0a75457
* Merge pull request
|\
- 后来我们开发完成了,将新分支merge到当前分支,这时候河流汇合了。而且我们发现一点,在左侧的那条时间线上和右侧的那条时间线上都出现了
f2 ,是的cherry-pick 会造成重复commit,所以这个命令也是不怎么推荐用的,只要在少数情况下才会使用。
$ git logga -6
* Merge commit '3b0dfdd' into demo5 - (HEAD -> demo5) (2021-11-15 10:27:09 +0800) <H179378> b3e6bba
|\
| * f3 - (demo6) (2021-11-15 10:24:23 +0800) <H179378> 3b0dfdd
| * f2 - (2021-11-15 10:24:00 +0800) <H179378> cc5889b
| * f1 - (2021-11-15 10:23:39 +0800) <H179378> a5f8451
* | f2 - (2021-11-15 10:25:23 +0800) <H179378> f07f847
|/
* Update version to b34d - (origin/demo5, origin/HEAD) (2021-11-09 11:19:39 -0700) <rtklibexplorer> 0a75457
|