Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I split a past un-pushed commit with Sourcetree?

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?

like image 992
cdeszaq Avatar asked Mar 14 '14 16:03

cdeszaq


People also ask

How do you undo a pushed commit in Sourcetree?

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...".

How do you remove commit that is not pushed Sourcetree?

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).

How do you squash two commits in Sourcetree?

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.


1 Answers

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:

  1. 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).

  1. 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.

  1. 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.

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".

  1. 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.

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.

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

Use SourceTree as usual and commit the staged changes.

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

(no comments)

  1. 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

Remarks

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.

like image 85
axiac Avatar answered Sep 29 '22 01:09

axiac