I want to reorder last two commits in git:
right now I have:
$ git log --oneline -4
1e0ecba (HEAD, my-branch) Fix for T255
82d45dc django_extensions
af3953
A little late to the party, but I have written the following answer from the standpoint of understanding how few git commands work. The other answers will get your work done in a shorter way with the help of interactive rebase commands. I had encountered this similar situation and this is how I solved my problem -
Suppose this is how your last 4 commits look like.
* ca6807e - (HEAD -> lolo) third (4 seconds ago) <Kaustubh Butte>
|
* 61a069c - (master) fourth (18 hours ago) <Kaustubh Butte>
|
* f3b0255 - (lol) second (2 days ago) <Kaustubh Butte>
|
* c2f5e4f - first (2 days ago) <Kaustubh Butte>
Now according to your question you want to make the commit history as follows (Ignore the rest of the commit ids)-
* 0fe6482 - (HEAD -> master) fourth (5 seconds ago) <Kaustubh Butte>
|
* 2c3ba40 - (lol) third (4 minutes ago) <Kaustubh Butte>
|
* f3b0255 - (lolo) second (2 days ago) <Kaustubh Butte>
|
* c2f5e4f - first (2 days ago) <Kaustubh Butte>
To do that follow these steps -
Go to the 3rd last commit
git reset HEAD~2
Now your HEAD will point at the 'second' commit
At this point, we will switch our branch from master to lol (look at the first tree diagram)-
git checkout lol
Now if you do git status
you may find some files are in the untracked
section that is because you checked back to a previous commit in the
history which which did not have those files in tracking mode but your remote
repository has them. So you have to just ignore those files for now. But git
will not let you move forward with our approach if we keep those files
untracked. So we add all of them by doing git add *
followed by git
stash
which will save those files in a temporary stack (ignoring them
temporarily and then allowing us to pop those files from this stack later when
we need).
Now we need to move our 'fourth' commit on the current branch 'lol'. To do
that we need to use git cherry-pick
command. Copy the commit id of the
'fourth' commit which is ca6807e
in my case. Now type git cherry-pick ca6807e
. Now the tree structure will look something like this -
* 2c3ba40 - (HEAD -> lol) third (3 seconds ago) <Kaustubh Butte>
|
| * 61a069c - (master) fourth (18 hours ago) <Kaustubh Butte>
|/
|
* f3b0255 - (lolo) second (2 days ago) <Kaustubh Butte>
|
* c2f5e4f - first (2 days ago) <Kaustubh Butte>
Now you just need to do switch back to master branch and rebase lol branch on it.
git checkout master
git rebase lol
And now you have successfully interchanged the last two commits. Here is how the tree structure looks like now -
* 0fe6482 - (HEAD -> master) fourth (5 seconds ago) <Kaustubh Butte>
|
* 2c3ba40 - (lol) third (4 minutes ago) <Kaustubh Butte>
|
* f3b0255 - (lolo) second (2 days ago) <Kaustubh Butte>
|
* c2f5e4f - first (2 days ago) <Kaustubh Butte>
I truly recommend to read this answer about how to reorder commits, you'll feel like a git rockstar afterwards, I promise.
Apart from that, here's how you do it with a simple rebase (assuming you're standing on the branch you want to rebase):
git rebase -i HEAD~2
Next, change the order of the commits in the prompt.
pick f4648aee My first commit
pick 00adf09a My second commit
to
pick 00adf09a My second commit
pick f4648aee My first commit
Unbelievable that it can be that simple, if you ask me.
In general you have to use git rebase --interactive
- here is detail answer how to reorder any number of commits:
But if you want to reorder last two commits you can use this git alias:
Add to ~/.gitconfig
:
[alias]
reorder = "!GIT_SEQUENCE_EDITOR=\"sed -i -n 'h;1n;2p;g;p'\" git rebase -i HEAD~2"
and then:
$ git reorder
Rebasing(2/2)
Successfully rebased and updated refs/heads/my-branch.
Assuming no conflicts:
git rebase -i HEAD~4