ChatGPT解决这个技术问题 Extra ChatGPT

What are the differences between `--squash` and `--no-ff --no-commit`?

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?


M
Multinerd

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:

https://i.stack.imgur.com/cbPxa.png

--squash

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

https://i.stack.imgur.com/4qDmI.png

--no-ff --no-commit

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

https://i.stack.imgur.com/BLiIy.png

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.


Isn't the purpose of -no-ff to do hide micro-commits? -> stackoverflow.com/a/2850413/321973
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."
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
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.
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