Question

I have a repository with various commits which I want merged in two patches. One patch introducing the feature and another changing the existing code to use it. Problem is, when I was coding and committing I didn't have that in mind, so there are commits which do both. How can I split these commits?

I know that somehow I can do it with git rebase -i and picking edit for each commit I'd like to change, but this way I can only change the commit message, not the code

Was it helpful?

Solution

Git rebase allows you to split commits:

In interactive mode, you can mark commits with the action "edit". However, this does not necessarily mean that git rebase expects the result of this edit to be exactly one commit. Indeed, you can undo the commit, or you can add other commits. This can be used to split a commit into two:

  • Start an interactive rebase with git rebase -i ^, where is the commit you want to split. In fact, any commit range will do, as long as it contains that commit.

  • Mark the commit you want to split with the action "edit".

  • When it comes to editing that commit, execute git reset HEAD^. The effect is that the HEAD is rewound by one, and the index follows suit. However, the working tree stays the same.

  • Now add the changes to the index that you want to have in the first commit. You can use git add (possibly interactively) or git gui (or both) to do that.

  • Commit the now-current index with whatever commit message is appropriate now.

  • Repeat the last two steps until your working tree is clean.

  • Continue the rebase with git rebase --continue.

If you are not absolutely sure that the intermediate revisions are consistent (they compile, pass the testsuite, etc.) you should use git stash to stash away the not-yet-committed changes after each commit, test, and amend the commit if fixes are necessary.

OTHER TIPS

Here is what I would do:

git reset COMMIT_BEFORE_CHANGES --soft

and re-commit everything in the appropriate commits. --soft will leave your working tree and index in the state they are before the reset.

Needless to say, that you shouldn't do something like this after someone has pulled from you.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top