Re: How to fix issue #4023 (on Windows, 'svn rm missingItem' deletes the unversioned 'MissingItem' from disk)?
From: Johan Corveleyn <jcorvel_at_gmail.com>
 
Date: Sun, 22 Jan 2012 21:24:44 +0100 
On Sun, Jan 22, 2012 at 9:12 AM, Bert Huijben <bert_at_qqmail.nl> wrote:
 Hm, interesting. I hadn't looked into that problem in detail yet, but
 > The other 'fix' was in svn, but this one can't be worked around at the
 Ok, but in the svn working copy, even on Windows, we can have a valid
 The root of this new copy-with-invalid-wcroot-casing problem is
 For #3865, we introduced the following special case:
     If the target was truepath'ed, but there is also an exact match to the
 The problem, apparently, is that the "original target" can also
 I don't know how to do it, but I guess this means that the only robust
 If this could be fixed, we can probably also rework the patch for
 > We can never 100% emulate a case sensitive filesytem on a case
 Heh. But we can still try to emulate it as good as possible :-).
 
-- 
Johan
> Bert Huijben (Cell phone)
> From: Johan Corveleyn
> Sent: 22-1-2012 2:48
> To: Bert Huijben
> Cc: Subversion Development
> Subject: Re: How to fix issue #4023 (on Windows, 'svn rm missingItem'
> deletes the unversioned 'MissingItem' from disk)?
> On Tue, Jan 17, 2012 at 3:02 PM, Johan Corveleyn <jcorvel_at_gmail.com> wrote:
>> On Sun, Jan 15, 2012 at 10:14 PM, Bert Huijben <bert_at_qqmail.nl> wrote:
>>>
>>>
>>>> -----Original Message-----
>>>> From: Johan Corveleyn [mailto:jcorvel_at_gmail.com]
>>>> Sent: zondag 15 januari 2012 21:26
>>>> To: Subversion Development
>>>> Subject: How to fix issue #4023 (on Windows, 'svn rm missingItem' deletes
>>>> the unversioned 'MissingItem' from disk)?
>>>>
>>>> Hi,
>>>>
>>>> I'm looking into fixing issue #4023. I'd like to have some feedback on
>>>> a possible solution, and some hints on how to best implement it.
>>>>
>>>> The problem
>>>> -----------
>>>> - 'svn rm missingItem' (while there is a 'MissingItem' on disk, and
>>>> not a 'missingItem') will eventually call
>>>> adm.ops.c#svn_wc__delete_many, with 'missingItem' as one of the
>>>> targets (so far so good).
>>>>
>>>> - svn_wc__delete_many, after updating wc.db, will eventually call
>>>> erase_unversioned_from_wc, which will call
>>>> svn_io_remove_file2('missingItem').
>>>>
>>>> - At this point, we have a problem, because
>>>> svn_io_remove_file2('missingItem') will eventually call the Windows
>>>> API DeleteFileW, which will happily delete 'MissingItem' when given
>>>> the 'missingItem' argument.
>>>>
>>>>
>>>> Proposed solution
>>>> -----------------
>>>> Inside svn_wc__delete_many, we could find out that 'missingItem' is,
>>>> you know, missing, before we try to delete it from disk. In that case,
>>>> there is no need to call erase_unversioned_from_wc, so no call to
>>>> DeleteFileW occurs.
>>>>
>>>>
>>>> I can't come up with a better way, but if someone has other ideas, shoot.
>>>>
>>>> If this is indeed the way to proceed, then I'd appreciate a small
>>>> hint/pointer: how do I find out (as cheaply as possible) whether the
>>>> target in question is missing? In the beginning of
>>>> svn_wc__delete_many, a call is done to svn_wc__db_read_info, but this
>>>> doesn't seem to give this information (status == normal, kind == file,
>>>> whether or not the file in question is missing from disk).
>>>
>>> The cheapest way to check would be (indirectly) calling the
>>> apr_filepath_merge call to find the paths true name. If the basename of the
>>> returned path is (case-)different than the path you entered, then the file
>>> would be missing.
>>> If the file is really missing, you would get the identical path or an error
>>> from that call.
>>
>> Thanks. I'll look into that.
>>
>> I'll try to complete it during this week, but these are busy times, so
>> if someone beats me to it: no problem.
>>
>>> On Windows this is cheaper than retrieving all directory entries in the
>>> parent directory and checking yourself and on other platforms getting the
>>> truename is a no-op.
>>>
>>>
>>> We might have a wrapper for that apr_filepath_merge, for handling the path
>>> encoding conversion.
>>> If we have, then we probably used it for the file move fix we programmed in
>>> Berlin. If not, then we should probably add one :)
>>
>> Yes, apr_filepath_merge (with APR_FILEPATH_TRUENAME flag) is wrapped
>> inside svn_opt__arg_canonicalize_path. Am I allowed to call this
>> function from inside svn_wc__delete_many? In that case, I can just
>> call that function and compare its output with the output of
>> svn_dirent_internal_style, just like we did for the 'case-only move'
>> code.
>>
>> Actually, during the Berlin hackathon last year, we fixed the
>> case-only moves without adding another call to
>> svn_opt__arg_canonicalize_path. Instead, we did it by inserting some
>> additional logic inside cmdline.c#svn_client_args_to_target_array,
>> where the truepath conversion is done anyway, for all the path
>> arguments. At that point we already had knowledge of both the original
>> form and the truepath-converted form, so we could compare the two.
>> (see r1124469 and r1131326)
>
> Hi Bert,
>
> Ok, the following patch fixes issue #4023 (and passes make check). But
> I'm not sure if it's a "good fix" (more below). So I'd like some extra
> eyes if possible ...
>
> [[[
> Index: subversion/libsvn_wc/adm_ops.c
> ===================================================================
> --- subversion/libsvn_wc/adm_ops.c      (revision 1233695)
> +++ subversion/libsvn_wc/adm_ops.c      (working copy)
> @@ -59,6 +59,7 @@
>  #include "svn_private_config.h"
>  #include "private/svn_io_private.h"
>  #include "private/svn_wc_private.h"
> +#include "private/svn_opt_private.h"
>
>
>
> @@ -742,14 +743,29 @@ svn_wc__delete_many(svn_wc_context_t *wc_ctx,
>    * unversioned. */
>   if (!keep_local)
>     {
> +      const char *local_truepath;
> +
>       for (i = 0; i < versioned_targets->nelts; i++)
>         {
>           svn_pool_clear(iterpool);
>
>           local_abspath = APR_ARRAY_IDX(versioned_targets, i, const char *);
> -          SVN_ERR(erase_unversioned_from_wc(local_abspath, TRUE,
> -                                            cancel_func, cancel_baton,
> -                                            iterpool));
> +
> +          /* Canonicalization will, on Windows, return the 'truepath' of the
> +             given target (the actual casing on disk corresponding to the
> +             given path).  If this differs from the original target, we know
> +             that the latter is missing from disk, and another case-clashing
> +             file is present.  In that case, we avoid the call to
> +             erase_unversioned_from_wc (which would otherwise erase the wrong
> +             file from disk).  See also issue #4023. */
> +          SVN_ERR(svn_opt__arg_canonicalize_path(&local_truepath,
> +                                                 local_abspath, iterpool));
> +          if (strcmp(local_abspath, local_truepath) != 0)
> +            continue;
> +          else
> +            SVN_ERR(erase_unversioned_from_wc(local_abspath, TRUE,
> +                                              cancel_func, cancel_baton,
> +                                              iterpool));
>         }
>     }
>
> ]]]
>
> Some things on my mind:
>
> - Is it ok to call svn_opt__arg_canonicalize_path from libsvn_wc, or
> is this some kind of layering violation? (if so, we'd have to write
> another wrapper for apr_filepath_merge (if so, where should we put
> this?))
>
> - It can only detect real 'case-clashes' (which is sufficient to fix
> #4023), not 'missing' in general (like we discussed above). That's
> because, going through svn_opt__arg_canonicalize_path, one cannot see
> whether apr_filepath_merge returned an error, or just canonicalized to
> the identical path (meaning the exact path was present). Both will
> return the given path as is. OTOH, this is not really a problem, it's
> enough to get #4023 fixed ...
>
> --
> Johan
Received on 2012-01-22 21:25:38 CET
 | 
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.