2

I accidentally added dozens of backup files to SVN and would like to recursively revert all files matching a given pattern (*.~sql)

On UNIX, I'd simply use a

svn revert `svn status .|grep "~sql$"|awk '{print $2}'`

which is a variation of one of the answers to How do I 'svn add' all unversioned files to SVN?

Using Powershell, I came up with

svn status|findstr "~sql" | %{ $_.Split('`t')[1]; }

but this seems to cut of the first characters of the filenames (e.g. I get ch_sys.~sql instead of scratch_sys.~sql).

What am I missing here? Or is there a more Powershellish way of doing this?

Community
  • 1
  • 1
Frank Schmitt
  • 30,195
  • 12
  • 73
  • 107
  • 1
    Powershell way of doing something is called POSH and not Powershellish :) – manojlds May 22 '12 at 09:27
  • 1
    manojlds, that sounds kinda stupid, though ;-) (at least I could never get used to calling PowerShell PoSh – besides, »posh« doesn't really sound that powerful :-P) – Joey May 22 '12 at 09:29

2 Answers2

6

You would need to use

$_.Split("`t")

as a quick fix for your code because currently you have a string containing `t instead of a string containing a tab because single-quoted strings don't allow escape sequences (except ""). string.Split gets a char[] as argument and splits at any of the characters you passed, so in this case it splits on a grave accent and t.

But you are right, that's not really a PowerShell-y way of doing this. First of all, you're using findstr which has plenty of PowerShell equivalents, e.g.

svn status | where { $_ -match '~sql' }
(svn status) -match '~sql'

When working with SVN from PowerShell you have another option, though. Most SVN commands can output XML which is a lot more robust to handle than text output, usually.

([xml](svn status --xml)).status.target.entry |
  select -exp path |
  where {$_ -match '~sql'} |
  foreach { svn revert $_ }

Whether that's prettier is probably debatable, but I prefer working with structured data when possible.

However,

svn revert -R *~sql*

should work, too, I guess.

Frank Schmitt
  • 30,195
  • 12
  • 73
  • 107
Joey
  • 344,408
  • 85
  • 689
  • 683
  • Thanks for pointing out the " vs ' problem - I wasn't aware of that. When I try your last solution (svn status --xml) ..., I get an error svn: E205001: Try 'svn help' for more info svn: E205001: Not enough arguments provided – Frank Schmitt May 22 '12 at 09:41
  • That's weird. But the code wasn't correct so far anyway. Still, the `revert` call *should* work. – Joey May 22 '12 at 09:44
  • (svn status --xml).status apparently doesn't return anything; I'm using Powershell V1, might this be the cause for the problem? – Frank Schmitt May 22 '12 at 09:49
  • Argh, I forgot the cast. The supposedly nicer snippet is getting increasingly uglier. – Joey May 22 '12 at 09:57
  • Awesome, thanks a lot. FYI, the svn revert -R *~sql* doesn't work, since it's not reverting recursively (even if quoting the *~sql* to prevent the shell from expanding the wildcards). – Frank Schmitt May 22 '12 at 10:33
  • The shell won't expand wildcards on Windows, but it could be that SVN is replicating the Unix behaviour by only expanding wildcards with respect to the current directory. – Joey May 22 '12 at 10:37
0

If you use Select-String, alias sls you can also use regex for matching.

([xml](svn status --xml)).status.target.entry.path | sls ".+sql" | %{svn revert $_}

(n.b. $_ is a matchinfo that gets converted into a string)

8DH
  • 2,022
  • 23
  • 36