FrankKai / FrankKai.github.io

FE blog
https://frankkai.github.io/
362 stars 39 forks source link

如何理解git cherry pick? #172

Open FrankKai opened 4 years ago

FrankKai commented 4 years ago
FrankKai commented 4 years ago
git cherry-pick [commit hash]

概述

git cherry-pick是一个非常强大的命令,这个命令可以使得任意Git commits被选中,然后添加到当前的工作HEAD。Cherry pick可以从一个分支选中一个commit,然后再应用到另外一个分支。 git cherry-pick对于undoing的改变是很有用的。例如,一个commit意外提交到了错误的分支。你可以切换到当前分支然后cherry-pick这个commit到它本该属于的地方。

思考:看起来git cherry-pick做的事情是把一个branch上的commit,转移到另一个branch上。

什么时候使用git的cherry pick

git cherry-pick 是一个很好用工具,但并不是所有场景都适用。Cherry picking可以导致重复提交而且许多场景下的cherry pick,传统的merge是更好的选择。尽管如此,git cherry-pick在一些场景下还是很方便的工具。

团队合作

很多时候,团队里的成员会操作同一段代码。也许一个新的产品特性有一个后端和前端组件。也许在两个产品部门之间有共享的代码。也许后端开发者创建的数据结构,前端也要利用。前端开发者可以用git cherry-pick去选择创建这个数据结构的commit。这个选择可以使前端开发继续开发项目的前端部分。

思考:前后端合作时,前端可以从后端的commit上拿到伪数据?前后端分离模式下有点难哦。除非是nodejs,python,java全栈项目,前后端代码公用一个仓库的情况下。

Bug hotfixes

发现bug就要最快速度去修复。比如这个场景,开发人员在一个新的feature上开始工作。 在新分支上,他们识别出一个已存在bug。开发者创建了一个明确提交去patch这个bug。这个新的patch提交可以直接cherry-pick到master分支去修复这个bug,从而及时修复bug。

撤销改变并且恢复丢失的提交

又是一个feature分支被淘汰了并且不能被merge到master。又是pr在没有合并的情况下关闭。Git不会丢掉这些commit,通过git log和git reflog可以找到这些commit,然后cherry pick新生。

思考:找到丢失的commit hash,直接cherry pick到当前分支即可。

如何使用git cherry pick

为了演示如何使用git cherry-pick,我们假设Feature和Master分支是下面的状态。

    a - b - c - d   Master
         \
           e - f - g Feature

git cherry-pick的语法是这样的:git cherry-pick commitSha

在这个例子中,commitSha是一个commit引用。你可以通过git log找到commit引用。在这个例子中我们假设自己想在master分支上用'f'这个提交。

第一步,切换到master分支:git checkout master // gco master 第二步,执行cherry pick命令:git cherry-pick f //注意f是一个commit hash 第三步,执行完命令后,git历史记录如下

    a - b - c - d - f   Master
         \
           e - f - g Feature

成功从特性分支中提取出f commit并添加到master分支。

在自己的项目中测试成功!

➜  weidian-crm git:(feature/cherry-pick-test) git cherry-pick a5332ee6876cb5216e5e01e8911bd8facbaa19ff
[feature/cherry-pick-test da9e8cb5] 新增店铺选项;
 Date: Tue Dec 10 17:08:30 2019 +0800
 1 file changed, 22 insertions(+)

git cherry pick的使用示例

git cherry pick可以加一些额外的选项。

cherry-pick前修改commit信息

--edit

cherry-pick前删除commit信息

--no-commit

cherry-pick后commit信息上增加”signoff“标记

--signoff

无signoff: image

有signoff: image

这些有用的选项,可以帮助cherry pick做多种多样的合并策略。可以查看git合并策略去了解更多。

另外,git cherry pick还有一些解决冲突的选型:--abort --continue 和 --quit,这些选项在git merge和git rebase上更深入。

总结

cherry pick是一个强大的方便的命令,在一些场景下是很好用的。cherry pick不应该和git merge,git rebase混淆。git log命令可以帮助cherry pick去查找commit。

收获:cherry-pick可以很方便的把一个branch上的commit,复制一份到另一个branch上面。

FrankKai commented 4 years ago

参考资料: https://www.atlassian.com/git/tutorials/cherry-pick https://git-scm.com/docs/git-cherry-pick