Botel Vyvten
Botel Vyvten

Reputation: 143

What's the difference between git merge --squash and git cherry-pick?

If I work in a standard master-feature workflow, what'd be the difference between squashing a feature branch into master and cherry-picking it into master?

Example branches:

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

I think both have the same output ie

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

Upvotes: 9

Views: 9269

Answers (2)

timgeb
timgeb

Reputation: 78650

Cherry-picking lets you apply the change another commit introduced to your current branch.

Merging with squashing (followed by committing) does the same as merging (with respect to the resulting working directory and index, not the history).

Here's an example (some output by git is not shown).

Setup

$ 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

We now have a branch dev with an additional file (dev.txt) and where the typo in shared-file.txt is fixed. We switched back to the master branch to compare cherry-picking and merging.

Cherry-picking

$ 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

As you can see, after cherry-picking the change the last commit in the dev branch introduced was applied (fixing the typo in shared-file.txt) but the additional file dev.txt was not carried over, because it was not created in the last commit in the dev branch.

We now undo the cherry-pick and compare with the result of merging.

Merging (with squashing and committing)

$ 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

As you can see, both the typo were fixed and dev.txt was carried over. This is because merging with squashing (followed by committing) is the same as the regular merge of two commits with respect to the resulting working directory and index (but not the history of course).

Upvotes: 2

Andreas Wolf
Andreas Wolf

Reputation: 1065

There are two important differences between merge --squash and cherry-pick:

1. Cherry-picking only moves one commit

That is, if you have a the situation you described above and you (on master) do a git cherry-pick feature, the resulting branch will look like this:

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

This means the changes from f1 are not present on master (and cherry-picking possibly fails if f2 depends on them.

2. Cherry-picking creates a commit

merge --squash does not immediately commit, instead it creates a summary of all the changes and makes them ready to commit. This is essentially a patch of your complete branch changes, the same that git diff m1..feature would show.

On my machine, a quick test gave this output:

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

The important bit here is the "not updating HEAD", which is git-speak for "I didn’t commit the stuff I did". The second sentence in fact is far more user-friendly…

This feature is handy if you like to develop step-by-step (by committing all the little steps that led to the solution, e.g. with a commit after every successful test run. In this case, your history would likely get cluttered with hundreds of one-liner commits. So it is probably better to do a merge-squash-commit every now and then (e.g. after you have developed one bit of the functionality).

Upvotes: 12

Related Questions