[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: Johan Corveleyn <jcorvel_at_gmail.com>
Date: Sat, 16 Apr 2011 16:14:35 +0200

2011/4/16 Branko Čibej <brane_at_e-reka.si>:
> On 16.04.2011 10:17, Johan Corveleyn wrote:
>> Hi,
>>
>> Following discussion in [1], I tried to write a patch for issue #3702
>> ("svn ren TODO todo" not work on windows). As mentioned by Bert in
>> comment to the issue [2], we need to avoid letting 'svn move' convert
>> the destination path to on-disk casing in this case, so that's what
>> the below patch does.
> [...]
>
> Your biggest headache is going to be dealing with the fact that the WC
> database is case-sensitive, as in, for example:
>
>    svn mv foo foo
>
> where the file on disk (and in the database) is actually called Foo. The
> above operation is perfectly valid on case-insensitive file systems. The
> other case is where neither the source nor the destination name of the
> rename match the name case in wc-db.

Yes, but I think I covered that. Disregarding for a minute the problem
that libsvn_client still disallows the move, the flow is now as
follows, after my patch:

(1) Normalize all paths to their on-disk representation (the existing
code which was already there, using apr_filepath_merge with flag
APR_FILEPATH_TRUENAME).

(2) Now the patch comes in effect: if the normalized dst_path is equal
to the normalized src_path, we potentially have a case-only rename. In
that case, re-normalize the dst_path without converting to on-disk
representation, and try to do the move with that dst_path.

If the file on disk is Foo, then "svn mv foo foo" would then be
transformed to a move of Foo (on-disk rep) to foo (not converted to
on-disk rep). Which is exactly what I would expect as a user, because
that's what happens on Windows when you do the same with the native
"move" command.

> N.B.: You are absolutely not allowed to do a case-insensitive comparison
> of file names anywhere. You must let the filesystem decide if Foo and
> fOO refer to the same file. This is because the file system can (and
> often will) have different ideas about case folding than the current
> locale does. This implies that, if you "svn mv foo foo", and the file on
> disk is "fOO" but the entry in the wc-db is "Foo", you have to scan the
> directory in wc-db and check if the truename of any of those entries
> matches the truename of the rename source. This is not very optimal at
> all, but I don't see any other sure way of getting correct results.

Thanks for the heads up. When I do a comparison in libsvn_client (as I
described), I think I'll let apr_filepath_merge with flag
APR_FILEPATH_TRUENAME do this (or some similar function), just like
the existing code does (like in
libsvn_subr/opt.c#svn_opt__arg_canonicalize_path) - or just call that
function in opt.c or something. So I'll definitely not try to ignore
case myself.

Do I have to worry about differences between on-disk casing and wc-db
casing of a path? Is that possible? I guess it is by using non-svn
commands, but I bet that's an invalid state of the wc (I know that in
1.6, if you run into this, svn gets all confused (marking the file it
has in metadata as deleted, and your on-disk file as unversioned)).
That's definitely out of scope for the change I'm trying to make.

Cheers,

-- 
Johan
Received on 2011-04-16 16:15:27 CEST

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

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.