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

Re: [PATCH] First step for issue #3702 (case-only renames on Windows) - now blocked by libsvn_client

From: Daniel Shahaf <d.s_at_daniel.shahaf.name>
Date: Wed, 4 May 2011 00:53:14 +0300

Johan Corveleyn wrote on Tue, May 03, 2011 at 23:29:26 +0200:
> On Tue, May 3, 2011 at 10:17 PM, Daniel Shahaf <d.s_at_daniel.shahaf.name> wrote:
> > Johan Corveleyn wrote on Tue, May 03, 2011 at 21:49:48 +0200:
> >> On Mon, Apr 25, 2011 at 11:26 PM, Daniel Shahaf <d.s_at_daniel.shahaf.name> wrote:
> >> > Johan Corveleyn wrote on Mon, Apr 25, 2011 at 23:10:21 +0200:
> >> >> On Mon, Apr 25, 2011 at 5:03 PM, Daniel Shahaf <d.s_at_daniel.shahaf.name> wrote:
> >> >> > Johan Corveleyn wrote on Mon, Apr 25, 2011 at 01:08:24 +0200:
> >> >> >> 2011/4/22 Branko Čibej <brane_at_e-reka.si>:
> >> >> >> > Meh. For now, just hack a special case so that committing one half of a
> >> >> >> > case-only rename will automagically commit the other half. Shouldn't be
> >> >> >> > too hard to do, and it's almost impossible to do the wrong thing --
> >> >> >> > after all, you're constrained by a) staying in the same directory, and
> >> >> >> > b) both halves of a rename resolving to the same on-disk file on a
> >> >> >> > case-insensitive file system.
> >> >> >>
> >> >> >> Sounds like another option. A small change here and there to make
> >> >> >> case-only renames work specifically (and not solve the more general
> >> >> >> problem of fixing path-guessing via wc-db or truepaths).
> >> >> >>
> >> >> >> The fact of the matter is that, for sane setups/companies,
> >> >> >> case-clashes are going to be really rare, *except when doing case-only
> >> >> >> renames*. A repository holding 'Foo', 'FOo' and 'FOO' would be a
> >> >> >> repository that's un-checkoutable on a case-insensitive filesystem
> >> >> >> anyway. So I'd expect companies that have to support case-insensitive
> >> >> >> clients to keep real case-clashes out of their repository (or fix them
> >> >> >> as soon as they are discovered).
> >> >> >>
> >> >> >> So maybe "case-only rename" (and perhaps "case-only replace"
> >> >> >> (delete+add w/o history)) is the only use-case we need to go for. But
> >> >> >> apart from commit, we should maybe also make "revert" possible, as
> >> >> >> well as adding to and removing from changelists ... (hm, commit would
> >> >> >> be the main thing I guess, revert can always be done in two steps
> >> >> >> (revert the add, then the delete), changelists ... oh well).
> >> >> >>
> >> >> >
> >> >> > Another use-case:
> >> >> >
> >> >> > When r1 contains a file 'Foo', r2 contains a file 'foo', the working
> >> >> > copy is at uniform revision r2, and the user types 'svn up -r1 Foo'.
> >> >> >
> >> >> > There is also a variant where Foo_at_r1 is a directory rather than a file,
> >> >> > but that's getting contrived.
> >> >>
> >> >> And I guess 'Foo' no longer exists in r2, and 'foo' didn't exist in
> >> >> r1? Maybe 'Foo' got renamed to 'foo'? Or maybe there is no historical
> >> >> relationship?
> >> >>
> >> >> Anyway, I think this also works right now, without any special tricks:
> >> >>
> >> >> - 'svn up -r1 Foo' gets canonicalized to 'svn up -r1 foo', the file
> >> >> on-disk, and currently present in the working copy.
> >> >>
> >> >> - If 'foo's ancestor is 'Foo', 'foo' gets deleted and 'Foo' is
> >> >> downloaded from the repository, by the update editor.
> >> >>
> >> >> The update editor currently has no problems with handling case-only
> >> >> renames on case-insensitive filesystems.
> >> >>
> >> >
> >> > Sorry for not being clear.
> >> >
> >> > In my example I intended 'foo' and 'Foo' to be two separate lines of
> >> > history.
> >> >
> >> > % svnadmin create r1
> >> > % svn co file://`pwd`/r1 wc1
> >> > % cd wc1
> >> > % svn mkdir iota
> >> > % svn ci -m r1
> >> > % svn rm iota
> >> > % svn mkdir IOTA
> >> > % svn ci -m r2
> >> > % svn up -r2
> >> > % option #1:   svn up -r1 iota
> >> > % option #2:   svn up -r1 iota IOTA
> >> >
> >> > For option #1, I specified 'iota', so I expect svn to error out saying
> >> > "You asked me to create ./iota but I can't because ./IOTA exists" (never
> >> > mind whether or not it's versioned).
> >>
> >> I'm confused. If you type "svn up -r1 iota", the iota is a target of
> >> the PATH variety, or in any case you're trying to address something in
> >> the working copy. At this point there is no ambiguity: you're actually
> >> referring to IOTA (the on-disk truepath), because what else is there
> >> (there is no iota present on disk, nor in the wc metadata)?
> >>
> >
> > There is ^/iota_at_1.  Just take IOTA out of the picture and try it:
> >
> > % svnadmin create r1
> > % svn co file://`pwd`/r1 wc1
> > % cd wc1
> > % touch iota && svn add iota
> > % svn ci -m r1 iota
> > % svn rm iota
> > % svn ci -m r2
> > % svn up -r2
> > % svn up -r1 iota
> >
> >> So you're really asking to update IOTA to r1, in which it didn't
> >> exist.
> >
> > No, I'm asking to restore 'iota' from r1, in which it did exist.
>
> Wow, I didn't even know that was possible :-). Reading "svn help up",
> I guess the last paragraph explains it:
>
> ------
> If the specified update target is missing from the working copy but its
> immediate parent directory is present, checkout the target into its
> parent directory at the specified depth. If --parents is specified,
> create any missing parent directories of the target by checking them
> out, too, at depth=empty.
> ------
>
> Getting back to your case-clashing example:
>
> > % svnadmin create r1
> > % svn co file://`pwd`/r1 wc1
> > % cd wc1
> > % svn mkdir iota
> > % svn ci -m r1
> > % svn rm iota
> > % svn mkdir IOTA
> > % svn ci -m r2
> > % svn up -r2
> > % option #1: svn up -r1 iota
> > % option #2: svn up -r1 iota IOTA
> >
> > For option #1, I specified 'iota', so I expect svn to error out saying
> > "You asked me to create ./iota but I can't because ./IOTA exists" (never
> > mind whether or not it's versioned).
> >
> > Option #2 is what I'd expect to work to get me iota_at_1 (at the expense of
> > shifting IOTA_at_2 to not-present(?) state, but that's the best I can do
> > given the filesystem's limitations). It's probably a bit tricky unless
> > we can ensure the editor sends IOTA before iota, though...
>
> Ok, if we'd have an option --literal-path, I'd go for your suggested
> way of handling it (don't know about the not-presentness of IOTA_at_2 in
> option #2).
>

:-)

> But, in the absence of such an option, I wouldn't try to support this.
> Otherwise, you're going even further than issue #3865 ('svn' on
> Windows cannot address scheduled-for-delete file, if another file
> differing only in case is present on disk). You're trying to target
> some path that's *missing* from the working copy, while a
> case-clashing file is present in the working copy. To do that, the
> client would first have to contact the repository to see if 'iota' is
> perhaps present in the repository at r1, before it can finally do the
> truepath conversion and decide you're actually meaning IOTA but
> mistyped the case :-).
>
> I.e.: without an explicit flag, I would let the client do the truepath
> canonicalization first (but after checking the wc-db (for case-only
> renames/replaces), and only after that try the "if it's missing, check
> it out from its parent" trick.
>

In the absence of such a flag it's indeed ambiguous whether the intended
semantics are to refer to ^/iota_at_1 or ./IOTA_at_2. If you're saying that
the former semantics is too costly (performance-wise) --- and I believe
it's also less historically compatible with past releases --- then +1
here to the latter semantics.

> Cheers,
> --
> Johan
Received on 2011-05-03 23:54:03 CEST

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