views:

947

answers:

7

Is it possible to checkout only those files from a SVN repository that were modified in a revision or range of revisions, without checking out any files that were not modified?

A: 

I'm not completly sure if this is possible but you can also do something like this:

svn checkout --revision <revisionNumber>

to get a certain revision and

svn log --revision <revisionNumber>

to list all files chaned in a revision

Drejc
This will always refer to all files of the given revision (ie. for files not changed in the given version, he will give you the last version of it)
flolo
Ups svn log was what I had in mind
Drejc
+1  A: 

If you use svn log with the -v (verbose option):

svn log -r <revision> -v <path>

You will get an output that includes the changed files:

 r3 | ciaran | 2008-11-16 12:24:30 +0000 (Sun, 16 Nov 2008) | 1 line
Changed paths:
   A /trunk/apache/apache.conf
   A /trunk/application/controllers

Commit message goes here

You should be able to manipulate that with some grepping etc. to produce a sequence of svn co commands.

Ciaran McNulty
+2  A: 

There is afaik now direct way to get just the changed files and not all.

My idea would be: use the verbose output of the list (which shows the last changed version), filter it through awk, and checkout the rest. E.g. to search the files which changed in version 42 I would use this

VERSION=42
svn list -v -R -r $VERSION svn://... |  awk "/^[ ]*$VERSION/ {print \$7}" > files_to_checkout

And later do a svn update -r $VERSION 'cat files_to_checkout'(or a co on the url, depending on where you will run the command).

EDIT: Additional even shorter: use the svn diff command, and replace with -x and --diff-cmd the diff command with svn co. This requires some argument shifting hacking (which I wont elaborate here), but needs just one line and no intermedate file (which you could save above too, but that would have cost readability)

flolo
+1  A: 

My suggestion is in the same lines as flolo suggests. But, takes a range. You could the following shell function.

function checkout_files_in_revrange()
{
  svn_url=$1;
  start_rev=$2;
  end_rev=$3;
  for theCheckoutCanditate in `svn log -r $start_rev:$end_rev --verbose --incremental | grep "   M " | cut -f5 -d' ' | cut -f3- -d/`
  do
     svn co $svn_url/$theCheckoutCandidate -q;
  done
}
Shyam
+1  A: 

We do this in an MSBuild script:

Step 1: - Use the diff command to get the list of modified files, redirect output into a temporary file in the target directory Step 2: - Read the temporary file into an itemGroup

<Exec command="$(svnExecutable) diff -r $(StartRevision):$(EndRevision) $(DOUBLE_QUOTES)$(SvnRepositoryPath)/$(DOUBLE_QUOTES) --no-diff-deleted --summarize &gt; $(TempFilePath)" WorkingDirectory="$(WorkDirectory)" />

Sorry code paste did not work as planned - if anyone want's a look add a comment here
A: 

Another take at answering your question:

Assuming you have an existing workingcopy you should just use 'svn update' on the root of the directory containing the files you are looking at as that retrieves exactly what changed between your current revision and the HEAD revision with the least data possible.

Older sourcecode management systems like CVS and VSS asked the server for every file has this file changed?, while subversion just sends the changes of a tree as a single action. When you pass a list of files to svn update you don't have this advantage.

Therefore the most efficient way to transfer what has changed is just updating. This only transfers a binary diff of the changes in HEAD compared to the base version of your working copy.


If the problem you are trying to solve is that svn update is to slow, then we are trying to solve that for Subversion 1.7.

This version will introduce a new working copy data storage format that will make simple operations that have to lock an entire working copy (like updating) much faster.

Bert Huijben
A: 

In almost the same lines as most of the folks have suggested, (however only in a system with grep and awk), you can get the list by executing

svn log -v --revision <revision_number> | grep "^ " | awk '{print $2}'.

Shyam