Temporarily put away uncommitted changes in Subversion (a la "git-stash")

Viewed 94936

While programming software stored in a Subversion repo, I often modify some files, then notice that I'd like to do some preparatory change for my main work. E.g. while implementing new functionality, I notice some refactoring which might help me.

In order not to mix two unrelated changes, in these cases I'd like to "stow away" my changes, i.e. revert to the repository version, do some other changes, commit these, then "fetch back" my changes.

git-stash allows to do just that. Is there some way to do this with Subversion, either directly or with some plugin or script. Eclipse plugins would also be fine.

17 Answers

Use:

svn cp --parents . ^/trash-stash/my-stash

It will create a branch from the current location and current revision, and then it will commit the changes in working copy to that branch without switching to it.

usage: copy SRC[@REV]... DST

SRC and DST can each be either a working copy (WC) path or URL:

WC  -> URL:  immediately commit a copy of WC to URL

Note that changes in working copy won't be automatically reverted (cp is just CoPying changes to a new branch) and you have to revert them manually.

To restore the changes, you can just merge the changes from newly created branch to your working copy.

svn merge --ignore-ancestry ^/trash-stash/my-stash -c <commited revision>

--ignore-ancestry is used in order not to update merge info in working copy.

Use:

svn ls -v ^/trash-stash/

to see what you have at stash path. Committed revisions are also printed.

If you don't need the stash anymore, just run:

svn rm ^/trash-stash/my-stash

This solution is better than using patch in that if new changes in working copy or on the current branch conflict with the changes in the stash, you can resolve the conflicts using svn means, whereas patch in some cases will just fail or even apply patch incorrectly.

I would like to make a summary for all the solutions mentioned above, since it's such a mess under this question. Some high voted answers are ambiguous and I spent quite a lot time proving whether some part of the answer is true or not.

Solutions:

  1. Checking out a new working copy and work in the new copy. (The easiest and safest one)
  2. Create a branch -> switch to new branch -> blablabla (Some say it will produce some trash in the SVN server)
  3. Create a patch -> revert working copy -> patch back (Works great if you don't have any unadded files or deleted files)
  4. Use shelve (See below)

I tried 1. 2. and 3..

1. is the easiest and safest one. If you want to save time, use this solution. Not elegant I know.

3. is not my choice because:

  • you can create a patch with unadded files and changes of existing files. But it doesn't delete those unadded files after creating a patch. So what to do? I have to creat a patch(select unadded files) -> revert working copy -> manually delete all those unadded files. This doesn't work like git stash -u at all.

4. shelve would be the most elegant way and the most similar one to git stash -u.

add unadded/untracked files -> shelve -> done.

See? Compared to git stash -u, the only difference is that you have to add the unadded file first then shelve.

Test Environment:

I am testing all those using Windows Tortoise SVN client with a network sharing copy (SAMBA) and local repos created by Windows Tortoise SVN client.

So I don't know how things could be different if you are using a SVN server, which is different from a local share. But I guess shelve would work in any siutaions since it's a local operation/feature.

Since Subversion doesn't support stash feature perfectly,
I just do manual way like this.

Place Development and Production(release) project to a separated path.

source\code\MyApp         -- Development
release\MyApp(release)    -- Production(release)

You can work any new features for your project in the development path,
and you would only commit meaningful progress or something should be released for the stable.

When you have to release it for production, open production project, update svn and do stuff to release(build, export... etc).

I know this makes little bit troublesome, but releasing progress doesn't happen often(it doesn't for me, but I know some projects do) compare to develop progress, this way fits for me.

I'm using svn for specific projects since the project team members use it, so I have to follow.
The best solution is to use git which has a perfect version control system and better than svn.

Related