How can only the files that were modified in a range of SVN revisions be checked out?

依然范特西╮ 提交于 2019-11-30 16:44:07

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
}

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)

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.

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)" />

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

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}'.

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.

svn diff -r starting_revision:ending_revision_or_HEAD --summarize

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!