Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git - squash entire branch - one line squash command

Tags:

Whilst I am working on new code, I make many small commits to track my changes. My company, however, prefers each feature to be committed as a single commit. So the solution is to squash my entire (local) branch down to a single commit.

How do I squash an entire branch without using git rebase --interactive and then changing pick to squash for all the commits?

like image 224
masstroy Avatar asked Dec 29 '14 17:12

masstroy


People also ask

How do you squash all commits in a branch?

Git's squash commits command There is no explicit Git squash command. Instead, to squash git commits, the interactive git rebase is used. To squash all commits on a single branch, the interactive git rebase command must be passed one of two arguments: the id of the commit from which the branch split from its parent.

Should I squash all commits?

Before you start, keep in mind that you should squash your commits BEFORE you ever push your changes to a remote repository. If you rewrite your history once others have made changes to it, you're asking for trouble… or conflicts. Potentially lots of them!


1 Answers

My preferred method is a two-liner (excluding steps 1 and 4 below). The benefits are you do not need to know/record any commit IDs, you can write a simple alias to perform all the steps involved, and your actually moving your entire branch onto origin/master so that the actual merge into master can be a fast-forward and there cannot be any conflicts.

First, my assumptions:

  • You're working on a branch called my-feature-branch. This branch has diverged from master by several commits; this is the checked-out branch.
  • Your local master tracks remote branch origin/master
  • You want to squash all of your commits from my-feature-branch into a single commit ontop of the current state of origin/master (not your local master, which may be out of date)
  • All of your changes are committed, you have no unstaged changes (they will be lost during git reset --hard)

My process is as follows:

  1. Fetch, so origin/master is current:

    $ git fetch 
  2. Throw away all the commits on your local branch by resetting it to point at origin/master

    $ git reset --mixed origin/master 
  3. Merge all of your old changes from the previous state of your branch into the index

    $ git merge --squash HEAD@{1} 
  4. Commit your changes - Git will pre-populate your editor with a commit message containing all the commit messages from the squashed commits

The simple alias I mentioned would be:

alias squash="git fetch; git reset --mixed origin/master; git merge --squash HEAD@{1}" 
like image 173
meagar Avatar answered Oct 25 '22 12:10

meagar