tail -f findings.out

« Chained No More, or, How I got WoW running perfectly in linux

Beginner Python Debugging »

An awesome xargs option and cleaning up SVN accidents

I started using a wonderfully helpful option for xargs recently, after Master Ian showed me its use in a particularly thorny case. Before seeing the cool option, I will give the case as an example of its use:

I am still learning about the best (or even proper) way to use some aspects of SVN. In this particular case, I need to take all the files in a directory that was in the repo, move them into a new directory in the same directory, add another new directory, and copy new files into that.

To better explain the example, here is the structure I had in place, initially:

  • Directory 1 (In SVN)
    • FilesetA

And this is what I wanted in the end:

  • Directory 1
    • Directory1.1
      • FilesetA
    • Directory1.2
      • FilesetB

What I should have done is: made the 2 new directories (1.1 and 1.2) within the first one, copied the new files into one (FilesetB), add and commit both new directories and their contents. Then I should have run

1
svn mv

on the files in the top directory (FilesetA) into the second new directory.

What I actually did was: created the two new directories, simply

1
mv

‘ed FilesetA into one, copied in FilesetB into the other, and then

1
svn add

‘ed the two new directories and their contents. Then I had a problem. I still had FilesetA in Directory 1 in the repo, but not locally. So I needed to svn rm those, but I could not since they did not exist locally any more!

In the end, I copied the FilesetA out into a temp directory, when up to the directory above my repository, check the entire thing out again,

1
svn rm

‘ed the FilesetA in Directory 1, and then needed to add FilesetA back into Directory 1.1. This was why I moved it to a temp directory. The problem was that that set had several nested directories with

1
.svn

directories in them. I had to remove these before adding them into the SVN’ed directories, else mass confusion would result. So I ran:

find . -type d | xargs -I % rm -rf %/.svn

This gem found all directories from the current directory down, and passed them to rm -rf. However, I could not just pipe the results and use xargs, as I needed to append “/.svn” to specify the right directories to remove. This is where -I comes in handy. This option replaces all instances of the string following it with the results of the first command (before the pipe). In this case the string was “%”, for similarity to Python syntax, but any string could be used. The man page uses “replace-str”. So in this particular case, if FilesetA included Directory 1.1.1 and 1.1.2, the command would resolve to: “rm -rf Directory1.1.1/.svn Directory1.1.2/.svn”, which is precisely what was needed!

For some reason, I had a hard time understanding the option from the man page, but Ian translated it to Python for me:

for dir in [find . -type d]:  cmd = "rm -rf %s/.svn" % dir  os.popen(cmd)

This was much clearer to me. What it basically comes down to is:

OPERATION1 | xargs -I replaceme ANOTHEROPERATION replaceme OTHERTHINGS

translates into

ANOTHEROPERATION OPERATIO1RESULTS OTHERTHINGS

.

Share and Enjoy:
  • E-mail this story to a friend!
  • LinkedIn
  • Slashdot
  • StumbleUpon
  • Technorati
  • Netvibes

[Post to Twitter]  [Post to Delicious]  [Post to Digg]  [Post to Reddit] 

Possibly Related (no promises):

  1. Elegant option checking with optparse
  2. Recursively ignoring multiple file patterns in subversion
  3. Useful ways to list directory contents
  4. Handy Alias: Grab latest svn log
  5. Useful grep incantations

Related posts brought to you by Yet Another Related Posts Plugin.

Tags: , ,
August 1, 2007 - 9:31 AM
Leave a reply

Subscribe without commenting