void.pointer
void.pointer

Reputation: 26385

How to add new commit before root commit of branch?

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?

Upvotes: 1

Views: 85

Answers (2)

void.pointer
void.pointer

Reputation: 26385

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.

Upvotes: 1

sfletche
sfletche

Reputation: 49744

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    

Upvotes: 1

Related Questions