On 11/11/2011 11:41 AM, Julian Foad wrote:
Neels J Hofmeyr wrote:
I think there is general agreement (to the degree of common
sense?) that file and dir externals should behave the same
way.

+1 to that.

I would be fine with keeping current trunk: it changes file
externals' default behavior, so that they are treated like
dir externals. So now it's: never include any externals in
commit recursion, unless --include-externals.

So far so good; this is definitely an improvement over the previous mixture.

Yea. This thread should probably have stopped there, actually. Here is the long reason why:

I like your argument placing the whole issue in the bigger picture,
mentioning the other aspects (propset, revert, add, delete...). Thinking about those brings me back to a general awkwardness with dir externals, which I have not mentioned before to keep things simpler; it all comes from the fact that a dir external has its own distinct WC-root & wc.db:

Simple case: If I say 'svn commit sub/dir/target', 'svn' goes to 'sub/dir/target', finds its "most immediate" WC-root and uses that to find metadata (e.g. externals definitions). Say the immediate WC-root is 'dir'.

Extend above case: assume the WC-root in 'dir' actually belongs to a dir external, and its defining svn:externals prop is set on 'sub', which is the "original" WC-root. The target path is still 'sub/dir/target'.

To distinguish between above two cases is not so trivial. If 'svn' gets passed a target path and finds its WC-root, the only way of knowing whether that is already the "original", top-most WC-root is to scan upwards for more WC-roots. If we find a WC-root above it, then even that WC-root may itself be an external checked out by another parenting WC-root.

Furthermore, imagine a "skip-nesting" like this:
  WC-root (0) --> dir-external (1) --> dir-external (2)
The deeper dir-external (2) may actually be defined in (0)! I.e. an svn:externals definition for any given WC-root may be found on *any* level of WC-root above itself. Only when there is *no* WC-root found all the way to the file system root that has an externals definition for the target in question can we be sure that the target is not part of an external. Note that (1) treats (2) like an unversioned dir, because it does not know about the definition in (0). Only if a target path is part of (0) will svn treat (2) as the external that it is.

Note that the *target path* is of relevance, not the CWD.

This makes a general comprehensive-external-modes approach expensive: *Every* affected command has to scan upwards all the way to the FS root to find potential WC-roots with externals definitions. Now that's awkward.

Under this aspect, it would make sense to combine dir externals' wc.dbs with their topmost WC-root, i.e. to always automatically store sub-WCs' metadata in their single ancestral WC-root. (Queue Bert)

Another solution would be to mark each WC-root that is a dir external explicitly with its defining WC-root, at the time that the external is being checked out. (A simple WC-id <--> parent WC-root abspath table)

BTW, only then can --include-externals work as expected with "skip-nested" WCs (the situation above where "(0) defines (2)"), and only then can we prevent the user from committing an external marked "read-only third-party" when the user passes it as explicit target (which may happen by accident when using wildcards, for example).

So I guess a really good externals implementation is still some way further down the road. Looking at it in Julian's bigger picture, I think I'm not up to that ATM...

Let me mention that I have thankfully noticed Johan's and Stefan's remarks (prefer separate flag instead of using just revision peg, and not use '-c' because it means '-rN:M'), and that I agree with both.

Thanks everyone for the discussion! Heh, threads like this always remind me of Greg, some time back, telling me to stop spinning my wheels :)

~Neels

Reply via email to