1

I have a branch with 2 commits. I need to add a 3rd commit before both of them. Normally I'd simply add a new tip commit, do git rebase -i and then move it to the top (make it the first commit on the branch). However, I cannot do this since the specific change in question impacts code changed by the previous 2 commits, and I need to make this change before those changes (to avoid unnecessary conflicts).

At the moment the only way I've been able to accomplish this is to do roughly this:

  1. $ git rebase -i origin/master
  2. mark top commit as edit (oldest commit)
  3. $ git reset --soft @^
  4. $ git stash save 'Last commit'
  5. make some code changes
  6. $ git commit -am 'New commit'
  7. $ git stash pop
  8. $ git commit -aC @{2} (commit the previous commit again, with same message)
  9. $ git rebase --continue (until finished)

This is a lot of steps, and it's messy. It would be nice to be able to mark the commit BEFORE my branch's first commit as an edit and then just commit on top of that. But that won't work, if my merge-base is a merge commit. I tried this:

$ git rebase -i origin/master^

I also tried:

$ git rebase -i origin/master^2

Both parents on the merge commit as my base. However, I get a ton of extra commits in the todo file, I'm not sure why.

What is an easy and intuitive method of accomplishing this?

void.pointer
  • 24,859
  • 31
  • 132
  • 243
  • You can save ~1/2 the steps if you checkout a new branch, commit to that, and then switch back to your original and `git rebase --onto`. – Andrew C Jan 08 '16 at 17:33
  • Does this answer your question? [Insert a commit before the root commit in Git?](https://stackoverflow.com/questions/645450/insert-a-commit-before-the-root-commit-in-git) – questionto42 Jun 13 '22 at 09:33

2 Answers2

1

Could be accomplished with cherry-pick

Step 1. record the sha's of the 3 commits (say they are A1, B1, and C1)

Step 2. perform the following from the branch in question (in the example below, I'm assuming it's branched off of origin/master)

git reset --hard origin/master
git cherry-pick C1
git cherry-pick A1    
git cherry-pick B1    
sfletche
  • 47,248
  • 30
  • 103
  • 119
1

I asked this same question on the git mailing list and found a pretty cute workaround. In the TODO file for an interactive rebase, simply add an exec false to the top:

exec false
pick 123abc Commit 1
pick 456xyz Commit 2

exec will execute the given shell command. false causes a non-zero return code which rebase interprets as failure and stops the rebase before the next commit, allowing you to make a commit directly. Then you can git rebase --continue normally.

void.pointer
  • 24,859
  • 31
  • 132
  • 243