The interactive rebase capabilities of Sourcetree are great, but I often find myself wanting to be able to "split" a commit into multiple smaller commits. I know theres a way to do this from the command line, but I can't seem to find any place in the UI to handle this.
Is there a way to do this with Sourcetree? Or is this one of those places where I have to drop down to the command line to accomplish my goals?
When you push a commit, the safest way to revert it (rather than forcing the push with -f) is to use the revert function, so a new commit is created on top of your previous commit. This is possible to do using Sourcetree, right clicking in the commit that you want to revert, and selecting "Reverse commit...".
In the new window, select the commit you want gone, and press the "Delete"-button at the bottom, or right click the commit and click "Delete commit". Click "OK" (or "Cancel" if you want to abort).
Squashing lets you combine tiny-yet-related commits into a single, meaningful commit. To use the squashing feature in Sourcetree, drag and drop rows on top of one another. Or, you can use the squash with previous option by right-clicking or using the button at the bottom of the dialog.
Splitting the commits from the command line using interactive rebase is explained in git help rebase
(search for "SPLITTING COMMITS"). It is not a git command or option; it is more a way of commits editing. You can do the steps described there using SourceTree for Mac. From your question I understand you did interactive rebases using SourceTree before and are familiar with its UI.
Update:
It seems that my original answer (see above) is too cryptic. There is no special git
command for splitting commits, and consequently SourceTree
does not provide a command or an option in the interface to do that. You have to read and follow the steps explained in the documentation using the GUI instead of the command line.
These are the steps (quoted from the documentation) and how to follow them using Atlassian SourceTree
:
- Start an interactive rebase with
git rebase -i <commit>^
, where<commit>
is the commit you want to split. In fact, any commit range will do, as long as it contains that commit.
Right-click on the parent commit of the commit you want to edit. Select "Rebase children of <hash>
interactively ..." from the contextual menu that appears (<hash>
is the abbreviation of the clicked commit's hash).
- Mark the commit you want to split with the action "edit".
SourceTree
opens the "Interactive Rebase" dialog box. Identify in the list the commit you want to split (it's the last one) and check its checkbox in the column "Amend Commit?". Press the "OK" button to continue.
- When it comes to editing that commit, execute
git reset HEAD^
. The effect is that theHEAD
is rewound by one, and the index follows suit. However, the working tree stays the same.
SourceTree
runs in the background the needed Git
command(s) and stops when it comes to edit the commit you marked for amending. Right click the parent of the current HEAD
and select "Reset (no branch, rebasing <branch>
) to this commit" from the contextual menu that appears (<branch>
is the name of the branch you had checked out when you started the process). It will ask what mode to use for reset; select "Mixed - keep working copy but reset index" in the "Using mode" list and press "OK".
- Now add the changes to the index that you want to have in the first commit. You can use
git add
(possibly interactively) orgit gui
(or both) to do that.
It's split time! Add to the index the files and the hunks you want to put into the first commit; you can even do changes that were not present in the original commit if you need. However, be aware that changes that were not in the commit you are editing may conflict with changes introduced by the later commits.
- Commit the now-current index with whatever commit message is appropriate now.
Use SourceTree
as usual and commit the staged changes.
- Repeat the last two steps until your working tree is clean.
(no comments)
- Continue the rebase with
git rebase --continue
.
Pick the "Continue Rebase" from the "Actions" menu.
Congratulations! You just split a commit using the hidden "split commit" command provided by SourceTree
:p
If something goes wrong or you make up your mind or for whatever reason you need to cancel the entire process then use the "Abort Rebase" from the "Actions" menu. In the background SourceTree
will invoke git rebase --abort
and everything well return to the state it was before you started.
If you need to split/edit more than one commit on the same branch you can use the oldest commit on step 1 and mark for amending all the commits you need on step 2. Everything else is the same, SourceTree
will repeat the steps 3-7 for each commit you marked for amending.
This is how you can split a commit using Atlassian SourceTree
.
Any other Git
client with GUI that provides a way to do interactive rebase can be used instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With