Greg Nisbet
Greg Nisbet

Reputation: 6994

git reorder commits in branch "in place" without rebasing

Edit:

I was fundamentally using git rebase -i ... wrong and thinking of it the wrong way when I wrote this question. git rebase -i [some branch name or tag or commit hash] allows you to explicitly identify the start of the sequence of commits that you are interactively editing (e.g. git rebase -i HEAD~3). Relying on the default argument in the case of a branch tracking another branch is a weird way to use interactive rebase, not a normal one.


git rebase -i is incredibly useful for reordering commits and combining them. However, sometimes I want to reorder, drop, combine, or split commits without the rebasing behavior. The main use case I can think of for doing this is cleaning up a development branch first and then rebasing it and potentially dealing with merge conflicts rather than doing both steps at once.

In the following scenario I am working in a git repository where the main branch has a linear history and reviewed commits are incorporated into the main branch via cherry-pick. I am working on commits B, C and D on a branch called my-feature. Let's further suppose that my-feature tracks the main branch. Commit A in the main branch is a big refactor.

Future

*
|
A      D (my-feature)
|     /
*    C
|   /
*  B
| /
*

Past

Suppose I want to reorder C and B. I want to reorder them first before marching my-feature forward beyond A.

I first want to do this change:

Future

*
|
A      D (my-feature)
|     /
*    B
|   /
*  C
| /
*

Past

and then do this change:

Future


      D (my-feature)
     /
    B
   /
  C
 /
*
|
A
|
*
|
*
|
*

Past

Upvotes: 2

Views: 1965

Answers (2)

matt
matt

Reputation: 534977

I'm not seeing what the problem is. I started with a graph just like your starting graph, with a branch main containing A and a branch my-feature containing B C D, and did this:

$ git checkout my-feature
$ git rebase -i <theCommitBeforeB>
[swap the C and B commits, and save]
$ git rebase main

And I ended up with your ending graph, with A on main and then C B D growing out the end of it on my-feature.

And

Upvotes: 1

Chris Dodd
Chris Dodd

Reputation: 126203

To do what you describe you want to rebase on the same base and reorder.
git rebase -i HEAD~3 will allow you to reorder/change the most recent three changes. It will bring up an editor window that looks something like:

pick 5f22324 This is change B
pick 843611f This is change C
pick 76e4eab This is change D

showing the most recent three changes in order from oldest to newest. To reorder B and C, just swap the first two lines. You can also squash changes (by changing the pick to squash or s) and remove changes (by just deleting them).

Upvotes: 2

Related Questions