Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between merge --squash and rebase?

I'm new to git and I'm trying to understand the difference between a squash and a rebase. As I understand it you perform a squash when doing a rebase.

like image 307
GiH Avatar asked Mar 11 '10 17:03

GiH


People also ask

What is the difference between Squash and merge and merge?

Squash merging is a merge option that allows you to condense the Git history of topic branches when you complete a pull request. Instead of each commit on the topic branch being added to the history of the default branch, a squash merge adds all the file changes to a single new commit on the default branch.

What is rebase and Squash in Git?

With “squash”, you can merge all of your commits from a feature branch into a single commit, which can then be added to the end of the main branch. In this example, after the 2 feature branches have been rebased and merged in, instead of being 3 commits each, they're now just 1.

Is it better to Squash and merge?

As a general rule, when merging a pull request from a feature branch with a messy commit history, you should squash your commits. There are exceptions, but in most cases, squashing results in a cleaner Git history that's easier for the team to read.

Is rebase better than merge?

Rebasing is better to streamline a complex history, you are able to change the commit history by interactive rebase. You can remove undesired commits, squash two or more commits into one or edit the commit message. Rebase will present conflicts one commit at a time whereas merge will present them all at once.


2 Answers

Merge commits: retains all of the commits in your branch and interleaves them with commits on the base branchenter image description here

Merge Squash: retains the changes but omits the individual commits from history enter image description here

Rebase: This moves the entire feature branch to begin on the tip of the master branch, effectively incorporating all of the new commits in master

enter image description here

More on here


The first two diagrams come from About pull request merges on the GitHub Docs

like image 170
Md Ayub Ali Sarker Avatar answered Sep 28 '22 02:09

Md Ayub Ali Sarker


Both git merge --squash and git rebase --interactive can produce a "squashed" commit. But they serve different purposes.

  • git merge --squash abranch

will produce a squashed commit on the destination branch, without marking any merge relationship. (Note: it does not produce a commit right away: you need an additional git commit -m "squash branch")

This is useful if you want to throw away the source branch completely, going from (schema taken from SO question):

git checkout stable            X               stable          / a---b---c---d---e---f---g tmp 

to:

git merge --squash tmp git commit -m "squash tmp"   # In the following graph, G is c--d--e--f--g squashed together            X-------------G stable          / a---b---c---d---e---f---g tmp 

and then deleting tmp branch.


Note: git merge has a --commit option, but it cannot be used with --squash. It was never possible to use --commit and --squash together. Since Git 2.22.1 (Q3 2019), this incompatibility is made explicit:

See commit 1d14d0c (24 May 2019) by Vishal Verma (reloadbrain). (Merged by Junio C Hamano -- gitster -- in commit 33f2790, 25 Jul 2019)

merge: refuse --commit with --squash

Previously, when --squash was supplied, 'option_commit' was silently dropped. This could have been surprising to a user who tried to override the no-commit behavior of squash using --commit explicitly.

git/git builtin/merge.c#cmd_merge() now includes:

if (option_commit > 0)     die(_("You cannot combine --squash with --commit.")); 

  • git rebase --interactive

replays some or all of your commits on a new base, allowing you to squash (or more recently "fix up", see this SO question), going directly to:

git checkout tmp git rebase -i stable     stable       X----------------G tmp      / a---b 

If you choose to squash all commits of tmp (but, contrary to merge --squash, you can choose to replay some, and squashing others).

So the differences are:

  • squash does not touch your source branch (tmp here) and creates a single commit where you want.
  • rebase allows you to go on on the same source branch (still tmp) with:
    • a new base
    • a cleaner history
like image 43
VonC Avatar answered Sep 28 '22 02:09

VonC