how to re-order commits in Git non-interactively

13.2k views Asked by At

What non-interactive git command(s) achieve the change from Before to After?

Before:

A---B---C---D

After:

A---C'---B'---D'
4

There are 4 answers

5
Paŭlo Ebermann On

Try this:

git reset --hard A
git cherry-pick C
git cherry-pick B
git cherry-pick D

There may be a way with git rebase, but I didn't really understand it.

4
Mohamed Mansour On

In your case, you can rebase interactive: git rebase -i HEAD~4 Then you can just reorder your picks

For example lets add three more files to our branch:

git add A
git commit -m "A"

git add B
git commit -m "B"

git add C
git commit -m "C"

Your shortlog will be:

$ git shortlog
 (3):
      A
      B
      C

If you want to reorder B with C:

$ git rebase -i HEAD~2
pick 1f9133d B
pick 33f41be C

You just re-order them to be:

pick 33f41be C
pick 1f9133d B

After you're done writing, see the shortlog:

$ git shortlog
 (3):
      A
      C
      B

You can do the same thing with all the commits by re-ordering. It is like what you see is what you get, which is pretty cool :)

0
pfalcon On

See How do I run git rebase --interactive in non-interactive manner? for using git rebase --interactive in non-interactive manner.

Then, if you have formal criteria for reordering commits, you can script that, see for example Really flatten a git merge to reorder commits by the original commit date.

0
Johannes Riecken On

If you want to reorder commits in a script and don't want to deal with the commit hashes, then this seems to work as a general solution (based on Paŭlo Ebermann 's answer):

git reset --hard @~3
git cherry-pick ORIG_HEAD~1
git cherry-pick ORIG_HEAD~2
git cherry-pick ORIG_HEAD

I assume that running this sequence of commands twice in a row will restore the commit tree to what it was before, except for changing the changed commit hashes.