tags:

views:

1497

answers:

5

In the current project I am working in, someone decided that binary files be checked in as part of the source tree. The binaries live in a directory beneath the sources themselves:

project/src             # Here is the location of the source code
project/src/more_src    # Some more source code lives here
project/src/bin         # Here are the binary files

As you can imagine, merge conflicts happen all the time because of this. It's quite annoying since I do not feel that any developer's machine should be committing the binaries - this should be left to the build server.

I am a command-line user of subversion. I would like to ignore the bin directory so that when I use svn st and svn ci these directories are skipped (even if there are pending changes).

Unfortunately, I cannot use -N (non-recursive) because of the more_src directory.

How can I accomplish this?

+2  A: 

I would create a script or alias to work with the sub-directories directly via one command.

I have a similar scenario, and have a set of aliases like this:

alias up-all='svn up ~/includes ~/scripts ~/htdocs/intra ~/htdocs/update'

If you're on Windows, you could cobble together some .bat or other scripts and put them in your path to achieve the same results.

Trevor Bramble
+7  A: 

edit: subversion 1.6 has been released. From the release notes:

In Subversion 1.6, the --set-depth parameter to svn update has grown a new value—exclude. This value tells Subversion to exclude the target from the working copy, immediately and until further notice. Prior to Subversion 1.6, if a directory could not easily be removed from a working copy. ...

All the stuff below is obsolete now.


You could limit the depth of the folders in your working copy in the right places so that the undesired files don't appear as versioned files. You can't reduce the depth in an existing working copy though.

1) Checkout a clean working copy like this (it will contain only files and empty folders in the root):

svn co --depth immediates repoURL /some/wc/path

2) Now for each folder that you DON'T want to ignore, pull in the content with

svn update --depth infinity /some/good/path

If the folder with content to ignore is not in the root of your working copy, you can work your way down the tree gradually with repeated calls to

svn update --depth immediates /some/path/to/make/deeper

This approach does have a disadvantage. If the files to ignore appear in your working copy through your own actions (e.g. build), they will show up in svn status as unversioned files. You can even svn add them and cause "file already exists" commit errors.


edit: Apparently you CAN reduce the depth of parts of your working copy, which is much simpler:

  1. normal project checkout (or start from existing working copy)
  2. delete undesired folder (normal filesystem delete, not svn rm). At this point the folder is missing and would return with all it's evil content if you did a normal update.
  3. bring back the folder with

svn update --depth empty /path/where/deleted/folder/was

Now you can do svn update of the entire project but the bad content will not return.

Wim Coenen
Wow, kinda complex, but it makes sense. Thanks for the info.
Frank Krueger
Yes, it takes some work. It's best to put the effort in a script that you can invoke multiple times to create fresh working copies.
Wim Coenen
+1  A: 

If they're version controlled then subversion is doing it's job :)

wcoenen's approach should also do the job after a bit of work, another approach could be a script which performs svn revert /project/src/bin then svn ci.

For what it's worth, this is one reason why we setup a "deploy" directory, and always ignore bin and obj directory output. That way only on certain release builds does the binary output get copied (and added to svn) to deploy.

Si
Agreed, svn is doing its job. I just don't like how the project was setup and am looking for a work-around.
Frank Krueger
+1  A: 

Usually you only want to keep binary files that have been explicitly released, i.e. official releases or binaries that are used by the Testing department. So it really doesn't make sense to commit every newly built binary.

So the real solution to your problem is a redesign of your SVN repository. The directories where the files are built shouldn't be under source control AND should be ignored using svn:ignore properties. This prevents newly built binaries from being noticed by SVN. Secondly you might create a separate directory where you store the binaries you do want to keep. This directory, ofcourse, needs to be under version control.

Now you can develop, without having troubles with changing binaries. When you finally get to the stage where you do want to keep those binaries, you just copy those binaries to that separate directory created above, thereby overwriting the old ones. SVN will now notice the files have changed and you can commit them.

Another approach that I have seen used in the past is to first create a TAG from your source tree. The build server (or yourself) then checks out this TAG and builds the binaries from that checked out TAG. Afterwards the built binaries are committed on top of that TAG. Many people think you should never ever commit on top of a TAG, but it might work for you. The only think you should remember is that when you export/check out that TAG you have to take the HEAD revision and not the TAG's own revision (which would be HEAD-1).

LeonZandman
Thank you for your thoughts, I agree 100%. Unfortunately, this is a project that I'm working for under contract and haven't bothered to give them your lecture. I was just hoping to work around their "bug".
Frank Krueger
A: 

Another important note to add to the above (copied from http://svnbook.red-bean.com/nightly/en/svn.advanced.props.special.ignore.html):

Subversion's support for ignorable file patterns extends only to the one-time process of adding unversioned files and directories to version control. Once an object is under Subversion's control, the ignore pattern mechanisms no longer apply to it. In other words, don't expect Subversion to avoid committing changes you've made to a versioned file simply because that file's name matches an ignore pattern — Subversion always notices all of its versioned objects.

Vaibhav Gumashta
You might wanna use the above mentioned technique in conjuntion with sparsed checkouts:http://svnbook.red-bean.com/en/1.5/svn.advanced.sparsedirs.htmlA proper initial sparse checkout (to suit your use case) + setting appropriate global-ignores in your config file can do the trick
Vaibhav Gumashta