gitgit-rebasegit-subtree

Git Interactive Rebase to Split Commit With Subtree


I have the following git history:

|    Merge (HEAD)
|\   SubTree Add (Squashed)
|    ** Git Commit I need to Split Into Two Commits **
|    Git Commit 1

I am trying to clean up my git history a bit and I have a commit that I would like to split into two commits using an interactive rebase.

git rebase -i HEAD~3
git reset HEAD^

The problem is that I get a rebase conflict with my .gitignore file for the project and the subtree I pulled in from a remote. I realized this was due to rebase not preserving merges, makes sense why there is a file conflict with two projects in a linear file history. I dug around a bit more and found there is a --rebase-merges flag to preserve the merges.

git rebase -i HEAD~3 --rebase-merges

When I run this command I never hit the interactive mode, the command doesn't fail either, its just rebases itself into the same exact repo and I can never make my edits which accomplishes nothing.

Not sure if my approach is wrong, but the goal is to split my previous commits as needed and respect my subtree project and subsequent merge without conflicts.

I am familiar with rebases but not with subtree(s) involved. Where am I going wrong about this?

UPDATE: It seems there were/are some weird problems with vscode around rebasing. I had to add the sequence.editor 'code -w' setting for my git config in order to have vscode stop and wait for the interactive rebase.

With that said, I have tried again with success to rebase my commits as needed. However, the rebase is still failing with file conflicts even when using the --rebase-merges flag.


Solution

  • git rebase is not going to be very helpful in this situation. The problem is that --rebase-merges uses the usual merge strategy that is also used by git merge, but this subtree merge needs to be treated completely differently.

    Your best bet is probably:

    1. Reset the branch before the subtree merge, which also happens to be the commit that you want to split: git reset --hard HEAD~2, but first verify that you do not have any uncommitted changes.
    2. Then you do what needs to be done with that commit.
    3. Finally you just repeat the git subtree add command.
    4. In case you have built further commit on top since you posted the question, you would just cherry-pick them to the rebuilt branch.