Partial commits with TortoiseSVN


When working on code changes sometimes you end up with spotting a bug alongside the code which you are working on atm.

But how would you handle this? You want to quickly commit the fix, but you have a lot of other changes inside the same file. Creating a patch, making a backup of the file, or using a new checkout of the project are certainly ways to deal with it, but all take a certain amount of overhead and can be error prone.

Here, TortoiseSVN does provide a very handy (but unfortunately also a bit hidden) feature called the Restore-After-Commit functionality which has been around since TortoiseSVN 1.8 already [1].

Working with Restore-After-Commit

The handling on how this feature works is best explained through a simple example.
(Sidenote: WinMerge 2011 is used in the screenshots below to display the local changes.)

Let’s assume we have a single file called test.cpp with a lot of local changes:

The left side shows the content of test.cpp in the repository (at revision 3), the right side shows what we changed inside the file in our working directory.

Let’s assume we found a bug in the function foo() which we want to quickly fix without committing the rest of the changes inside that file. For that, we first bring up the TortoiseSVN commit dialog:

Next we right click the test.cpp file in the ‘Changes made’ list and select “Restore after commit”:

The test.cpp file will show a new overlay icon, depicting that it’s marked for ‘restore after commit’:

Next, we revert the changes we do not want to commit in that file. Just double clicking the file in the list here and using our diff tool, we revert everything except the one line change in the foo() function:

Afterwards, we commit the file as usual by clicking on OK on the commit dialog:

Bringing up the diff for the file after the successful commit shows that our previous changes were restored, while the fix in foo() was committed in revision 4:

Committing multiple files

Since you can tag each file individually to be restored after a commit, you can also do partial commits of multiple files in one go and even combine it with non-partial file commits.
The following screenshot shows how this might look. In here we have partial file changes in the files test2.cpp and test3.cpp and also commit all changes in test.cpp while the changes in test4.cpp are not part of the commit:

For small changes, this functionality is quite handy and can save you a lot of time where you would otherwise work with reverting and reapplying changes which can be quite time consuming and error prone.

Shelving as another option

It should be mentioned here that as of (Tortoise)SVN 1.10.0, Subversion introduced the experimental shelving functionality. This too is a very handy feature which allows you to put entire changes “on a shelf” to work on another thing in-between. However, for simple changes like the one shown in the example above, the ‘revert after commit’ functionality is still faster to apply and still has its purpose even with the new shelving feature (which is out of scope to be covered in this blog post).

Caveats with the Restore-After-Commit feature

Most of the issues with the feature have been fixed during the 1.8.x timeline [2].
If you are still working for some reason with that old version and are not able to upgrade to TSVN 1.9+ you are strongly suggested to use TSVN 1.8.12, since earlier versions had some bugs with this feature.

On the TSVN 1.9.x timeline the feature unfortunately suffered a display issue resulting in the missing overlay icon for files to be restored after commit. This made it kind of tedious to work with the functionality, as you didn’t see which files were about to be restored, if you didn’t do the partial commit immediately. This issue was finally fixed in TSVN 1.10.0. [3] Unfortunately the fix wasn’t shipped for the 1.9.x versions, since 1.9.8 (which would have included the fix) was never released.

An issue with the functionality however still remains as of today (TSVN 1.14.0 at the time of writing this). When you tag a file to be restored after commit, then try to commit the changes but TortoiseSVN needs to update said file in the process of the commit first (as other changes were applied meanwhile to the file), the file will be restored to its original state after the commit and you will have lost the incoming changes to the file.
Obviously there’s no perfect simple solution for cases like these and you need to manually adjust the file and re-apply the changes. It can get even more messy if the incoming file updates caused conflicts and couldn’t be cleanly applied.
Good practice is therefore to do an update of the file(s)/working copy before you try to do a partial commit, unless you are certain that the commit won’t require a file update first.