how to re-order commits in Git non-interactively

12,632

Solution 1

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 :)

Solution 2

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.

Solution 3

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.

Share:
12,632
James Tauber
Author by

James Tauber

Entrepreneur and Pinax Lead Developer; Web Standards and Open Source Guy; Movie Producer and Digital Cinematographer; Composer and Music Theorist; Greek Scholar and Doctoral Student in Linguistics

Updated on June 15, 2022

Comments

  • James Tauber
    James Tauber almost 2 years

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

    Before:

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

    After:

    A---C'---B'---D'
    
  • James Tauber
    James Tauber about 13 years
    git rebase -i will certainly let you do it; but wasn't sure how you'd achieve the same thing non-interactively
  • Ben Jackson
    Ben Jackson about 13 years
    All git rebase does is use git format-patch and then git am to reapply them (possibly in a different order). It's a fundamentally interactive process, though, since re-applying the patches out of order can fail and require user intervention.
  • Andreas Wederbrand
    Andreas Wederbrand about 10 years
    How come this answer gets up votes when it clearly does not answer the question? OP asks for a way of doing this NON-INTERACTIVELY and this answer is all about how to do it INTERACTIVELY.
  • Thomson Comer
    Thomson Comer over 9 years
    I think this really answers the question without rebase -i, except you ordered the cherry-picks B, C, D instead of C, B, D so it doesn't actually solve the problem :)
  • Paŭlo Ebermann
    Paŭlo Ebermann over 9 years
    @ThomsonComer oops, seems nobody noted this for almost 4 years. Thanks.
  • hugo der hungrige
    hugo der hungrige almost 9 years
    @AndreasWederbrand probably because that's what most people (including me) were looking for, when they came here, though you're absolutely right.
  • Antonio
    Antonio over 7 years
    This solution is to the point. Besides, for interactive, it works perfectly for TortoiseGit: tortoisegit show log, reset to "A" (HARD), tortoisegit show reflog, right click on the entry before the reset, "Show Log...", and then start the cherry picking to reorder your commits. If necessary, start by stashing your uncommitted local changes.
  • Larry N
    Larry N over 4 years
    @AndreasWederbrand People searched for "How to reorder commits in git" and this on helped them :v.
  • Olsgaard
    Olsgaard about 2 years
    Let's imagine there is a thousand commits (or a million, if you don't think a thousand lines isn't much in your code editor) between B and C. How do you do this in a manageable way with an interactive rebase?