0

I am writing a shell script which can store the actual state of a SVN working copy and restore it later, exactly as it was. Currently I have a problem with specific, rare combination of revisions of files and directories which seems to be undetectable.

Let's say that there is a repository with two revisions. There are two cases:

  1. Assume that foo is a file (or a directory) that exists only in revision 2. At the beginning the whole working copy is at revision 2. Then foo (and only foo) is updated to revision 1.

  2. Assume that bar is a file (or a directory) that exists only in revision 1. At the beginning the whole working copy is at revision 1. Then bar (and only bar) is updated to revision 2.

The both cases are very similar but it seems that they have different solutions. In both cases the file (or directory) simply vanishes. However, output of command svn status contains no information about that.

How to create by a shell script a list of such files and directories?


There is one simple but bad solution. It is possible to use command svn list to get a list of files that should exist in current revision and compare it to the list of files that really exist.

This solution is unacceptable because it takes a lot of time and generates a big traffic to the server.


I posted the best answer that I can come up with. Still, it works only for the first case and has false-positives.

Piotr Siupa
  • 3,929
  • 2
  • 29
  • 65
  • You mean something like `cp -a`? – Etan Reisner Nov 11 '15 at 14:01
  • @EtanReisner This solution is not suitable for my projects. Most of them have hundreds of megabytes. It's to much to copy. Most often only a few small files is changed. That's why I am writing script to copy only changed files. – Piotr Siupa Nov 11 '15 at 14:13

2 Answers2

2

I once attempted to do the same thing that you're doing, and I hit so many corner cases that I eventually went a completely different direction. Instead of using a script, I used a local git repository.

Check out a working copy from the Subversion repository, then create a local git repository in that folder using git init. Add the entire contents of your Subversion working copy to the git repository - including the .svn metadata directories - using git add followed by a git commit. Git is now keeping track of your working copy plus all of the Subversion metadata associated with it. My current git repository has 5 different branches, each based off of a different Subversion revision and containing different sets of changes that haven't been committed to the Subversion repository yet. The git repository makes it easy to switch back and forth between them, and Subversion works as if they were all separate working copies. Even for large working copies, git does a good job at storing contents efficiently and switching between branches quickly.

Note that this is different than the git svn command, which is git's method of directly interfacing with a Subversion repository. I found git svn to be more complicated to use and easier to break things. Wrapping a normal Subversion working copy in a git repository allowed me to still do all of my repository operations using Subversion, and only required me to learn a few basic git commands (add, commit, branch, checkout, etc). It's a bit easier for someone who is experienced with Subversion and new to git; git svn is more geared towards someone who is experienced with git and stuck with a Subversion repository.

bta
  • 43,959
  • 6
  • 69
  • 99
  • This probably won't be compatible with my other scripts for SVN. I don't have too much time today. I'll check it tomorrow. – Piotr Siupa Nov 11 '15 at 21:28
  • @NO_NAME- My original reason for going this route was precisely so that my existing Subversion scripts still worked. From Subversion's standpoint, everything works the same as it did before. The only real change in my workflow was that changing from one working copy state to another involved a git command instead of calling a complicated script. – bta Nov 11 '15 at 22:03
  • This is causing that they are both '.svn' and '.git' directory in working copy root. It may be misinterpreted by an IDE. (I tested this in Eclipse and this works fine but it is probably an accident.) This also double size of the working copy. (Still better than `cp -a`.) After all, it is still a good option, especially after I wrap it in a script. – Piotr Siupa Nov 12 '15 at 21:50
  • To date, I haven't had any IDEs or tools complain about the folder being both in git and in Subversion. You might see both sets of options in a right-click menu, but you should be able to tell which one is which (I know RabbitVCS will put the git and svn commands in separate groups). It may help if you add the ".git" folder to Subversion's ignore list. – bta Nov 13 '15 at 20:34
  • "You might see both sets of options in a right-click menu" This is not always truth. For example, Eclipse shows only set of options for SVN. It just classifies project as SVN-type and doesn't check further. Fortunately, it checks the SVN firstly, but it probably may change randomly. – Piotr Siupa Nov 13 '15 at 21:47
  • I think you should copy your answer to this question: http://stackoverflow.com/questions/1554278/temporarily-put-away-uncommited-changes-in-subversion-a-la-git-stash – Piotr Siupa Nov 15 '15 at 00:25
0

I found partially solution for the first case.

svn status -u | grep '^........\*........ ' | cut -c 22-

This code shows all files that exist in head revision and do not exists in current one. This finds files and directories from first case. However, it generates false-positives, when a file is removed when the parent directory (which still exists) is updated to lower revision.

Piotr Siupa
  • 3,929
  • 2
  • 29
  • 65