I want to combine my last two commits. Here is the result of git log
:
Now I want to merge those last two commits (which are into read box) into one commit. How can I do that?
Git merging combines sequences of commits into one unified history of commits. There are two main ways Git will merge: Fast Forward and Three way. Git can automatically merge commits unless there are changes that conflict in both commit sequences.
Make changes while you are on your branch, then, when you are ready to commit, checkout the last public commit, commit your changes, get back to your local branch, and merge your new commit.
If you're currently on your "commit 1", and the commit you want to merge, "commit 2", is the previous commit, you can run git rebase -i HEAD~2 and change the first word of the second line from "pick" to "squash". Then write your file, and quit.
When you get the hash of the commit you want to get back to, run git reset --hard commit-before-the-merge: You should see some things get removed from your code editor when you run the command. If you are not sure of the hash of the last commit, you can run git reset --hard HEAD~1 to go back to the commit before the merge:
To squash the last 2 commits, at the command prompt type: git rebase -i HEAD~2 This will open up your text editor with the following lines: pick da9ee9b Added new feature W (11 minutes ago) pick af81b37 Fixed typo in feature name (2 minutes ago)
You can grab only specific commits with a very simple git command: git cherry-pick. Git's cherry-pick command allows you to "cherry pick" only the commits you want from another branch. Here are the steps to using it: Pull down the branch locally. Use your git GUI or pull it down on the command line, whatever you'd like.
There are many ways to do it (using rebase
or reset
).
The approach using git reset
:
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.git branch backup
to create a backup branch on the current commit.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.git reset --soft HEAD~2
.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
).git commit
. You'll have to enter a new commit message.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).backup
branch created at step 2 (git branch -D backup
). 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 one commit, while squash
ing the other 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 promt you for a new commit message, and voilà: a new commit containing changes from both of the older commits.
See here 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With