81

Which one should one use to hide microcommits?

Is the only difference between git merge --squash and git merge --no-ff --no-commit the denial of the other parents?

Tobias Kienzler
  • 25,759
  • 22
  • 127
  • 221

1 Answers1

81

The differences

These options exists for separate purposes. Your repository ends up differently.

Let's suppose that your repository is like this after you are done developing on the topic branch:

enter image description here


--squash

If you checkout master and then git merge --squash topic; git commit -m topic, you get this:

enter image description here


--no-ff --no-commit

Instead, if you do git merge --no-ff --no-commit; git commit -m topic, you get this:

enter image description here

Hiding micro-commits

If you really want to hide (I mean delete from your repository) your micro-commits, use --squash. Because, as you can see in the above images, you are not really hiding your micro-commits if you do not squash. Moreover, you do not usually push your topic branches to the world. Topic branches are for topic to get mature.

If you want your history to have all your micro-commits, but leave them in another line of development (the green line in the above images), use --no-ff --no-commit. But please remember that a) this is not a branch, and b) does not really mean anything in Git because it is just another parent of your commit.

Please refer to Git Branching - What a Branch Is if you really want to understand.

highboi
  • 673
  • 7
  • 28
Yasushi Shoji
  • 4,028
  • 1
  • 26
  • 47
  • 1
    Isn't the purpose of `-no-ff` to _do_ hide micro-commits? -> http://stackoverflow.com/a/2850413/321973 – Tobias Kienzler Aug 16 '12 at 09:29
  • 6
    No. `--no-ff` is to tell git "Do not first forward even if you can. instead create a merge commit and reuse all existing commits." – Yasushi Shoji Aug 16 '12 at 09:36
  • 2
    You mean _fast_ forward? Sure it will use the commits, but if you look at the history of the branch you merged into, you will not see the micro-commits in its _own_ history, but only that another branch (containing these commits) has been merged, while a fast-forwarded merge (if possible) would simply rebase the micro-commits into the branch, making history look as though the two branches have not separated since the original split, while `--no-ff` conserves that split – Tobias Kienzler Aug 16 '12 at 09:49
  • 2
    Ah, OK. I thought that "hide" to "remove from the entire porosity history", because that's what `--squash` does. Yes, you can _hide_ your micro-commits in the development line, but that does not mean _another branch_ as you described above. Because you are merging your development branch to the master, it will no longer be a separate _branch_. – Yasushi Shoji Aug 16 '12 at 09:59
  • 4
    Ok, then we understand it the same way but I misunderstood your meaning of "hiding", sorry. So if you maybe rephrase that into something like "`-no-ff --no-commit` does not hide the _existence_ of micro-commits, while `--squash` does", and that is the only difference, I'd accept this answer – Tobias Kienzler Aug 16 '12 at 10:03
  • Thanks! I guess I still have to learn and accept that topic branches are not meant to be conserved... – Tobias Kienzler Aug 16 '12 at 10:40
  • 1
    Note that if you do a ff merge, the diagram will look exactly the same as the first one, with the exception that *master* will also point to "world" (i.e. same like *topic*) – Rado Jun 21 '17 at 00:22