10

Dealing with a subversion repo and a new user that didn't quite understand how it worked.

Long story short, since their local structure was messed up due to copying random .svn folders about, I did the following:

  • copied the local structure to a folder called staging
  • recursively deleted all .svn folders from the staging directory
  • checked out the repo to a "clean folder"

Now we're at the last step — getting the staging folder contents to overwrite the clean contents.

I need to have a command copy the contents of the staging directory to the clean directory, removing everything that is only in the clean directory, BUT leaving the clean folder's .svn folders in tact.

This sounds like a job for rsync. Would the following command be correct?

rsync -avr --exclude=.svn* [staging] [clean]
Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
SeanKilleen
  • 355
  • 1
  • 4
  • 12

2 Answers2

32

The -C option for rsync may be what you want.

Don't let the short description in the man page fool you though. It would seem like the option only applies to CVS, but depending on your rsync version it will skip the files of almost every common version control system in existence.

# rsync version: 3.0.7

-C, --cvs-exclude           auto-ignore files in the same way CVS does

...

          The exclude list is initialized to exclude the  following  items
          (these  initial  items are marked as perishable — see the FILTER
          RULES section):

                 RCS  SCCS  CVS  CVS.adm   RCSLOG   cvslog.*   tags   TAGS
                 .make.state  .nse_depinfo *~ #* .#* ,* _$* *$ *.old *.bak
                 *.BAK *.orig *.rej .del-* *.a *.olb *.o *.obj *.so  *.exe
                 *.Z *.elc *.ln core .svn/ .git/ .bzr/

          then,  files  listed in a $HOME/.cvsignore are added to the list
          and any files listed in the CVSIGNORE environment variable  (all
          cvsignore names are delimited by whitespace).
Zoredache
  • 3,580
  • 7
  • 29
  • 37
  • 2
    Be very careful, because these extensions may be used for files that you do want copied, eg. `*.a` is for iOS Static Libraries. – Max Chuquimia Jul 01 '14 at 00:57
  • N.B. files and directories are excluded: any folder called "core" is not copied e.g. /myproj/api/ /myproj/core/ <- not backed up! – teknopaul Aug 10 '16 at 10:35
8

Almost — this should be

rsync -av --exclude='.svn*' [staging] [clean]

or any other form of quoting that prevents the shell from expanding the wildcard. (The wildcard would only match an unlikely file whose name begins with --exclude=.svn, but it's better not to take the risk, and also to work correctly even if the shell is configured to choke on non-matching wildcards or to expand them to the empty list.)

-r is already included in -a. The extra r is just superfluous, it won't do any harm.

--exclude causes files matching its argument to be neither copied, nor considered for recursive traversal. The usual difficulty with rsync is going the other way, excluding a directory except for certain parts of it. See Rsync filter: copying one pattern only for some tips.

In this particular case, excluding version control directories is a quick way of getting what you want.

Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175