You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@subversion.apache.org by Иван Селин <iv...@yandex-team.ru> on 2019/11/18 09:15:16 UTC

Cannot get info for a file that was inside of file-replaced directory

Hi!

I think I've found a bug in subversion client. Setup is as follows:

1\. Create directory with a file in it — commit 1

2\. Replace directory with other file — commit 2

3\. Call "svn info dir/file@1" — it should give information about dir/file at
revision 1, but it fails saying that "dir" is a file at latest revision:

svn: E160016: Failure opening '/dir' in revision 2

svn: E160016: '/dir' is not a directory in filesystem
'0bc899d5-c233-4fed-98a3-8705ddfc96c4'

But directory can be listed, it shows the file, and file can be listed too:

$ svn info file:///tmp/subversion-info-on-replaced-file/repo/dir@1

Path: dir

URL: file:///tmp/subversion-info-on-replaced-file/repo/dir

Relative URL: ^/dir

Repository Root: file:///tmp/subversion-info-on-replaced-file/repo

Repository UUID: 0bc899d5-c233-4fed-98a3-8705ddfc96c4

Revision: 1

Node Kind: directory

Last Changed Author: ivanselin

Last Changed Rev: 1

Last Changed Date: 2019-11-18 11:38:16 +0300 (Пн, 18 ноя 2019)

$ svn list file:///tmp/subversion-info-on-replaced-file/repo/dir@1

file

$ svn list file:///tmp/subversion-info-on-replaced-file/repo/dir/file@1

file

So, only "info" does not work. It seems that it's performing directory check
against HEAD instead of provided peg revision. Adding --revision key changes
nothing. This is trunk svn (1.14.0-dev, r1869957), svn 1.9.7 does not have
this bug, it correctly shows info.

Sample reproduction script attached.

Regards,

Ivan.


Re: Cannot get info for a file that was inside of file-replaced directory

Posted by Иван Селин <iv...@yandex-team.ru>.
Hi, Nathan!

Thanks for your reply. If you need anything else, I can provide more
information to help debug the problem.

Regards,

Ivan.

19.11.2019, 08:04, "Nathan Hartman" <ha...@gmail.com>:

> On Mon, Nov 18, 2019 at 4:53 AM Иван Селин <[ivanselin@yandex-
team.ru](mailto:ivanselin@yandex-team.ru)> wrote:

>

>> Hi!

>>

>> I think I've found a bug in subversion client. Setup is as follows:

>>

>> 1\. Create directory with a file in it — commit 1

>>

>> 2\. Replace directory with other file — commit 2

>>

>> 3\. Call "svn info dir/file@1" — it should give information about dir/file
at revision 1, but it fails saying that "dir" is a file at latest revision:

>>

>> svn: E160016: Failure opening '/dir' in revision 2

>>

>> svn: E160016: '/dir' is not a directory in filesystem
'0bc899d5-c233-4fed-98a3-8705ddfc96c4'

>>

>> But directory can be listed, it shows the file, and file can be listed too:

>>

>> $ svn info file:///tmp/subversion-info-on-replaced-file/repo/dir@1

>>

>> Path: dir

>>

>> URL: file:///tmp/subversion-info-on-replaced-file/repo/dir

>>

>> Relative URL: ^/dir

>>

>> Repository Root: file:///tmp/subversion-info-on-replaced-file/repo

>>

>> Repository UUID: 0bc899d5-c233-4fed-98a3-8705ddfc96c4

>>

>> Revision: 1

>>

>> Node Kind: directory

>>

>> Last Changed Author: ivanselin

>>

>> Last Changed Rev: 1

>>

>> Last Changed Date: 2019-11-18 11:38:16 +0300 (Пн, 18 ноя 2019)

>>

>> $ svn list file:///tmp/subversion-info-on-replaced-file/repo/dir@1

>>

>> file

>>

>> $ svn list file:///tmp/subversion-info-on-replaced-file/repo/dir/file@1

>>

>> file

>>

>> So, only "info" does not work. It seems that it's performing directory
check against HEAD instead of provided peg revision. Adding --revision key
changes nothing. This is trunk svn (1.14.0-dev, r1869957), svn 1.9.7 does not
have this bug, it correctly shows info.

>>

>> Sample reproduction script attached.

>

> Hello Ivan,

>

> Thank you for reporting this.

>

> I performed similar steps and I am seeing the same result, namely:

>

> $ svn info "$repo/dir/file"@1

>

> svn: E160016: Failure opening '/dir' in revision 2

>

> svn: E160016: '/dir' is not a directory in filesystem '(snip)'

>

> You asked for peg revision 1, it's looking in revision 2.

>

> I'm investigating...

>

> Thanks again for reporting this.

>

> Nathan


Re: Cannot get info for a file that was inside of file-replaced directory

Posted by Nathan Hartman <ha...@gmail.com>.
On Tue, Nov 26, 2019 at 12:21 PM Nathan Hartman
<ha...@gmail.com> wrote:
> On Mon, Nov 25, 2019 at 12:03 PM Julian Foad <ju...@apache.org> wrote:
> > Yes, (2): it already checks for two error codes:
> >
> >        ((err->apr_err == SVN_ERR_CLIENT_UNRELATED_RESOURCES) ||
> >         (err->apr_err == SVN_ERR_FS_NOT_FOUND)))
> >
> > we need to add:
> >
> >         (err->apr_err == SVN_ERR_FS_NOT_DIRECTORY) ||
> >
> > Fixed: http://svn.apache.org/r1870395
> >
> > This does beg the question of what is the total set of possible failure
> > modes that should be handled the same way.
>
> I went through the list of error in svn_error_codes.h one by one and
> two possibilities came to mind:
>
> The first is SVN_ERR_FS_NOT_FILE. I wonder if this code would appear
> and cause a failure if a similar test is run, but replacing a file
> with a directory instead of replacing a directory with a file... I'll
> test that scenario a little later...

Nope. Replacing a file with a dir does not appear to trigger an error
here. I tested with r1870266 (before the fix) and r1870479 (after the
fix). I guess the only way to know whether there are additional
failure modes is with random testing as you suggested previously.

For the record, I tested with (excuse the hard-coded paths, again):

[[[

#!/bin/bash

SVN=/home/nate/ramdrive/svn-trunk/subversion/svn/svn
SVNADMIN=/home/nate/ramdrive/svn-trunk/subversion/svnadmin/svnadmin

REPO="/home/nate/ramdrive/repo"
WC="/home/nate/ramdrive/wc"

rm -rf "$REPO"
rm -rf "$WC"

echo "Running test with this version of Subversion:"
svnversion /home/nate/ramdrive/svn-trunk

set -x

"$SVNADMIN" create "$REPO"
"$SVN" checkout "file://$REPO" "$WC"
cd "$WC"

# Revision 1 will create a file called dir

echo "to be replaced" > dir
"$SVN" add dir
"$SVN" ci -m 'Add a file called dir'

# Revision 2 will replace the file called dir with an actual dir

"$SVN" mkdir temp

if [ "$1" == "move" ]; then
    # Move
    "$SVN" mv dir temp/file
elif [ "$1" == "copy" ]; then
    # Copy and remove
    "$SVN" cp dir temp/file
    "$SVN" rm dir
else
    # Remove first and then copy
    "$SVN" rm dir
    "$SVN" cp dir@BASE temp/file
fi

"$SVN" mv temp dir

# Commit r2
"$SVN" ci -m 'Replace file called dir with an actual dir called dir'

"$SVN" up

"$SVN" info "file://$REPO/dir"@1  # File cannot be info-ed

]]]

Nathan

Re: Cannot get info for a file that was inside of file-replaced directory

Posted by Nathan Hartman <ha...@gmail.com>.
On Mon, Nov 25, 2019 at 12:03 PM Julian Foad <ju...@apache.org> wrote:
>
> TL;DR: Fixed and nominated for backport.

Thank you!!

More below...

> > (2) Alternately, perhaps svn_client_info4() should remain as-is and
> >      instead same_resource_in_head() should change: Maybe under certain
> >      conditions that currently return an error, it should instead
> >      set *same_p = FALSE and return SVN_NO_ERROR?
>
> Yes, (2): it already checks for two error codes:
>
>        ((err->apr_err == SVN_ERR_CLIENT_UNRELATED_RESOURCES) ||
>         (err->apr_err == SVN_ERR_FS_NOT_FOUND)))
>
> we need to add:
>
>         (err->apr_err == SVN_ERR_FS_NOT_DIRECTORY) ||
>
> Fixed: http://svn.apache.org/r1870395
>
> This does beg the question of what is the total set of possible failure
> modes that should be handled the same way.

I went through the list of error in svn_error_codes.h one by one and
two possibilities came to mind:

The first is SVN_ERR_FS_NOT_FILE. I wonder if this code would appear
and cause a failure if a similar test is run, but replacing a file
with a directory instead of replacing a directory with a file... I'll
test that scenario a little later...

The second possibility has to do with authz somehow causing a same-
resource check to fail (object accessible in old revision but not new
revision). I suppose that under this scenario, the error message would
say something to that effect.

Nathan

Re: Cannot get info for a file that was inside of file-replaced directory

Posted by Julian Foad <ju...@apache.org>.
TL;DR: Fixed and nominated for backport.


I see it was a change I made that broke this case.

Filed as: http://subversion.apache.org/issue/4837

Test added: http://svn.apache.org/r1870393

More below...

Nathan Hartman wrote:
[...]
> (1) This line in svn_client_info4():
> 
>    SVN_ERR(same_resource_in_head(&related, pathrev->url, pathrev->rev,
>                                  ra_session, ctx, pool));
> 
>      would terminate if any error occurs in same_resource_in_head().
>      Perhaps we should: check the specific error code; consider certain
>      error codes as signifying that the object is not locked, set
>      lock = NULL, and proceed?
> 
> (2) Alternately, perhaps svn_client_info4() should remain as-is and
>      instead same_resource_in_head() should change: Maybe under certain
>      conditions that currently return an error, it should instead
>      set *same_p = FALSE and return SVN_NO_ERROR?

Yes, (2): it already checks for two error codes:

       ((err->apr_err == SVN_ERR_CLIENT_UNRELATED_RESOURCES) ||
        (err->apr_err == SVN_ERR_FS_NOT_FOUND)))

we need to add:

        (err->apr_err == SVN_ERR_FS_NOT_DIRECTORY) ||

Fixed: http://svn.apache.org/r1870395

This does beg the question of what is the total set of possible failure 
modes that should be handled the same way.

We really ought to:
   * do random testing (svn info on all sorts of combinations of paths)
   * group error codes better so we don't have to guess what ones to expect

> (4) Optimization: Currently same_resource_in_head() is being called
>      unconditionally. Perhaps this should not be called at all if there
>      are no locks?

Someone could look into the pros and cons of switching the order (query 
for locks first, then check relatedness) as a separate exercise.  We 
currently have no indication that would be an optimization in general; 
it would be different in different cases.  There are cases like 
recursive info request to consider.  It doesn't sound like a priority.


While those follow-ups remain possible, the basic issue is fixed.

Nominated for backport to 1.10 and 1.13.

- Julian

Re: Cannot get info for a file that was inside of file-replaced directory

Posted by Nathan Hartman <ha...@gmail.com>.
On Fri, Nov 22, 2019 at 2:00 PM Daniel Shahaf <d....@daniel.shahaf.name> wrote:
> Let's continue the discussion on dev@.  [Moved from users@]

I didn't (much) get into the code yet except for a quick skim through
svn_client_info4().

If my understanding is correct, the change in r1823327 has to do
solely with reporting about locks.

Prior to r1823327, 'svn info' on an old revision could spend
significant time to determine if an object in question is the same as
an object in HEAD, in which case it would check if a lock applies to
the object.

The performance was sped up considerably by changing the search
direction for the "same object" check. But as Ivan points out, under
whatever set of circumstances (such as those exposed by Ivan's repro
script), a replaced object is no longer found by 'svn info' with a peg
revision:

$ svn info "$repo/dir/file"@1
svn: E160016: Failure opening '/dir' in revision 2
svn: E160016: '/dir' is not a directory in filesystem '(snip)'

My initial thoughts (I have NOT yet tested any of these):

(1) This line in svn_client_info4():

  SVN_ERR(same_resource_in_head(&related, pathrev->url, pathrev->rev,
                                ra_session, ctx, pool));

    would terminate if any error occurs in same_resource_in_head().
    Perhaps we should: check the specific error code; consider certain
    error codes as signifying that the object is not locked, set
    lock = NULL, and proceed?

(2) Alternately, perhaps svn_client_info4() should remain as-is and
    instead same_resource_in_head() should change: Maybe under certain
    conditions that currently return an error, it should instead
    set *same_p = FALSE and return SVN_NO_ERROR?

(3) If all else fails, an admittedly naive and kludgy fix might be to
    try the "new fast" search first; if it fails, fall back on the
    "old slow" search? Generally I *really* don't like to introduce a
    kludge unless as a last resort so hopefully there is a better way.

(4) Optimization: Currently same_resource_in_head() is being called
    unconditionally. Perhaps this should not be called at all if there
    are no locks?

> P.S. Nathan, are you aware of this syntax? — «svn log --diff -x-wp -c r1823327»

I actually never noticed that 'svn log' has a --diff option!! Thanks
for mentioning that!

Nathan

Re: Cannot get info for a file that was inside of file-replaced directory

Posted by Daniel Shahaf <d....@daniel.shahaf.name>.
Let's continue the discussion on dev@.  [Moved from users@]

Ivan, would you like to write a regression test for this?  See
subversion/tests/cmdline/info_tests.py.

Cheers,

Daniel

P.S. Nathan, are you aware of this syntax? — «svn log --diff -x-wp -c r1823327»


Nathan Hartman wrote on Fri, Nov 22, 2019 at 01:01:56 -0500:
> On Tue, Nov 19, 2019 at 12:03 AM Nathan Hartman <ha...@gmail.com>
> wrote:
> > On Mon, Nov 18, 2019 at 4:53 AM Иван Селин <iv...@yandex-team.ru> wrote:
> >> Sample reproduction script attached.
> >
> >
> > Hello Ivan,
> >
> > Thank you for reporting this.
> >
> > I performed similar steps and I am seeing the same result, namely:
> >
> > $ svn info "$repo/dir/file"@1
> > svn: E160016: Failure opening '/dir' in revision 2
> > svn: E160016: '/dir' is not a directory in filesystem '(snip)'
> >
> > You asked for peg revision 1, it's looking in revision 2.
> >
> > I'm investigating...
> 
> Hello Ivan,
> 
> Update: This bug was introduced in r1823327.
> 
> I don't have a fix yet but at least we know where it is now.
> 
> The last command in your reproduction script:
> 'svn info "file://$REPO/dir/file"@1'
> works correctly in r1823326, fails in r1823327:
> 
> [[[
> 
> $ svn log -r 1823327
> ------------------------------------------------------------------------
> r1823327 | julianfoad | 2018-02-06 08:44:17 -0500 (Tue, 06 Feb 2018) | 21
> lines
> 
> Performance: Make the 'info' command fast on old repository revisions.
> 
> The svn_client_info4() API reports the lock status of the given URL (at
> head, implicitly) if that is the same resource as the given URL and
> revision. The 'same resource' check was inefficient, searching history
> forwards from the given revision up to head.
> 
> The problem was present even when a peg revision is specified and even when
> the 'svn info --show-item=x' option is used. (The 'show-item' filtering is
> not performed in the library.)
> 
> Example: 'svn info https://svn.apache.org/repos/asf/subversion@850000'
> took 13s before and 2s after this change.
> 
> See http://colabti.org/irclogger/irclogger_log/svn-dev?date=2018-02-06#l11
> 
> * subversion/libsvn_client/info.c
>   (same_resource_in_head): Search history backwards instead of forward.
> 
> Found by: jcorvel
> 
> $ svn diff -x-wp -r 1823326:1823327
> Index: subversion/libsvn_client/info.c
> ===================================================================
> --- subversion/libsvn_client/info.c (revision 1823326)
> +++ subversion/libsvn_client/info.c (revision 1823327)
> @@ -253,17 +253,17 @@ same_resource_in_head(svn_boolean_t *same_p,
>                        apr_pool_t *pool)
>  {
>    svn_error_t *err;
> -  svn_opt_revision_t start_rev, peg_rev;
> +  svn_opt_revision_t operative_rev, peg_rev;
>    const char *head_url;
> 
> -  start_rev.kind = svn_opt_revision_head;
> -  peg_rev.kind = svn_opt_revision_number;
> -  peg_rev.value.number = rev;
> +  peg_rev.kind = svn_opt_revision_head;
> +  operative_rev.kind = svn_opt_revision_number;
> +  operative_rev.value.number = rev;
> 
>    err = svn_client__repos_locations(&head_url, NULL, NULL, NULL,
>                                      ra_session,
>                                      url, &peg_rev,
> -                                    &start_rev, NULL,
> +                                    &operative_rev, NULL,
>                                      ctx, pool);
>    if (err &&
>        ((err->apr_err == SVN_ERR_CLIENT_UNRELATED_RESOURCES) ||
> 
> ]]]
> 
> I modified your reproduction script a little and ran a bisect using
> https://metacpan.org/pod/distribution/App-SVN-Bisect/bin/svn-bisect.
> (Excuse the hard-coded paths.)
> 
> [[[
> 
> #!/bin/bash
> 
> SVN=/home/nate/ramdrive/svn-trunk/subversion/svn/svn
> SVNADMIN=/home/nate/ramdrive/svn-trunk/subversion/svnadmin/svnadmin
> 
> REPO="/home/nate/ramdrive/repo"
> WC="/home/nate/ramdrive/wc"
> 
> rm -rf "$REPO"
> rm -rf "$WC"
> 
> "$SVNADMIN" create "$REPO"
> "$SVN" checkout "file://$REPO" "$WC"
> cd "$WC"
> 
> mkdir dir
> echo text > dir/file
> "$SVN" add dir
> 
> # Commit r1
> "$SVN" ci -m 'Add file'
> 
> "$SVN" cp dir/file file-moved
> "$SVN" rm dir
> echo replaced > dir
> "$SVN" add dir
> 
> # Commit r2
> "$SVN" ci -m 'Replace dir with file'
> 
> "$SVN" up
> 
> # The moment of truth
> "$SVN" info "file://$REPO/dir/file"@1
> 
> ]]]
> 
> Nathan

Re: Cannot get info for a file that was inside of file-replaced directory

Posted by Daniel Shahaf <d....@daniel.shahaf.name>.
Let's continue the discussion on dev@.  [Moved from users@]

Ivan, would you like to write a regression test for this?  See
subversion/tests/cmdline/info_tests.py.

Cheers,

Daniel

P.S. Nathan, are you aware of this syntax? — «svn log --diff -x-wp -c r1823327»


Nathan Hartman wrote on Fri, Nov 22, 2019 at 01:01:56 -0500:
> On Tue, Nov 19, 2019 at 12:03 AM Nathan Hartman <ha...@gmail.com>
> wrote:
> > On Mon, Nov 18, 2019 at 4:53 AM Иван Селин <iv...@yandex-team.ru> wrote:
> >> Sample reproduction script attached.
> >
> >
> > Hello Ivan,
> >
> > Thank you for reporting this.
> >
> > I performed similar steps and I am seeing the same result, namely:
> >
> > $ svn info "$repo/dir/file"@1
> > svn: E160016: Failure opening '/dir' in revision 2
> > svn: E160016: '/dir' is not a directory in filesystem '(snip)'
> >
> > You asked for peg revision 1, it's looking in revision 2.
> >
> > I'm investigating...
> 
> Hello Ivan,
> 
> Update: This bug was introduced in r1823327.
> 
> I don't have a fix yet but at least we know where it is now.
> 
> The last command in your reproduction script:
> 'svn info "file://$REPO/dir/file"@1'
> works correctly in r1823326, fails in r1823327:
> 
> [[[
> 
> $ svn log -r 1823327
> ------------------------------------------------------------------------
> r1823327 | julianfoad | 2018-02-06 08:44:17 -0500 (Tue, 06 Feb 2018) | 21
> lines
> 
> Performance: Make the 'info' command fast on old repository revisions.
> 
> The svn_client_info4() API reports the lock status of the given URL (at
> head, implicitly) if that is the same resource as the given URL and
> revision. The 'same resource' check was inefficient, searching history
> forwards from the given revision up to head.
> 
> The problem was present even when a peg revision is specified and even when
> the 'svn info --show-item=x' option is used. (The 'show-item' filtering is
> not performed in the library.)
> 
> Example: 'svn info https://svn.apache.org/repos/asf/subversion@850000'
> took 13s before and 2s after this change.
> 
> See http://colabti.org/irclogger/irclogger_log/svn-dev?date=2018-02-06#l11
> 
> * subversion/libsvn_client/info.c
>   (same_resource_in_head): Search history backwards instead of forward.
> 
> Found by: jcorvel
> 
> $ svn diff -x-wp -r 1823326:1823327
> Index: subversion/libsvn_client/info.c
> ===================================================================
> --- subversion/libsvn_client/info.c (revision 1823326)
> +++ subversion/libsvn_client/info.c (revision 1823327)
> @@ -253,17 +253,17 @@ same_resource_in_head(svn_boolean_t *same_p,
>                        apr_pool_t *pool)
>  {
>    svn_error_t *err;
> -  svn_opt_revision_t start_rev, peg_rev;
> +  svn_opt_revision_t operative_rev, peg_rev;
>    const char *head_url;
> 
> -  start_rev.kind = svn_opt_revision_head;
> -  peg_rev.kind = svn_opt_revision_number;
> -  peg_rev.value.number = rev;
> +  peg_rev.kind = svn_opt_revision_head;
> +  operative_rev.kind = svn_opt_revision_number;
> +  operative_rev.value.number = rev;
> 
>    err = svn_client__repos_locations(&head_url, NULL, NULL, NULL,
>                                      ra_session,
>                                      url, &peg_rev,
> -                                    &start_rev, NULL,
> +                                    &operative_rev, NULL,
>                                      ctx, pool);
>    if (err &&
>        ((err->apr_err == SVN_ERR_CLIENT_UNRELATED_RESOURCES) ||
> 
> ]]]
> 
> I modified your reproduction script a little and ran a bisect using
> https://metacpan.org/pod/distribution/App-SVN-Bisect/bin/svn-bisect.
> (Excuse the hard-coded paths.)
> 
> [[[
> 
> #!/bin/bash
> 
> SVN=/home/nate/ramdrive/svn-trunk/subversion/svn/svn
> SVNADMIN=/home/nate/ramdrive/svn-trunk/subversion/svnadmin/svnadmin
> 
> REPO="/home/nate/ramdrive/repo"
> WC="/home/nate/ramdrive/wc"
> 
> rm -rf "$REPO"
> rm -rf "$WC"
> 
> "$SVNADMIN" create "$REPO"
> "$SVN" checkout "file://$REPO" "$WC"
> cd "$WC"
> 
> mkdir dir
> echo text > dir/file
> "$SVN" add dir
> 
> # Commit r1
> "$SVN" ci -m 'Add file'
> 
> "$SVN" cp dir/file file-moved
> "$SVN" rm dir
> echo replaced > dir
> "$SVN" add dir
> 
> # Commit r2
> "$SVN" ci -m 'Replace dir with file'
> 
> "$SVN" up
> 
> # The moment of truth
> "$SVN" info "file://$REPO/dir/file"@1
> 
> ]]]
> 
> Nathan

Re: Cannot get info for a file that was inside of file-replaced directory

Posted by Nathan Hartman <ha...@gmail.com>.
On Tue, Nov 19, 2019 at 12:03 AM Nathan Hartman <ha...@gmail.com>
wrote:
>
> On Mon, Nov 18, 2019 at 4:53 AM Иван Селин <iv...@yandex-team.ru>
wrote:
>>
>> Hi!
>>
>> I think I've found a bug in subversion client. Setup is as follows:
>> 1. Create directory with a file in it — commit 1
>> 2. Replace directory with other file — commit 2
>> 3. Call "svn info dir/file@1" — it should give information about
dir/file at revision 1, but it fails saying that "dir" is a file at latest
revision:
>>
>> svn: E160016: Failure opening '/dir' in revision 2
>> svn: E160016: '/dir' is not a directory in filesystem
'0bc899d5-c233-4fed-98a3-8705ddfc96c4'
>> But directory can be listed, it shows the file, and file can be listed
too:
>>   $ svn info file:///tmp/subversion-info-on-replaced-file/repo/dir@1
>> Path: dir
>> URL: file:///tmp/subversion-info-on-replaced-file/repo/dir
>> Relative URL: ^/dir
>> Repository Root: file:///tmp/subversion-info-on-replaced-file/repo
>> Repository UUID: 0bc899d5-c233-4fed-98a3-8705ddfc96c4
>> Revision: 1
>> Node Kind: directory
>> Last Changed Author: ivanselin
>> Last Changed Rev: 1
>> Last Changed Date: 2019-11-18 11:38:16 +0300 (Пн, 18 ноя 2019)
>>
>>   $ svn list file:///tmp/subversion-info-on-replaced-file/repo/dir@1
>> file
>>   $ svn list file:///tmp/subversion-info-on-replaced-file/repo/dir/file@1
>> file
>>
>> So, only "info" does not work. It seems that it's performing directory
check against HEAD instead of provided peg revision. Adding --revision key
changes nothing. This is trunk svn (1.14.0-dev, r1869957), svn 1.9.7 does
not have this bug, it correctly shows info.
>>
>> Sample reproduction script attached.
>
>
> Hello Ivan,
>
> Thank you for reporting this.
>
> I performed similar steps and I am seeing the same result, namely:
>
> $ svn info "$repo/dir/file"@1
> svn: E160016: Failure opening '/dir' in revision 2
> svn: E160016: '/dir' is not a directory in filesystem '(snip)'
>
> You asked for peg revision 1, it's looking in revision 2.
>
> I'm investigating...

Hello Ivan,

Update: This bug was introduced in r1823327.

I don't have a fix yet but at least we know where it is now.

The last command in your reproduction script:
'svn info "file://$REPO/dir/file"@1'
works correctly in r1823326, fails in r1823327:

[[[

$ svn log -r 1823327
------------------------------------------------------------------------
r1823327 | julianfoad | 2018-02-06 08:44:17 -0500 (Tue, 06 Feb 2018) | 21
lines

Performance: Make the 'info' command fast on old repository revisions.

The svn_client_info4() API reports the lock status of the given URL (at
head, implicitly) if that is the same resource as the given URL and
revision. The 'same resource' check was inefficient, searching history
forwards from the given revision up to head.

The problem was present even when a peg revision is specified and even when
the 'svn info --show-item=x' option is used. (The 'show-item' filtering is
not performed in the library.)

Example: 'svn info https://svn.apache.org/repos/asf/subversion@850000'
took 13s before and 2s after this change.

See http://colabti.org/irclogger/irclogger_log/svn-dev?date=2018-02-06#l11

* subversion/libsvn_client/info.c
  (same_resource_in_head): Search history backwards instead of forward.

Found by: jcorvel

$ svn diff -x-wp -r 1823326:1823327
Index: subversion/libsvn_client/info.c
===================================================================
--- subversion/libsvn_client/info.c (revision 1823326)
+++ subversion/libsvn_client/info.c (revision 1823327)
@@ -253,17 +253,17 @@ same_resource_in_head(svn_boolean_t *same_p,
                       apr_pool_t *pool)
 {
   svn_error_t *err;
-  svn_opt_revision_t start_rev, peg_rev;
+  svn_opt_revision_t operative_rev, peg_rev;
   const char *head_url;

-  start_rev.kind = svn_opt_revision_head;
-  peg_rev.kind = svn_opt_revision_number;
-  peg_rev.value.number = rev;
+  peg_rev.kind = svn_opt_revision_head;
+  operative_rev.kind = svn_opt_revision_number;
+  operative_rev.value.number = rev;

   err = svn_client__repos_locations(&head_url, NULL, NULL, NULL,
                                     ra_session,
                                     url, &peg_rev,
-                                    &start_rev, NULL,
+                                    &operative_rev, NULL,
                                     ctx, pool);
   if (err &&
       ((err->apr_err == SVN_ERR_CLIENT_UNRELATED_RESOURCES) ||

]]]

I modified your reproduction script a little and ran a bisect using
https://metacpan.org/pod/distribution/App-SVN-Bisect/bin/svn-bisect.
(Excuse the hard-coded paths.)

[[[

#!/bin/bash

SVN=/home/nate/ramdrive/svn-trunk/subversion/svn/svn
SVNADMIN=/home/nate/ramdrive/svn-trunk/subversion/svnadmin/svnadmin

REPO="/home/nate/ramdrive/repo"
WC="/home/nate/ramdrive/wc"

rm -rf "$REPO"
rm -rf "$WC"

"$SVNADMIN" create "$REPO"
"$SVN" checkout "file://$REPO" "$WC"
cd "$WC"

mkdir dir
echo text > dir/file
"$SVN" add dir

# Commit r1
"$SVN" ci -m 'Add file'

"$SVN" cp dir/file file-moved
"$SVN" rm dir
echo replaced > dir
"$SVN" add dir

# Commit r2
"$SVN" ci -m 'Replace dir with file'

"$SVN" up

# The moment of truth
"$SVN" info "file://$REPO/dir/file"@1

]]]

Nathan

Re: Cannot get info for a file that was inside of file-replaced directory

Posted by Nathan Hartman <ha...@gmail.com>.
On Mon, Nov 18, 2019 at 4:53 AM Иван Селин <iv...@yandex-team.ru> wrote:

> Hi!
>
> I think I've found a bug in subversion client. Setup is as follows:
> 1. Create directory with a file in it — commit 1
> 2. Replace directory with other file — commit 2
> 3. Call "svn info dir/file@1" — it should give information about dir/file
> at revision 1, but it fails saying that "dir" is a file at latest revision:
>
> svn: E160016: Failure opening '/dir' in revision 2
> svn: E160016: '/dir' is not a directory in filesystem
> '0bc899d5-c233-4fed-98a3-8705ddfc96c4'
> But directory can be listed, it shows the file, and file can be listed too:
>   $ svn info file:///tmp/subversion-info-on-replaced-file/repo/dir@1
> Path: dir
> URL: file:///tmp/subversion-info-on-replaced-file/repo/dir
> Relative URL: ^/dir
> Repository Root: file:///tmp/subversion-info-on-replaced-file/repo
> Repository UUID: 0bc899d5-c233-4fed-98a3-8705ddfc96c4
> Revision: 1
> Node Kind: directory
> Last Changed Author: ivanselin
> Last Changed Rev: 1
> Last Changed Date: 2019-11-18 11:38:16 +0300 (Пн, 18 ноя 2019)
>
>   $ svn list file:///tmp/subversion-info-on-replaced-file/repo/dir@1
> file
>   $ svn list file:///tmp/subversion-info-on-replaced-file/repo/dir/file@1
> file
>
> So, only "info" does not work. It seems that it's performing directory
> check against HEAD instead of provided peg revision. Adding --revision key
> changes nothing. This is trunk svn (1.14.0-dev, r1869957), svn 1.9.7 does
> not have this bug, it correctly shows info.
>
> Sample reproduction script attached.
>

Hello Ivan,

Thank you for reporting this.

I performed similar steps and I am seeing the same result, namely:

$ svn info "$repo/dir/file"@1
svn: E160016: Failure opening '/dir' in revision 2
svn: E160016: '/dir' is not a directory in filesystem '(snip)'

You asked for peg revision 1, it's looking in revision 2.

I'm investigating...

Thanks again for reporting this.

Nathan

Re: Cannot get info for a file that was inside of file-replaced directory

Posted by Иван Селин <iv...@yandex-team.ru>.
Hi, Eric!

I think svn log -v is correct as it shows that /dir in commit 2 was replaced,
i.e. removed and added:

$ svn log -v file://$repo/dir

\------------------------------------------------------------------------

r2 | ivanselin | 2019-11-19 08:34:37 +0300 (Tue, 19 Nov 2019) | 1 line

Changed paths:

R /dir

A /file-moved (from /dir/file:1)

Replace dir with file

\------------------------------------------------------------------------

But yeah, some commands do work correctly, it's weird.

Regards,

Ivan.

18.11.2019, 20:03, "Eric Johnson" <er...@tibco.com>:

> Interesting.

>

> It appears that svn ls of "dir@1" works fine. As does svn cat of
"dir/file@1". svn proplist of "dir/file@1" appears to work as well.

>

> svn log -v appears to be incomplete, as it shows "dir" removed, but not also
added in the revision.

>

> svn info fails, as you note.

>

> Looks like a bug to me.

>

> Eric.

>

> On Mon, Nov 18, 2019 at 1:53 AM Иван Селин <[ivanselin@yandex-
team.ru](mailto:ivanselin@yandex-team.ru)> wrote:

>

>> Hi!

>>

>> I think I've found a bug in subversion client. Setup is as follows:

>>

>> 1\. Create directory with a file in it — commit 1

>>

>> 2\. Replace directory with other file — commit 2

>>

>> 3\. Call "svn info dir/file@1" — it should give information about dir/file
at revision 1, but it fails saying that "dir" is a file at latest revision:

>>

>> svn: E160016: Failure opening '/dir' in revision 2

>>

>> svn: E160016: '/dir' is not a directory in filesystem
'0bc899d5-c233-4fed-98a3-8705ddfc96c4'

>>

>> But directory can be listed, it shows the file, and file can be listed too:

>>

>> $ svn info file:///tmp/subversion-info-on-replaced-file/repo/dir@1

>>

>> Path: dir

>>

>> URL: file:///tmp/subversion-info-on-replaced-file/repo/dir

>>

>> Relative URL: ^/dir

>>

>> Repository Root: file:///tmp/subversion-info-on-replaced-file/repo

>>

>> Repository UUID: 0bc899d5-c233-4fed-98a3-8705ddfc96c4

>>

>> Revision: 1

>>

>> Node Kind: directory

>>

>> Last Changed Author: ivanselin

>>

>> Last Changed Rev: 1

>>

>> Last Changed Date: 2019-11-18 11:38:16 +0300 (Пн, 18 ноя 2019)

>>

>> $ svn list file:///tmp/subversion-info-on-replaced-file/repo/dir@1

>>

>> file

>>

>> $ svn list file:///tmp/subversion-info-on-replaced-file/repo/dir/file@1

>>

>> file

>>

>> So, only "info" does not work. It seems that it's performing directory
check against HEAD instead of provided peg revision. Adding --revision key
changes nothing. This is trunk svn (1.14.0-dev, r1869957), svn 1.9.7 does not
have this bug, it correctly shows info.

>>

>> Sample reproduction script attached.

>>

>> Regards,

>>

>> Ivan.


Re: Cannot get info for a file that was inside of file-replaced directory

Posted by Eric Johnson <er...@tibco.com>.
Interesting.

It appears that svn ls of "dir@1" works fine. As does svn cat of "dir/file@1".
svn proplist of "dir/file@1" appears to work as well.

svn log -v appears to be incomplete, as it shows "dir" removed, but not
also added in the revision.

svn info fails, as you note.

Looks like a bug to me.

Eric.


On Mon, Nov 18, 2019 at 1:53 AM Иван Селин <iv...@yandex-team.ru> wrote:

> Hi!
>
> I think I've found a bug in subversion client. Setup is as follows:
> 1. Create directory with a file in it — commit 1
> 2. Replace directory with other file — commit 2
> 3. Call "svn info dir/file@1" — it should give information about dir/file
> at revision 1, but it fails saying that "dir" is a file at latest revision:
>
> svn: E160016: Failure opening '/dir' in revision 2
> svn: E160016: '/dir' is not a directory in filesystem
> '0bc899d5-c233-4fed-98a3-8705ddfc96c4'
> But directory can be listed, it shows the file, and file can be listed too:
>   $ svn info file:///tmp/subversion-info-on-replaced-file/repo/dir@1
> Path: dir
> URL: file:///tmp/subversion-info-on-replaced-file/repo/dir
> Relative URL: ^/dir
> Repository Root: file:///tmp/subversion-info-on-replaced-file/repo
> Repository UUID: 0bc899d5-c233-4fed-98a3-8705ddfc96c4
> Revision: 1
> Node Kind: directory
> Last Changed Author: ivanselin
> Last Changed Rev: 1
> Last Changed Date: 2019-11-18 11:38:16 +0300 (Пн, 18 ноя 2019)
>
>   $ svn list file:///tmp/subversion-info-on-replaced-file/repo/dir@1
> file
>   $ svn list file:///tmp/subversion-info-on-replaced-file/repo/dir/file@1
> file
>
> So, only "info" does not work. It seems that it's performing directory
> check against HEAD instead of provided peg revision. Adding --revision key
> changes nothing. This is trunk svn (1.14.0-dev, r1869957), svn 1.9.7 does
> not have this bug, it correctly shows info.
>
> Sample reproduction script attached.
>
> Regards,
> Ivan.
>