21

I want to combine my last two git commits. Here is the result of git log:

A partial git log with commits in a red box

You can see my last two commits highlighted in the red box: 6aa74e47a35bb88a7f97366dda1099fd0dc3b185 and 77c15d644fa2dac4c341471d337ac3d14a552a2b.

Now I want to merge those last two commits into one commit. How can I do that?

2 Answers 2

30

There are many ways to do it (using rebase or reset).

The approach using git reset:

  1. No matter the approach, before anything else make sure the working copy is clean. Use git status to find out. If there are uncommitted changes either save them in a stash (git stash or commit them on a temporary branch.
  2. Run git branch backup to create a branch named backup on the current commit.
    It is not really needed (the same result can be achieved using the reflog or by writing down the hash of the current commit) but it is the easiest way to restore the current status if something goes wrong.
  3. Run git reset --soft HEAD~2.
    This moves HEAD two commits in the past (on commit e8de117) without changing the working tree or the index. The index and the working tree look now like they were just before you created the commit 6aa74e4. All the files changed in the last two commits will be already added to the index. Because HEAD is on e8de117, the next commit will be created on top of e8de117 (it will "replace" commits 6aa74e4 and 77c15d6).
  4. Run git commit. You'll have to enter a new commit message.
  5. If the result doesn't look like you expected (git diff backup should not report any difference) or if you have changed your mind, run git reset --hard backup to go back where you started from (actually, right after step #2).
  6. If you are pleased with the output then remove the backup branch created at step 2 (git branch -D backup).
  7. That's all.
Sign up to request clarification or add additional context in comments.

4 Comments

I did it, however the final commit is wrong kinda .. I mean I expect it be contain some codes which are exist in one commit before the last one. thank you anyway.
can't git push the result.
IMPORTANT!! there is a mistake: after git branch backup you will be in the new 'backup' branch. You have to git checkout master (or the branch you are working).
@Ivan No. git branch does not change the current branch.
28

You're looking for the squash feature of an interactive rebase:

Use git rebase -i HEAD~2 to start an interactive rebase.

In the opening editor, all commits that are part of the rebase are listed. In this case, since we provided the HEAD~2 argument to the rebase call, we see two commits, each prefixed by pick.

Not changing anything would lead rebase to pick, i.e. apply both commits, and nothing would be different.

Instead, what you want to do is to pick only the first commit, while squashing (use commit, but meld into previous commit) the second one. This way, you squash the second commit into the first one, resulting in a single commit.

When you safe and exit now, git will prompt you for a new commit message, and voilà: a new commit containing changes from both of the older commits.

See "Squashing commits with rebase" for detailed instructions.

As always when messing with history (as squashing different commits into a new one definitely is), you should only perform such operations on commits that you are sure nobody else based their work on.

1 Comment

What is the command or sequence of commands to do this non-interactively? I’m thinking of adding an alias to automate this.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.