-1

Let me be clear upfront: I squashed, committed, and pushed to public history every commit in a branch. There is only one commit in the public history. My working directory is clean. There are no changes to any files.

Now, I want to split the one commit into multiple to recreate the history without changing any files unnecessarily.

I'm currently using GitKraken, so suggestions using it would be appreciated. It doesn't have the full featureset implemented (like git commit --allow-empty. Not a thing.), but I can access the command line to do anything it doesn't directly support.

Casey
  • 10,297
  • 11
  • 59
  • 88

1 Answers1

1

To split a single commit into multiple commits (using command line git for examples):

Optional: git branch backupBranchName

In case you're worried about making a mistake and losing your work, or want to be able to back out of changes easily, make a backup of your branch first.

  1. git reset HEAD^

Undo the current commit while keeping the changes with a soft reset. The previously commited changes will now become unstaged changes.

  1. git add --patch .

Choose the first subset of changes to form the first commit, and stage them. If they are already split by file, you can easily choose which files to stage. More likely, there may be unrelated changes to the same files that you wish to break apart. In that case, you can interactively choose which hunks to add by using the -p or --patch parameter. You may need to "split" hunks to get the right change set. If independent changes do not modify similar sections of code, this should be enough. If independent changes modify the same line, you may need to temporarily edit those lines in your source code editor.

  1. git stash --keep-index

Test your changes. You probably want to verify the change set you've staged, to make sure code still builds properly, and any unit tests pass. To do this, you'll want to temporarily stash the changes you aren't adding to the current commit. The already staged changes should stay so they can now be built and tested.

  1. git commit

Create the new commit.

  1. git stash pop

Unstash the remaining changes and continue splitting from step 2.


As you've already pushed, the history of your new work will be different once you complete the above steps. That means you can't simply push it to the same branch, as Git will reject the changes. You may want to instead push the updates as a new branch. Alternatively, and you need to think long and hard before doing so, you can force push the branch to overwrite the history in the remote repository, but only do that when it doesn't bother other people working in the same repository, who may have built off the old history. Force pushing is often considered a bad practice, so carefully consider when to actually use it. More standard practice would be to push a new branch, open a new pull request, and close any old pull request.

Daniel Stevens
  • 750
  • 1
  • 9
  • 17