git merge --squash和git cherry-pick之间的区别是什么?

时间:2015-01-28 10:21:05

标签: git version-control

如果我在一个标准的主要功能工作流程中工作,那么将一个功能分支压缩到主服务器并将其挑选到主服务器之间的区别是什么?

示例分支:

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

我认为两者都有相同的输出,即

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

2 个答案:

答案 0 :(得分:7)

merge --squashcherry-pick之间存在两个重要差异:

1。采摘樱桃只会移动一次提交

也就是说,如果您遇到上述情况并且(在master上)执行git cherry-pick feature,则生成的分支将如下所示:

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

这意味着来自f1的更改在主设备上不存在(如果f2取决于它们,则挑选可能会失败。

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-speak ,因为“我没有提交我所做的事情”。事实上,第二句话更加方便用户......

如果您希望逐步开发(通过提交导致解决方案的所有小步骤,例如在每次成功的测试运行后提交,此功能都很方便。在这种情况下,您的历史可能会变得混乱有数百个单行提交。所以最好不时地进行merge-squash-commit(例如,在你开发了一部分功能之后)。

答案 1 :(得分:0)

通过选择樱桃,您可以将 change 另一个提交应用于当前分支。

合并(紧随提交)与合并(相对于生成的工作目录和索引,而不是历史记录)相同。

这是一个例子(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

如您所见,在摘录了 change 之后,应用了引入的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都被保留。这是因为与压缩合并(之后是提交)与就结果工作目录和索引(当然不是历史记录)而言,两次提交的常规合并相同。