DEV Community

loading...

How to join several commits into one?

koscheyscrag profile image Andrei Fedotov ・2 min read

First way:

1) Consider we have the following commit’s history:

* 493f284 2019-01-11 | fourth (HEAD -> master) [Andrei Fedotov]
* d2fd771 2019-01-11 | second 3 [Andrei Fedotov]
* 4ad568e 2019-01-11 | second 2 [Andrei Fedotov]
* 1c29a96 2019-01-11 | second 1 [Andrei Fedotov]
* ca8ad26 2019-01-11 | first [Andrei Fedotov]

and we want to join second 1, second 2 and second 3 commits into one commit named second.
Execute the next command:

git rebase -i HEAD~4

2) After that the window with commits list will open in order of their creation (up to down):

pick 1c29a96 second 1
pick 4ad568e second 2
pick d2fd771 second 3
pick 493f284 fourth

3) Commits that we want to join with the previous commit we have to mark as squash. Commits which we want to stay without changes we stay as pick

pick 1c29a96 second 1
squash 4ad568e second 2
squash d2fd771 second 3
pick 493f284 fourth

4) Save and close the window. The next window will open where we should type the message for our joined commit. As a result, we obtain:

* 7a98610 2019-01-11 | fourth (HEAD -> master) [Andrei Fedotov]
* 5ef60fc 2019-01-11 | second [Andrei Fedotov]
* ca8ad26 2019-01-11 | first [Andrei Fedotov]

Another way:

1) Imagine we added one more commit and we want to join two last commits to one:

* 865a0f6 2019-01-11 | third (HEAD -> master) [Andrei Fedotov]
* 7a98610 2019-01-11 | fourth [Andrei Fedotov]
* 5ef60fc 2019-01-11 | second [Andrei Fedotov]
* ca8ad26 2019-01-11 | first [Andrei Fedotov]

2) Type the following commands:

git reset --hard HEAD~2
git merge --squash HEAD@{1}
git commit

3) Type the name of the commit in the opened window. For example: third. Now we have:

* c79f494 2019-01-11 | third (HEAD -> master) [Andrei Fedotov]
* 5ef60fc 2019-01-11 | second [Andrei Fedotov]
* ca8ad26 2019-01-11 | first [Andrei Fedotov]

If the commits we merged were pushed to the server before, we have to update them. It’s possible by typing the next command:

git push origin +branch_name

In addition, we can use helpful and convenient alias:
Bash:

git config --global alias.squash '!f(){ git reset --soft HEAD~${1} && git commit --edit -m"$(git log --format=%B --reverse HEAD..HEAD@{1})";};f'

Cmd:

git config --global alias.squash "!f(){ git reset --soft HEAD~${1} && git commit --edit -m\"$(git log --format=%B --reverse HEAD..HEAD@{1})\";};f"

Now it is possible to use this command to combine the last N commits:

git squash N

Cheers!

Discussion

pic
Editor guide