Shelving Changes

Suppose you have some, perhaps unfinished or untested, changes, but you are due to work on another problem. Sometimes it would be helpful to commit those changes, but the changes might not be appropriate for the trunk yet.

You can instead commit them to a branch.

(As usual, anything committed should still be in a reasonable state. As a minimum, it the sources should compile. Ideally, the generated executable should be stable, even if not functionally complete.)

Suppose that you have a working copy

C:\wc\project

of the URL

http://repository/project/trunk/

at revision 1234.

You wish to record your work at

http://repository/project/branches/yourname/r1234_plus_feature/

Two Methods

There are at least two ways to go about this. With either method:

Create any necessary hierarchy. For example, if there is not yet an area

http://repository/project/branches/yourname/

you could create one

svn mkdir http://repository/project/branches/yourname/
    -m "YourName's area for project change 'parking' etc."

Update your working copy to an appropriate revision (not necessarily the HEAD).

Also, sort out the changes, undoing or reverting anything you really don’t want to keep.

Method 1: direct working copy to branch commit

  • Advantage: fewer steps to do in the first place
  • Disadvantage: risk of forgetting to update and getting an over-complicated copy structure
  • Disadvantage: later viewing of the changes can be more awkward than with method 2
  • Disadvantage: later merging of the changes can be more awkward than with method 2

Beware! Before doing this it is better if your working copy is a pure revision (although it need not be the HEAD revision).

Sometimes, having a complex revision structure will be deliberate. However, usually, such a structure is just the result of forgetting to update the working copy uniformly to the same revison.

With a simple revision structure in the working copy, you should see a copy log entry like this:

------------------------------------------------------------------------
r1250 | yourname | 2008-12-19 16:32:22 +0000 (Fri, 19 Dec 2008) | 1 line
Changed paths:
   A /branches/r1234_plus_feature (from /trunk/project:1234)
   M /branches/r1234_plus_feature/dir/file4.txt
   M /branches/r1234_plus_feature/file1.txt

svn cp from wc with simple revision structure to repos URL
------------------------------------------------------------------------

With a complex one, it’s likely to look more like this:

------------------------------------------------------------------------
r1250 | yourname | 2008-12-19 16:29:24 +0000 (Fri, 19 Dec 2008) | 1 line
Changed paths:
   A /branches/r1234_plus_feature (from /trunk/project:1234)
   R /branches/r1234_plus_feature/dir (from /trunk/project/dir:1200)
   R /branches/r1234_plus_feature/dir/file3.txt (from /trunk/project/dir/file3.txt:1066)
   M /branches/r1234_plus_feature/dir/file4.txt
   R /branches/r1234_plus_feature/file1.txt (from /trunk/project/file1.txt:1199)
   R /branches/r1234_plus_feature/file2.txt (from /trunk/project/file2.txt:1212)

svn cp from wc with complex revision structure to repos URL
------------------------------------------------------------------------

The real changes are difficult to see amongst the accidental ones. Some real changes might even be hidden (as with file1.txt in the example).

Anyway, here’s how you do it:

C:
cd C:\wc\project\

svn update -r1234

svn copy . http://repository/project/branches/yourname/r1234_plus_feature/
    -m"parked unfinished work on feature"

That is:

  • in a DOS box, change to your working copy
  • update to a suitable revision (often, but not always the HEAD)
  • copy directly from your current local path (.) to a new branch in the repository

Note that the copy subcommand is essentially a commit when the target is a URL, as it is here. (In this case the source is a path.)

Method 2: staged commit (preferred)

(Advantages and disadvantages are obviously the converses of those of method 1.)

C:
cd C:\wc\project\

svn copy -r1234 http://repository/project/trunk/
    http://repository/project/branches/yourname/r1234_plus_feature/
    -m"(copy of trunk)"

svn switch http://repository/project/branches/yourname/r1234_plus_feature/

svn commit -m"parked unfinished work on feature"

svn switch -r1234 http://cvs01/svn/repository/project/trunk/

rem perhaps: svn revert ...

That is:

  • in a DOS box, change to your working copy
  • create a new branch that is a copy of the trunk
  • switch your working copy to the new branch
  • commit your changes to that branch
  • switch your working copy back to (an appropriate revision of) the trunk
  • perhaps revert the local changes, as these are now safely recorded in the repository

Again, note that the copy subcommand is essentially a commit when the target is a URL, as it is here. (In this case the source is also a URL.)

Also note that the switch subcommand behaves something like an update.

Variation on either method

Use a second working copy, and copy across (e.g. using WinMerge or Beyond Compare) the directories and/or files and/or individual lines of files that you wish to commit, and commit them from that second working copy.

(See my post on dual engineering.)

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: