Subversion’s biggest hole

Saturday 21 June 2008This is 15 years old. Be careful.

Subversion 1.5 has just been released, but it does nothing to fix what I consider to be Subversion’s biggest hole. I know people deride svn for not being distributed, or for doing a bad job of merging, and both of those will be solved when everyone finally switches over to git, as I’m sure we all will eventually.

But I don’t miss those things. The thing I miss that Subversion is lacking is a repository setting for globally ignored files. You can set a property on a directory to ignore (for example) *.pyc files. And you can set your client to always ignore *.pyc files in any working tree on your machine. But there is no way to set a repository to ignore *.pyc files anywhere they appear in the tree.

This is such a common need in software development, and is truly a property of the repository, not the client. Why are we still either touching every directory in the tree, or touching every client on the team?

And probably this will also be solved when we all switch over to git...


André Felipe Dias 10:29 AM on 21 Jun 2008
Sorry, but you're wrong. There is a global way to configure repositories to ignore files. It seems that you have not read Subversion documentation yet. Pay attention to SVN Red Book - Chapter 7 ( and you'll find out how to do it.

Anyway, from SVN 1.5 on, *.pyc is already included in global ignore files.

Besides, neither Git nor distributed version control systems are not the solution to everything:

"It is clearly true that if you're in a tighten control corporate environment, centralized systems work better".

Who said that? Me? No. It was said by our "modest" leader Linus Tovard during a presentation at Google in 2007.
André, I'd love to be proven wrong, but the chapter you referenced contains nothing of interest. It describes the per-client settings I mentioned in the post, but I don't see a way to set the repository to ignore files. Maybe I'm just being dense. Please give me a more specific pointer.

I was being only a bit tongue-in-cheek with the Git references. I think it will be widely adopted, but subversion also has a long future ahead of it. I've watched Linus' presentation, and unfortunately couldn't take much of it seriously. The actual content would fit in about ten minutes, the rest was just him making clumsy jokes about other systems and developers.
I didn't know you couldn't do something that simple in svn. I have always done the client side configuration and it has always been a pain moving from one machine to the next and having to do the same thing all over again.
"only a bit tongue-in-cheek", eh? Advocating the fairly confusing git, in an ecumenic way, *twice*, is rather bad, in my book, tongue-in-cheek or not.

Anyway, you may as well forget it, I'd say, since we have the precious simplicity of Mercurial (and Bazaar-NG too).

It actually saddens me a bit, seeing many Pythonistas flocking to complicated tools, when the pythonic ones, within and without, are readily available.

But then, the simple way is not always easy to follow. And no amount of joking is going to make it easier.
André, global-ignores is the client-side option that controls your client. It is not a repository setting, it will not automatically apply to other developers using your repository.

When new developers join my team, we have to manually ensure that their global-ignores setting is correct for the repository. This is precisely the thing I am complaining about.
Nicola, I know that git is a polarizing topic, I guess I didn't realize just how much...
Nicola: I read Ned's git references as tongue in cheek. I'm also not quite sure how Ned's post is ecumenical.

You're coming over overly defensive to me, with partisanism leaking through in the "fairly confusing".

IMO Ned's post was less one-sided than your comment.
If you feel so strongly about this, why not just submit it as a feature request to the subversion project?
This is one of the benefits of an open-source's an open community.
svn:ignore property seems to work well enough.

Maybe what needs to be done is a silent recursive for properties instead of only focusing on the ignore feature itself. Something like svnglobal:ignore or svnglobal:*. Any directories or files further down inherit these properties from the level above.

Or maybe properties should just be recursive all the time. If they are overwritten on a lower folder, then they are overwritten for that level. That would make a lot more sense to me.
André Felipe Dias 4:19 PM on 21 Jun 2008
You're right about global-ignore. It only works at machine level, not at server level even setting /etc/subversion/config, I thought. I apologize, but not for the git part ;o)

Actually, the problem is not only the global-ignore; the svn:ignore handles this just fine. The problem I see is related to auto-props:

"The auto-props section controls the Subversion client's ability to automatically set properties on files when they are added or imported."

It would be nice if there were a config section at repository level where we could set ignores and auto-props at repository level. This would be much simpler than try to do the same through a hook.

I searched in Subversion bug database and didn't found any related issue. Now, I will suggest this at svn mailing list.
André Felipe Dias 4:24 PM on 21 Jun 2008
I mean, if you won't post the suggestion yourself, I'll.

Regarding your comment that it is a feature of the repository and not the client, that really depends on what side of the fence you stand on. I could argue that the repository should store whatever files are sent to it - you're arguing that it shouldn't.

From a personal stand point, I don't find the client side configuration such a problem - however I also don't need to check out lots of different repositories all the time. Out of interest, what are you doing that makes the client side setting such a pain?

"I could argue that the repository should store whatever files are sent to it - you're arguing that it shouldn't."

One of the main benefits of client-server architectures, in this case using a central repository for version control, is that the single server can enforce rules rather than relying on the goodwill of fallible and possibly hostile clients.
Any choice that favors the clients over the server, such as promising to accept and store any file from clients rather than reserving the right to ignore them, undermines this important strength of the central server model; when a project doesn't want silly files in its repository, hoping that everyone uses a suitably configured client at all times is strictly worse that setting a rule once, in one place, and knowing that it will be respected whatever the users do.
@Al: you say the repository should store whatever files are sent to it, but you don't mind having the repo store the svn:ignore property, which directs clients as to what files to send. The same architecture would hold for a global repo setting which told the client what files to send.

@Lorenzo: excellent point.
Yes, the global-ignores thing is something that has always annoyed me - as the admin of several SVN servers - very much. You can write guidelines for your developers on how to set up their SVN client and provide an example configuration, but many will just not listen. A similar issue is the svn:eol-style setting. I wish I could set this centrally on the repository so people would stop checking in files with horrible CRLF line endings.

And while were at it, I have not found a way to specify any svn:ignore rules when importing a project into SVN. With CVS, you can just put .cvsignore files in place, but with SVN, you have to remove any files you don't want to import first, then do the import and then copy them back. Very cumbersome. :-(
Well yes, after switching to Mercurial (in strict, corporate environment) a lot of buggy unconfortabilities disappeared.

You don't know about them till You're used to work without them and then forced to switch back on some projects.

Ideally Subversion would have repository-based config, I agree. However, you could use a pre-commit hook to prevent people from checking in CRLF files.

Regarding ignores-on-import: Your ~/.subversion/config should be able to do this. See there for details. (You may want to move that dir aside and re-run 'svn', so the dir will be recreated and then you can see the latest template.)
Subversion (which I use myself) surely has many failings. But somehow I would never have thought to list as its MOST important failing a flaw which can be resolved by having all new developers run a single setup script (to activate the client-side global ignore) when they first check out the code. It seems like such a simple solution.

It may not be Subversion's biggest problem, but I think it's not as easily solved as you imply. First of all, getting every developer to run any kind of one-time setup script is always going to be a problem. Second, you don't address how the list of global ignores (or mime-types, or whatever) is to be updated, which it will surely need to be from time to time. Third, you might be assuming homogenous client environments, but that is rarely a reality. Fourth, what if the developers already have their own ignore-configuration set up -- now the script has to be smart enough to merge, rather than overwrite.

The solutions to this are not simple; that's why it comes up over and over and over in our user forums.
Umm... pre-commit hook script? I guess Karl already mentioned that. Still, it is much more flexible than a hard-coded property that affects an entire repository (perhaps you want compiled binaries in a distribution tag) and only filters based on filename extensions.
By the way, I'd like to point out how it is done in Git.

In Git there are local, per repository ignore file `.git/info/excludes` and `.gitignore` file in working directory, which can be comitted and therefore applies to all clones of given repository; equivalent of server-side settings in Subversion, IIRC.

Now patterns in `.gitignore` applies *RECURSIVELY* to the directory the `.gitignore` file is in and all its subdirectories... unless pattern contains slash '/' (for example begins with '/'), then it is "anchored" and must match non-recursively.

See gitignore(5)
The svn command takes a --config-dir argument. Why not put a wrapper around the svn command that points to a global svn config dir?

#!/bin/tcsh -f
/usr/bin/svn --config-dir=globalconfigdir $argv

That's still a client-side solution, and anyway, why would someone do that rather than just set it in their ~/.subversion/ config area? (I think the days of multiple developers running their client-side processes on the same machine are mostly gone -- perhaps your dev environment is an exception?)
I want all of the developers to use the same config so that I can set ignores and auto-props globally. By using the wrapper I can set --config-dir to a global config file. If we used ~/.subversion I would need to get all the developers to create, update, and maintain their ~/.subversion/config files ... I would prefer to set on the server side but I think that hole is still there...

Add a comment:

Ignore this:
Leave this empty:
Name is required. Either email or web are required. Email won't be displayed and I won't spam you. Your web site won't be indexed by search engines.
Don't put anything here:
Leave this empty:
Comment text is Markdown.