With the last git release, git-rebase gained a new option: --interactive.

If you already had the feeling that in a patch series of yours you should have ordered patches differently, or merged some, then this command is what you dreamed of. Here is how it works…

Let's pretend you want to rework your last 10 patches, you'll run:

   $ git rebase -i HEAD~10

It will launch your $EDITOR and you'll see something like:

   # Rebasing 16d3800..14f3d11 onto 16d3800 
   # 
   # Commands: 
   #  pick = use commit 
   #  edit = use commit, but stop for amending 
   #  squash = use commit, but meld into previous commit 
   # 
   # If you remove a line here THAT COMMIT WILL BE LOST. 
   # 
   pick 6270640 Simplify write_tree using strbuf's. 
   pick 27c528a Further strbuf re-engineering. 
   pick fd82c9a Eradicate yet-another-buffer implementation in buitin-rerere.c 
   pick eee488f More strbuf uses in cache-tree.c. 
   pick 16878b5 Add strbuf_rtrim and strbuf_insert. 
   pick e9081af Change semantics of interpolate to work like snprintf. 
   pick 99c3ef5 Rework pretty_print_commit to use strbufs instead of custom buffers. 
   pick 203db5d Use strbuf_read in builtin-fetch-tool.c. 
   pick a20d939 Use strbufs to in read_message (imap-send.c), custom buffer--. 
   pick 14f3d11 Replace all read_fd use with strbuf_read, and get rid of it.
   ~
   ~
   ~
   ~
   ~
   ~[1]

Then you can rewrite "pick" into "edit" if you want to change something in a commit, or "squash" if you want to merge it with the one from the line before.

What the small help doesn't say is that you can actually reorder your commits, and it will do what you expect it to do. I used it 10 minutes ago, because I have this string buffer module I extend on a regular basis, I squashed every API extension of that module in one commit using that.

Each time one change needs you to edit anything because either you asked for it, or that one of the change you asked for generated a conflict, then as usual the rebase will stop. You will be prompted to make the change, or fix the conflict, or merge comments (in case of a squash), and when all is in order, you just need to:

   $ git rebase --continue

This is just awsomely simple and intuitive

Notes

[1] if you don't have those, your $EDITOR sucks btw