352 Inc. / Digital Marketing / March 21st, 2008

SVN update clean?

We recently moved our development from CVSNT to SVN, which has been working out great. The two are very similar, what was once done in CVS, can for the most part be done in SVN. For example an update in CVS and SVN are accomplished with:

cvs update
svn update

One useful flag for cvs update was –C, for a clean update. In a clean update the working copy is updated to match the current version. In SVN, an analogous flag is not available (or at least I cannot find it). There is a revert command available which will bring all of the versioned files to the previous revision, effectively an update clean, with exceptions. The extra files remain (new files), and any new changes on the server are not considered. The revert command simply rolls the versioned files back to what they were at the last update or checkout. In order to recreate the clean update in SVN, I decided to run revert, a manual cleanup and then an update. The first and last are trivial, but manually cleaning the new files out at the command line took some work and the solution is presented here.

Creating an update clean equivalent

SVN provides a status command which lists the files and their status within a working copy.

svn st –no-ignore

Now in order to find only the new files (indicated by ‘?’), the output is filtered with AWK. To do this the output from SVN is piped (redirected) to AWK. The parameters for AWK tell it to split the lines on ‘?’, remove some whitespace, then print the filename (second parameter) for all lines with ‘?’.

svn st –no-ignore | awk -F? “/?/ {gsub(/ /,””””””,$2);print $2}”

With the list of extra files in the pipe we simply need to delete them. Unfortunately ‘delete’ does not accept redirected output like ‘rm’ from UNIX, so I just quickly knocked one out. The source for rmp, written in c# is also included.

svn st –no-ignore | awk -F? “/?/ {gsub(/ /,””””””,$2);print $2}” | rmp

using System;

using System.Collections.Generic;

using System.Text;

using System.IO;

namespace rmparam

{

classProgram

{

staticvoid Main(string[] args)

{

string path = “”;

if (args.Length == 1)

path = args[0];

Console.WriteLine(path);

string currentLine = Console.In.ReadLine();

while (currentLine != null)

{

Console.Out.WriteLine(path + currentLine);

if (String.IsNullOrEmpty(currentLine) == false)

File.Delete(path + currentLine);

currentLine = Console.In.ReadLine();

}

}

}

}

In order to resolve some path issues on the delete an optional parameter is available to set a base path to delete from.

svn st –no-ignore | awk -F? “/?/ {gsub(/ /,””””””,$2);print $2}” | rmparam “C:PathToWorkingCopy”

The complete command set, which could easily be placed in a bat.

svn revert –R

svn st –no-ignore | awk -F? “/?/ {gsub(/ /,””””””,$2);print $2}” | rmparam “C:PathToWorkingCopy”

svn update

I’m not happy with the dependence on the binary and fixed whitespace length, but it does work. Enjoy!