19

Can we use rebase to squash multiple commits into one single commit on the same branch?

Taking an example, i have created two topic branches - issueA_1 and issueA_2 from master. I make a couple of commits in both branches, as can be seen in the diagram(i am using commit names here instead of commit hashes for brevity) :

           -->  (issueA_1) - commitX1
          /
(master)--
          \
           -->  (issueA_2)
                   |
                commitY1
                   |
                commitY2

Then i do :

git checkout issueA_2
git rebase -i issueA_1

I change the rebase file to :

pick commitY1
fixup commitY2

After this rebase, the commit history looks like this :

           -->  (issueA_1) - commitX1
          /
(master)--
          \
           -->  (issueA_2)
                   |
                commitX1
                   |
                commitY1
                   |
                commitY2

I don't need the branch issueA_1 anymore, so i do :

git branch -D issueA_1

The commit history of issueA_2 isn't pretty enough to be merged into master yet. I want commitX1, commitY1 and commitY2 of this branch to be squashed into 1 single commit before i merge into master. Is this possible?

faizal
  • 3,497
  • 7
  • 37
  • 62
  • possible duplicate of [Squash my last X commits together using Git](http://stackoverflow.com/questions/5189560/squash-my-last-x-commits-together-using-git) – Sascha Wolf Aug 15 '14 at 10:13

2 Answers2

38

Yes, the simplest way I find is to do:

git rebase -i HEAD~3

This will let you review the last 3 commits and you can then squash them.

Ilion
  • 6,772
  • 3
  • 24
  • 47
  • Using this command I get the following text on my command window - pick pick # Rebase 551a895..4a2dc5e onto 551a895 (2 commands) # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit ..... and so on. I'm unable to type any command mentioned on that window. – phougatv Aug 25 '22 at 11:30
  • 1
    @phougatv You probably need to use vim commands. Press `i` to enter interactive mode then change the list of commits as described. Press `esc` to exit interactive mode then press `:x` to exit and save. – Ilion Aug 26 '22 at 15:19
3

In your case,

git checkout issueA_2
git rebase -i master

or

git rebase -i commitX1^ #parent of commitX1 in branch issueA_2

should also work. In this case, you don't need to count (I'm usually one off).

martin
  • 3,149
  • 1
  • 24
  • 35
  • what is `git co`? Did you mean `git checkout` ? – faizal Aug 15 '14 at 09:18
  • Would "commitX1^" be identical to "HEAD~3" in this context? – faizal Aug 15 '14 at 09:21
  • Yes, if I have counted that correcly ;) – martin Aug 15 '14 at 09:28
  • ok. How could i have missed "git rebase -i master"! That was the simplest and safest option. I guess i was a little nervous thinking of `rebase` and `master` in the same line..it didn't strike me that the command does not effect the master branch at all. – faizal Aug 15 '14 at 09:32