4

I find myself doing this sometimes:

git rebase -i HEAD~2

This shows me two commits, HEAD~1 and HEAD. I change pick to f to fix up HEAD into HEAD~1. Now I combined my two most recent commits into a single commit that only has the commit message from the older commit.

Is there a command/shortcut/option to do this quickly?

What if I want to fix up the three most recent commits into the fourth most recent commit?

The only solution I was able to find was to write a script that does this for you. But I'm looking for something that's already built into git.

rkta
  • 3,959
  • 7
  • 25
  • 37
Kevin
  • 175
  • 1
  • 9
  • I had a similar thought. Seems like we are doing a lot. But unfortunately, you may need a script to do this. Else use interactive rebase – Thiru Jul 19 '18 at 19:56
  • My best guess is that git declined to make such a command because of the risks. Beginners might accidentally use up to mess up their commits. I'll just keep using rebase -i – Kevin Aug 29 '19 at 16:09

1 Answers1

4

One solution would be to use git reset HEAD~1. This would remove the last commit and put its changes in your staging area. Then you can amend those changes into the previous commit using git commit --amend -a --no-edit. The --no-edit flag makes it use the same commit message.

Be aware you can only do this if you have a clean working directory. Otherwise, you'll squash all your uncommitted changes into the same commit.

It ends up with this one-liner that you could put in an alias for convenient use:

git reset HEAD~1 && git commit --amend -a --no-edit

As a git alias:

git config --global alias.squashLast2 '!git reset HEAD~1 && git commit --amend -a --no-edit'
Robbie
  • 18,750
  • 4
  • 41
  • 45
  • 1
    This could very easily commit a bunch of unintentional changes if the working directory isn't clean. Built-in commands like `rebase` are smart enough to stop you from doing this, writing a custom command that doesn't help you in the same way is a little dangerous. – user229044 Jul 19 '18 at 20:48
  • 1
    I must agree. That `--amend -a --noedit` combo is just asking for a mess – Max Jul 19 '18 at 20:52
  • Yes, this is true @meagar good point. So i'd advise using with caution. Although i would add that even if you did accidentally commit something you didn't intend to, its only a risk if you don't realise. If you do, you can just reset the commit and fix it. And you should really be checking your diffs - so you should notice. – Robbie Jul 19 '18 at 20:53
  • @Max i've been using `--amend -a --noedit` for years. Never had any issues - what mess are you expecting? – Robbie Jul 19 '18 at 20:53
  • `-a` adds everything (included undesired changes), `--no-edit` won't prompt you for a message (which would be a last chance to double-check the change), and `--amend` means it could mess up your previous (good) commit, making it even more annoying to clean up if you made a mistake. – Max Jul 19 '18 at 20:56
  • @Max commits cannot technically be altered, so you’re really only one `git reset` away from being back in your pre-amend state, the danger (as you said) is the high likelihood of including unwanted changes and not noticing. I always recommend against `git add -a` for this reason; `git add -p` should really be the only way people stage changes. – user229044 Jul 19 '18 at 21:16
  • fair enough concerns - i've updated the answer to include a warning. i don't personally experience any problems with it, and I use it a lot - although not quite like in the scenario of this question. Usually, i've just committed all my changes and I realise i missed something, so i just `gcan` it into the last commit. I often do this several times a day. I'm very forgetful. – Robbie Jul 19 '18 at 21:20