[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: follow symlinks

From: Ben Reser <ben_at_reser.org>
Date: Wed, 06 Nov 2013 16:47:34 -0800

On 11/6/13 1:49 PM, Dirk wrote:
> after going "full retard" in IRC (it was good for me) I have calmed down enough
> to give constructive criticism in regards of subversion and how it handles
> symbolic links on Unix (and compat.) platforms.

First of all this really belongs on the users@ list and not dev@. But it's
here now so let's look at what your issues are...

> I wan't to start with a question. I am confident there is no answer to it. At
> least not from people who share code between projects.
>
> * Why does subversion store symbolic links instead of following them? *

It would be a lot more likely for you to get a better response if you actually
explained what you were trying to do. What use case(s) did you run into where
how we're behaving are problematic. What version of Subversion were you using
that presented problems? It's possible this is a bug, in fact quite a few
issues have cropped up with this sort of thing due to the change from WC to
WCNG that happened in 1.7.x.

Since I don't have any sense of what you were actually trying to do...

Let's just talk a bit about what Subversion does right now (including some
places that are probably a step back from earlier versions) with trunk (though
nothing mentioned here should have significantly changed since 1.8.4).

[[[
$ svnadmin create repo

$ svn co file://`pwd`/repo wc
Checked out revision 0.

$ ln -s wc wc-link

$ svn info wc
Path: wc
Working Copy Root Path: /Users/breser/symlinks/wc
URL: file:///Users/breser/symlinks/repo
Relative URL: ^/
Repository Root: file:///Users/breser/symlinks/repo
Repository UUID: ae7752ff-322b-45e2-ba88-c74efb4e3747
Revision: 0
Node Kind: directory
Schedule: normal
Last Changed Rev: 0
Last Changed Date: 2013-11-06 15:36:27 -0800 (Wed, 06 Nov 2013)

$ svn info wc-link
Path: wc-link
Working Copy Root Path: /Users/breser/symlinks/wc-link
URL: file:///Users/breser/symlinks/repo
Relative URL: ^/
Repository Root: file:///Users/breser/symlinks/repo
Repository UUID: ae7752ff-322b-45e2-ba88-c74efb4e3747
Revision: 0
Node Kind: directory
Schedule: normal
Last Changed Rev: 0
Last Changed Date: 2013-11-06 15:36:27 -0800 (Wed, 06 Nov 2013)

$ cd wc

$ echo foo > foo

$ svn add foo
A foo

$ svn ci -mm
Adding foo
Transmitting file data .
Committed revision 1.

]]]

So far so good, my linked path to the working copy followed the symlink and
gave me info about the wc I was looking at. I've got a new file that I've added.

[[[
$ ln -s foo bar

$ svn ci -mm
Adding bar
Transmitting file data .
Committed revision 2.

$ svn pl -v bar
Properties on 'bar':
  svn:special
    *

$ svn cat bar
link foo

]]]

Okay so now Subversion stored a link when I `svn add`ed a link. I don't think
this is too spectacularly unexpected. I told it to add a symlink.

Let's continue looking at the behavior that Subversion has with symlinks though.

[[[
$ svn mkdir dir
A dir

$ cd dir

$ echo alpha > alpha

$ svn add alpha
A alpha

$ svn ci -mm
Adding .
Adding alpha
Transmitting file data .
Committed revision 3.

$ cd ../..

$ ln -s wc/dir dir-link

$ svn info dir-link
Path: dir-link
Working Copy Root Path: /Users/breser/symlinks/wc
URL: file:///Users/breser/symlinks/repo/dir
Relative URL: ^/dir
Repository Root: file:///Users/breser/symlinks/repo
Repository UUID: ae7752ff-322b-45e2-ba88-c74efb4e3747
Revision: 3
Node Kind: directory
Schedule: normal
Last Changed Author: breser
Last Changed Rev: 3
Last Changed Date: 2013-11-06 15:49:34 -0800 (Wed, 06 Nov 2013)

$ echo one >> dir-link/alpha

$ svn status dir-link/alpha
svn: warning: apr_err=SVN_ERR_WC_NOT_WORKING_COPY
svn: warning: W155007: '/Users/breser/symlinks/dir-link/alpha' is not a working
copy

$ svn commit dir-link/alpha
/Users/breser/wandisco/share/wcs/svn-trunk/subversion/svn/commit-cmd.c:182,
/Users/breser/wandisco/share/wcs/svn-trunk/subversion/libsvn_client/commit.c:648,
/Users/breser/wandisco/share/wcs/svn-trunk/subversion/libsvn_client/commit.c:372,
/Users/breser/wandisco/share/wcs/svn-trunk/subversion/libsvn_wc/wc_db.c:1615,
/Users/breser/wandisco/share/wcs/svn-trunk/subversion/libsvn_wc/wc_db_wcroot.c:626:
(apr_err=SVN_ERR_WC_NOT_WORKING_COPY)
svn: E155007: '/Users/breser/symlinks/dir-link/alpha' is not a working copy

$ svn status wc/dir/alpha
M wc/dir/alpha

$ svn commit wc/dir/alpha -mm
Sending wc/dir/alpha
Transmitting file data .
Committed revision 4.
]]]

So now we made a directory inside our working copy and added a file. We went
up outside our working copy and made a symlink into it. We then tried to run a
status using the symbolic link in target, which failed. We then tried to
commit the file using the same link as the status and that fails again. Using
the real path without the symlink and it works fine.

So now let's try the same thing with 1.6:
[[[
$ mkdir 1.6

$ cd 1.6

$ svnadmin-1.6 create repo

$ svn-1.6 co file://`pwd`/repo wc
Checked out revision 0.

$ cd wc

$ svn mkdir dir
A dir

$ echo 'alpha' > dir/alpha

$ svn add dir/alpha
A dir/alpha

$ svn-1.6 ci -mm
Adding dir
Adding dir/alpha
Transmitting file data .
Committed revision 1.

$ cd ..

$ ln -s wc/dir dir-link

$ echo one >> dir-link/alpha

$ svn-1.6 status dir-link/alpha
M dir-link/alpha

$ svn-1.6 commit dir-link/alpha -mm
Sending dir-link/alpha
Transmitting file data .
Committed revision 2.
]]]

And as you can see this is a regression in our behavior. A regression that
happened with 1.7.x. A regression caused by the change to WCNG with a single
.svn at the root of the working copy.

I haven't dug too far into this but I suspect what's happening is we're walking
up the tree to find the .svn directory without looking to see if the path is a
symbolic link and possibly following it.

This *IS* busted. I suspect based on what you say below that this is the
problem you ran into.

The above demonstrated problem really has *NOTHING* to do with the fact that
Subversion supports versioning symlinks. In fact as you can see we handled it
just fine in 1.6.x.

> I really don't get it. Who has a symbolic link inside a codebase pointing to
> another place inside the same codebase? That. And only that would justify the
> way how subversion handles symbolic links.

There are legitimate reasons to want to version symbolic links. There are
people that would like us to be able to version more of the unix filesystem. A
great example of this is people who version their home directories (I happen to
be one). I would like Subversion to be able to handle a lot of things that it
doesn't that I have to deal with on my own (e.g. permissions).

So frankly I'd say that your viewpoint is rather remarkably limited to the
particular use cases you have.

> So it was suggested to do it the subversion way. I can only assume that
> subversion reinvents the usability of symlinks in it's own
> murky/un-intuitive/proprietary way because of alternative operating systems
> like windows that have nothing like symlinks. (I am sure there will be a
> enthusiast trying to convince me that subversion does it better than the
> symlinks i used the last 15 years. - It doesn't.)

I suspect people were suggesting that you use svn:externals (which is an
entirely different beast) and may or may not be better for your use case.
svn:externals certainly have their own issues.

But it's really difficult to make suggestions to based on what you've provided.
 If you hung around on IRC longer, so that people could engage more with you or
if you spent more time explaining what you were doing it would be easier.

> So subversion has been developed for more than a decade now and nobody thought
> about adding --enable-follow-symlinks or something similar to the configure
> script. Fine. I can do it myself.

I'm not sure there are any commands that need --enable-follow-symlinks. The
busted examples above should be fixed (no need for a option).

The ability to store symlinks does mean that commands that act on versioned
resources have to act on the symlink when the symlink is versioned. E.g. `svn
cat versioned-symlink` is going to give you the contents of the special file
not the contents of the file that versioned-symlink points at. That should be
ok since you could just as easily use your OS level cat command if you want to
follow the symlink. The fact that you're using the svn command implies you
want to act on versioned resources that your typical OS command can't do.

The unfortunate side effect is that yes if you're going to use symlinks you
might have to think about things you would be able to ignore otherwise.

> So I did just remove the #define HAVE_SYMLINKS from the config and build it
> myself.
>
> Only to end up with a client who /still/ recognizes symbolic links and refuses
> to follow them.

Because the problem as I described above doesn't really have much to do with
our symlink support and rather has everything to do with failure to find the
working copy root properly.

> Tonight I found out that subversion also has a problem when I just use mount
> --bind to share code between projects. I thought I could do that after the .svn
> was centralized in the root of the project. But no. Subversion doesn't like that.

Actually centralized .svn directories makes it much more complicated to do
this. If you bind at the root of the working copy this should be no problem,
but if you bind to a sub directory of the working copy then it's going to be
impossible for us to walk up the path and find the root of the working copy.
When we had the .svn directories spread out this was no problem, but a lot of
people didn't like it for other reasons. The trade off of centralizing this
information at the root is breaking these sorts of use cases.

> Another Problem I have with subversion is that everything is stored in binary
> files. It is not like that I damage my repositories all the time. It happens
> maybe once every couple of years. But when it happens there is nothing else to
> do that to start a new repository with whatever is left in the local copy.
>
> I'd like to point out that CVS can, under any circumstance, be fixed with a
> standard text editor. I just never had it that I has to reimport a CVS
> repository to fix a broken one.

It's probably only going to go more and more that way because simply put it's
difficult to give good performance using plaintext files.

> I really wonder what the advantages of subversion are except from that
> TortoiseSVN is more actively developed than TortoiseCVS whose developers seem
> to have a irrational aversion against switching from XP to Win7. Win7 is ok for
> a Windows.

There are innumerable comparisons on the web. You're of course free to decide
for yourself which you prefer. Subversion is a tool, there are innumerable
failings. I think you'd be hard pressed to find a non-trivial piece of
software that you couldn't sling mud at.

> So. Despite knowing that some narcissistic project herald will announce to my
> face that "It is impossible. Because it doesn't flow with out vision." I would
> like ask you to include a compile option in the configure script that makes
> subversion follow symlinks. Just for (the majority of) us developers who have
> no use for symbolic links instead of the actual files in their repository.
>
> The package maintainers shall continue ignoring that little feature.
>
> That way subversion would embrace something that made Linux great: Choice.

Assuming I'm correct about your issue we ought to be able to fix it in a way
that doesn't cause you problems without needing to remove symlink support.

I think you're going to need to be a lot more specific about what you're doing
if you disagree.
Received on 2013-11-07 01:48:14 CET

This is an archived mail posted to the Subversion Dev mailing list.