git merge --squash 和 git cherry-pick 有什么区别?

9

如果我使用标准的主分支-功能分支开发流程,将一个功能分支合并到主分支和将其 cherry-pick 到主分支之间有什么区别?

示例分支:

m1 -- m2                 master
  \-- f1 -- f2           feature

我认为两者输出相同,即

m1 -- m2 -- -- -- m3     master
  \-- f1 -- f2           feature
2个回答

12

merge --squashcherry-pick之间有两个重要的区别:

1. Cherry-pick只移动一个提交

也就是说,如果你有像上面描述的情况,并且你(在master分支上)执行git cherry-pick feature,结果分支会看起来像这样:

m1 -- m2 -- f2’           master
  \-- f1 -- f2           feature

这意味着来自 f1 的更改不会出现在主分支上(如果 f2 依赖于它们,那么可能无法使用 Cherry-pick)。

2. Cherry-picking 创建一个提交

merge --squash 不会立即提交,而是创建所有更改的概要,并使其准备好提交。 这本质上是您完整分支更改的补丁,与 git diff m1..feature 显示的相同。

在我的机器上,快速测试产生了这个输出:

$ test git:(master) git merge --squash testbranch
Squash commit -- not updating HEAD
Automatic merge went well; stopped before committing as requested

这里重要的部分是“不更新HEAD”,这是“git术语”,意为“我没有提交我所做的内容”。实际上,第二句话更容易理解……

如果您喜欢逐步开发(通过在每次成功测试运行之后进行提交,例如使用一个提交记录来记录所有导致解决方案的小步骤)。则此功能很方便。在这种情况下,您的历史记录可能会混乱,有成百上千个一行提交记录。因此,最好定期进行合并压缩提交(例如,在您开发完一部分功能之后)。


2

挑选让你能够将另一个提交引入的更改应用到当前分支。

与压缩合并(跟随提交)相比,合并执行相同的操作(关于生成的工作目录和索引,而不是历史记录)。

以下是一个示例(git的某些输出未显示)。

设置

$ git init
$ echo sahred file > shared-file.txt
$ git add .
$ git commit -m 'added shared-file.txt in master branch'
$ git checkout -b dev
$ touch dev.txt
$ git add .
$ git commit -m 'added dev.txt in dev branch'
$ echo shared file > shared-file.txt 
$ git add .
$ git commit -m 'fixed typo in shared-file.txt in dev branch'
$ git checkout master

我们现在有一个名为dev的分支,其中包含一个额外的文件(dev.txt),并且修复了shared-file.txt中的拼写错误。我们切换回master分支来比较挑选和合并。 挑选
$ git cherry-pick dev
$ git log --oneline --graph
* 8019b05 (HEAD -> master) fixed typo in shared-file.txt in dev branch
* 7dbd3aa added shared-file.txt in master branch
$ ls
shared-file.txt
$ cat shared-file.txt 
shared file

正如您所看到的,在挑选完更改之后,应用了在dev分支中的最后一个提交引入的更改(修复了shared-file.txt中的拼写错误),但是附加文件dev.txt并没有被带过来,因为它不是在dev分支中的最后一个提交中创建的。
现在我们撤销这个挑选,并与合并结果进行比较。 合并(压缩并提交)
$ git reset HEAD~1 --hard # undo cherry-pick
$ git merge dev --squash
$ git commit -m 'merged dev'
$ git log --oneline --graph
* 01dd755 (HEAD -> master) merged dev
* 7dbd3aa added shared-file.txt in master branch
$ ls
dev.txt  shared-file.txt
$ cat shared-file.txt 
shared file

正如您所看到的,这两个错别字已经被修正,并且dev.txt也被保留下来。这是因为使用压缩合并(随后提交)与常规合并两个提交在生成的工作目录和索引方面是相同的(但历史记录当然不同)。

1
这就是我在寻找的答案,谢谢。 - Dino Tw

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接