Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Squash and Merge on the Command line

With the introduction of GitHub's Squash and Merge feature, this has become less prevelant, however it's still useful in scenarios where GitHub's interface is unavailable.

Let's talk through two ways to do a squash and merge on the command line.

Take 1: Interactive Rebase

When to use it

  • When you have not merged master into your feature branch
  • There are no merge conflicts
  • When you want to retain the original committer on the squashed commit

Steps

You are working on branch feat-fuu. You want to create a single squashed commit to push to your remote feat-fuu branch on GitHub.

  1. git checkout master
  2. git pull
  3. git checkout feat-fuu
  4. git checkout feat-fuu-backup
    • Optional but recommended - make a backup version of your branch
  5. git checkout feat-fuu
  6. EDITOR='code -w' git rebase -i master
    • Setting EDITOR is optional, and depends on your editor of choice. With the case of VSCode or Sublime Text, the -w flag tells the editor to "wait" until the file exits before closing.
  7. In your editor, edit all of the additional commits to squash. Leave the first commit in the list alone
  8. Save and exit your editor
  9. Rewrite a nice single commit message for the commit
  10. Check the history. feat-fuu will now contain a single commmit ahead of master
  11. git push -f origin feat-fuu
    • Please be careful with this step, as it overwrites your original remote branch on GitHub

Take 2: Git Squashed Merge

When to use it

  • You have merged master into your branch and resolved conflicts
  • You don't care about the author of the original commits (you will be rewriting it)

You are working on branch feat-fuu. You want to create a single squashed commit to push to your remote feat-fuu branch on GitHub.

  1. git checkout master
  2. git pull
  3. git checkout feat-fuu
  4. git checkout feat-fuu-backup
  5. git checkout master
  6. git branch -D feat-fuu
    • You are deleting your original branch. Ensure you have created feat-fuu-backup beforehand and it has your full commit history.
  7. git checkout -b feat-fuu
    • This creates a fresh branch from master
  8. git merge --squash feat-fuu-backup
    • You are merging and squashing your original work into a single commit. This is where the magic happens.
  9. Rewrite a nice single commit message for the commit
  10. Check the history. You should see a single commmit on your branch that branched from master
  11. git push -f -u origin feat-fuu
    • Please be careful with this step, as it overwrites your original branch on GitHub

References

  • This Stack Overflow Post has additional detail about the differences between these two approaches.
@toerndev

This comment has been minimized.

Copy link

toerndev commented Apr 15, 2020

Appreciate the write-up. I'm not sure it's equivalent but this way seems to avoid the force push:

  1. git checkout feat-fuu
  2. git rebase -i master <- squash down to first commit
  3. git checkout master && git cherry-pick feat-fuu <- can push to master without -f, retaining the original author
  4. optional: git branch -D feat-fuu && git push origin --delete feat-fuu
@aortbals

This comment has been minimized.

Copy link
Owner Author

aortbals commented Apr 15, 2020

@toerndev Thanks for the comment! I would never suggest force pushing to master, as that is generally a bad practice and should only ever be done in extreme circumstances. Specifically, in both of these flows you are rewriting the original commit history of your feature branch, not master. I'll try and make it more clear in the document which branch you are pushing.

@toerndev

This comment has been minimized.

Copy link

toerndev commented Apr 15, 2020

@aortbals Oh! Sorry for the lazy reading! 😄 I see now that you're squashing the remote feature branch, not squash-delete-merge-to-master! This page came up when googling how to squash-merge while keeping the author. I agree about avoiding force push to master, thus my sort of misdirected comment.

@MykolaGolubyev

This comment has been minimized.

Copy link

MykolaGolubyev commented Apr 22, 2020

That's a very good explanation! Thank you.
Did you mean to use

git branch feat-fuu-backup

instead of

git checkout feat-fuu-backup
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.