I am trying to merge 2 commits into 1, so I followed “squashing commits with rebase” from git ready.
I ran
git rebase --interactive HEAD~2
In the resulting editor, I change pick
to squash
and then save-quit, but the rebase fails with the error
Cannot 'squash' without a previous commit
Now that my work tree has reached this state, I’m having trouble recovering.
The command git rebase --interactive HEAD~2
fails with:
Interactive rebase already started
and git rebase --continue
fails with
Cannot 'squash' without a previous commit
$ git rebase --abort
Run this code at any time if you want to undo the git rebase
$ git rebase -i HEAD~2
To reapply last two commits. The above command will open a code editor
After :wq you will be in active rebase mode
Note: You'll get another editor if no warning/error messages, If there is an error or warning another editor will not show, you may abort by runnning
$ git rebase --abort
if you see an error or warning else just continue by running $ git rebase --continue
You will see your 2 commit message. Choose one or write your own commit message, save and quit [:wq]
Note 2: You may need to force push your changes to the remote repo if you run rebase command
$ git push -f
$ git push -f origin master
you can cancel the rebase with
git rebase --abort
and when you run the interactive rebase command again the 'squash; commit must be below the pick commit in the list
First you should check how many commits you have:
git log
There are two status:
One is that there are only two commits:
For example:
commit A
commit B
(In this case, you can't use git rebase to do) you need to do following.
$ git reset --soft HEAD^1
$ git commit --amend
Another is that there are more than two commits; you want to merge commit C and D.
For example:
commit A
commit B
commit C
commit D
(under this condition, you can use git rebase)
git rebase -i B
And than use "squash" to do. The rest thins is very easy. If you still don't know, please read http://zerodie.github.io/blog/2012/01/19/git-rebase-i/
Assuming you were in your own topic branch. If you want to merge the last 2 commits into one and look like a hero, branch off the commit just before you made the last two commits (specified with the relative commit name HEAD~2).
git checkout -b temp_branch HEAD~2
Then squash commit the other branch in this new branch:
git merge branch_with_two_commits --squash
That will bring in the changes but not commit them. So just commit them and you're done.
git commit -m "my message"
Now you can merge this new topic branch back into your main branch.
I often use git reset --mixed to revert a base version before multiple commits which you want to merge, then I make a new commit, that way could let your commit newest, assure your version is HEAD after you push to server.
commit ac72a4308ba70cc42aace47509a5e
Author: <[email protected]>
Date: Tue Jun 11 10:23:07 2013 +0500
Added algorithms for Cosine-similarity
commit 77df2a40e53136c7a2d58fd847372
Author: <[email protected]>
Date: Tue Jun 11 13:02:14 2013 -0700
Set stage for similar objects
commit 249cf9392da197573a17c8426c282
Author: Ralph <[email protected]>
Date: Thu Jun 13 16:44:12 2013 -0700
Fixed a bug in space world automation
If I want to merge head two commits into one, first I use :
git reset --mixed 249cf9392da197573a17c8426c282
"249cf9392da197573a17c8426c282" was third version, also is your base version before you merge, after that, I make a new commit :
git add .
git commit -m 'some commit message'
It's all, hope is another way for everybody.
FYI, from git reset --help
:
--mixed
Resets the index but not the working tree (i.e., the changed files are
preserved but not marked for commit) and reports what has not been
updated. This is the default action.
If you want to combine the two most recent commits and just use the older commit's message, you can automate the process using expect
.
I assume:
I tested with git version 2.14.3 (Apple Git-98)
.
#!/usr/bin/env expect
spawn git rebase -i HEAD~2
# change the second "pick" to "squash"
# down, delete word, insert 's' (for squash), Escape, save and quit
send "jdwis \033:wq\r"
expect "# This is a"
# skip past first commit message (assumed to be one line), delete rest of file
# down 4, delete remaining lines, save and quit
send "4jdG\r:wq\r"
interact
If there are multiple commits, you can use git rebase -i
to squash two commits into one.
If there are only two commits you want to merge, and they are the "most recent two", the following commands can be used to combine the two commits into one:
git reset --soft "HEAD^"
git commit --amend
A simpler way for most frequent scenario.
Actually if all you want is just simply combine several recent commits into one but do not need drop
, reword
and other rebase work.
git reset --soft "HEAD~n"
~n
is number of commits to softly un-commit (i.e. ~1
, ~2
,...)Then, use following command to modify the commit message.
git commit --amend
which is pretty much the same as a long range of squash
and one pick
.
And it works for n commits but not just two commits as above answer prompted.
Let me suggest you an easier approach,
Instead of divind into GIT's deep consepts and bothering with the editor's crab, you could do the following;
Lets suppose you created a branch named bug1 from master. Made 2 commits to bug1. You only modified 2 files with these changes.
Copy these two files into a text editor. Checkout master. Paste the files. Commit.
That simple.
If your master branch git log
looks something like following:
commit ac72a4308ba70cc42aace47509a5e
Author: <[email protected]>
Date: Tue Jun 11 10:23:07 2013 +0500
Added algorithms for Cosine-similarity
commit 77df2a40e53136c7a2d58fd847372
Author: <[email protected]>
Date: Tue Jun 11 13:02:14 2013 -0700
Set stage for similar objects
commit 249cf9392da197573a17c8426c282
Author: Ralph <[email protected]>
Date: Thu Jun 13 16:44:12 2013 -0700
Fixed a bug in space world automation
and you want to merge the top two commits just do following easy steps:
git checkout 77df2a40e53136c7a2d58fd847372 -b merged-commits
git cherry-pick -n -x ac72a4308ba70cc42aace47509a5e
. (Resolve conflicts if arise any)git commit --amend
.That's it. You may push this merged version in branch "merged-commits" if you like.
Also, you can discard the back-to-back two commits in your master branch now. Just update your master branch as:
git checkout master
git reset --hard origin/master (CAUTION: This command will remove any local changes to your master branch)
git pull
Since I use git cherry-pick
for just about everything, to me it comes natural to do so even here.
Given that I have branchX
checked out and there are two commits at the tip of it, of which I want to create one commit combining their content, I do this:
git checkout HEAD^ // Checkout the privious commit
git cherry-pick --no-commit branchX // Cherry pick the content of the second commit
git commit --amend // Create a new commit with their combined content
If i want to update branchX
as well (and I suppose this is the down side of this method) I also have to:
git checkout branchX
git reset --hard <the_new_commit>
Source: Stackoverflow.com