svn status merges intersected external records into single row

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

svn status merges intersected external records into single row

Andry
Here is the batch script for the windows:

```
@echo off

set REPODIR=test_repo
set "REPOROOT=%~dp0%REPODIR%"
set "REPOURL=file:///%REPOROOT:\=/%"
set WCROOT=%REPODIR%_root

if exist "%REPOROOT%\" rmdir /S /Q "%REPOROOT%"
if exist "%WCROOT%\" rmdir /S /Q "%WCROOT%"

mkdir "%REPOROOT%"
svnadmin create "%REPOROOT%"
mkdir "%WCROOT%"

svn co "%REPOURL%" "%WCROOT%"

rem creating tree w/o externals
mkdir "%WCROOT%/dir1/dir1_subdir1" || goto :EOF
mkdir "%WCROOT%/dir1/dir1_subdir2" || goto :EOF
mkdir "%WCROOT%/dir2/dir2_subdir1" || goto :EOF
mkdir "%WCROOT%/dir2/dir2_subdir2" || goto :EOF

svn add "%WCROOT%/*.*" || goto :EOF

svn ci "%WCROOT%" -m "rev1" || goto :EOF

rem update to the head
svn up "%WCROOT%" || goto :EOF

rem creating externals
type nul > "$externals.txt"

(
   echo.^^/dir1/dir1_subdir1 ext/dir1_subdir1
   echo.^^/dir1/dir1_subdir2 ext/dir1_subdir2
   echo.^^/dir2/dir2_subdir1 dir2_subdir1
   echo.^^/dir2/dir2_subdir2 dir2_subdir2
) >> "$externals.txt"

svn pset svn:externals -F "$externals.txt" "%WCROOT%" || goto :EOF

svn ci "%WCROOT%" -m "rev2" || goto :EOF

rem update to the head
svn up "%WCROOT%" || goto :EOF

rem show status
svn status "%WCROOT%"
```

The output:

```
Checked out revision 0.
svn: Skipping argument: E200025: 'test_repo_root/.svn' ends in a reserved  
name
A         test_repo_root\dir1
A         test_repo_root\dir1\dir1_subdir1
A         test_repo_root\dir1\dir1_subdir2
A         test_repo_root\dir2
A         test_repo_root\dir2\dir2_subdir1
A         test_repo_root\dir2\dir2_subdir2
Adding         test_repo_root\dir1
Adding         test_repo_root\dir1\dir1_subdir1
Adding         test_repo_root\dir1\dir1_subdir2
Adding         test_repo_root\dir2
Adding         test_repo_root\dir2\dir2_subdir1
Adding         test_repo_root\dir2\dir2_subdir2
Committing transaction...
Committed revision 1.
Updating 'test_repo_root':
At revision 1.
property 'svn:externals' set on 'test_repo_root'
Sending        test_repo_root
Committing transaction...
Committed revision 2.
Updating 'test_repo_root':

Fetching external item into 'test_repo_root\ext\dir1_subdir1':
External at revision 2.


Fetching external item into 'test_repo_root\ext\dir1_subdir2':
External at revision 2.


Fetching external item into 'test_repo_root\dir2_subdir1':
External at revision 2.


Fetching external item into 'test_repo_root\dir2_subdir2':
External at revision 2.

At revision 2.
X       test_repo_root\dir2_subdir1
X       test_repo_root\dir2_subdir2
X       test_repo_root\ext

Performing status on external item at 'test_repo_root\dir2_subdir1':

Performing status on external item at 'test_repo_root\dir2_subdir2':

Performing status on external item at 'test_repo_root\ext\dir1_subdir1':

Performing status on external item at 'test_repo_root\ext\dir1_subdir2':
```

The externals list is:

```
X       test_repo_root\dir2_subdir1
X       test_repo_root\dir2_subdir2
X       test_repo_root\ext
```

instead of:

```
X       test_repo_root\dir2_subdir1
X       test_repo_root\dir2_subdir2
X       test_repo_root\ext\dir1_subdir1
X       test_repo_root\ext\dir1_subdir2
```

This forces to use `svn pget svn:externals` + `a parser` instead of `svn  
status` + `a filter` in scripting to extract the records set.
Reply | Threaded
Open this post in threaded view
|

Re: svn status merges intersected external records into single row

Johan Corveleyn-3
On Tue, Jun 13, 2017 at 3:47 PM, Andrey <[hidden email]> wrote:

> Here is the batch script for the windows:
>
> ```
> @echo off
>
> set REPODIR=test_repo
> set "REPOROOT=%~dp0%REPODIR%"
> set "REPOURL=file:///%REPOROOT:\=/%"
> set WCROOT=%REPODIR%_root
>
> if exist "%REPOROOT%\" rmdir /S /Q "%REPOROOT%"
> if exist "%WCROOT%\" rmdir /S /Q "%WCROOT%"
>
> mkdir "%REPOROOT%"
> svnadmin create "%REPOROOT%"
> mkdir "%WCROOT%"
>
> svn co "%REPOURL%" "%WCROOT%"
>
> rem creating tree w/o externals
> mkdir "%WCROOT%/dir1/dir1_subdir1" || goto :EOF
> mkdir "%WCROOT%/dir1/dir1_subdir2" || goto :EOF
> mkdir "%WCROOT%/dir2/dir2_subdir1" || goto :EOF
> mkdir "%WCROOT%/dir2/dir2_subdir2" || goto :EOF
>
> svn add "%WCROOT%/*.*" || goto :EOF
>
> svn ci "%WCROOT%" -m "rev1" || goto :EOF
>
> rem update to the head
> svn up "%WCROOT%" || goto :EOF
>
> rem creating externals
> type nul > "$externals.txt"
>
> (
>   echo.^^/dir1/dir1_subdir1 ext/dir1_subdir1
>   echo.^^/dir1/dir1_subdir2 ext/dir1_subdir2
>   echo.^^/dir2/dir2_subdir1 dir2_subdir1
>   echo.^^/dir2/dir2_subdir2 dir2_subdir2
> ) >> "$externals.txt"
>
> svn pset svn:externals -F "$externals.txt" "%WCROOT%" || goto :EOF
>
> svn ci "%WCROOT%" -m "rev2" || goto :EOF
>
> rem update to the head
> svn up "%WCROOT%" || goto :EOF
>
> rem show status
> svn status "%WCROOT%"
> ```
>
> The output:
>
> ```
> Checked out revision 0.
> svn: Skipping argument: E200025: 'test_repo_root/.svn' ends in a reserved
> name
> A         test_repo_root\dir1
> A         test_repo_root\dir1\dir1_subdir1
> A         test_repo_root\dir1\dir1_subdir2
> A         test_repo_root\dir2
> A         test_repo_root\dir2\dir2_subdir1
> A         test_repo_root\dir2\dir2_subdir2
> Adding         test_repo_root\dir1
> Adding         test_repo_root\dir1\dir1_subdir1
> Adding         test_repo_root\dir1\dir1_subdir2
> Adding         test_repo_root\dir2
> Adding         test_repo_root\dir2\dir2_subdir1
> Adding         test_repo_root\dir2\dir2_subdir2
> Committing transaction...
> Committed revision 1.
> Updating 'test_repo_root':
> At revision 1.
> property 'svn:externals' set on 'test_repo_root'
> Sending        test_repo_root
> Committing transaction...
> Committed revision 2.
> Updating 'test_repo_root':
>
> Fetching external item into 'test_repo_root\ext\dir1_subdir1':
> External at revision 2.
>
>
> Fetching external item into 'test_repo_root\ext\dir1_subdir2':
> External at revision 2.
>
>
> Fetching external item into 'test_repo_root\dir2_subdir1':
> External at revision 2.
>
>
> Fetching external item into 'test_repo_root\dir2_subdir2':
> External at revision 2.
>
> At revision 2.
> X       test_repo_root\dir2_subdir1
> X       test_repo_root\dir2_subdir2
> X       test_repo_root\ext
>
> Performing status on external item at 'test_repo_root\dir2_subdir1':
>
> Performing status on external item at 'test_repo_root\dir2_subdir2':
>
> Performing status on external item at 'test_repo_root\ext\dir1_subdir1':
>
> Performing status on external item at 'test_repo_root\ext\dir1_subdir2':
> ```
>
> The externals list is:
>
> ```
> X       test_repo_root\dir2_subdir1
> X       test_repo_root\dir2_subdir2
> X       test_repo_root\ext
> ```
>
> instead of:
>
> ```
> X       test_repo_root\dir2_subdir1
> X       test_repo_root\dir2_subdir2
> X       test_repo_root\ext\dir1_subdir1
> X       test_repo_root\ext\dir1_subdir2
> ```
>
> This forces to use `svn pget svn:externals` + `a parser` instead of `svn
> status` + `a filter` in scripting to extract the records set.

Hi Andrey,

I tried your repro script and I'm seeing the same. However, I'm not
sure whether this is a bug or not ... The 'ext' directory in your
example is an unversioned "intermediate" directory. It's supported,
but it's quite special (I've never used externals like that).

So what you're seeing is that 'svn status' only reports one single X
line for the entire "unversioned intermediate directory", even if
there are multiple externals below it.

Summarized, you're saying that with this svn:externals definition:

    ^/dir1/dir1_subdir1 ext/dir1_subdir1
    ^/dir1/dir1_subdir2 ext/dir1_subdir2

(with ext being an unversioned intermediate directory)
running 'svn status' only reports one X line (for 'ext') instead of a
line for each external definition (like it does with other externals):

    X       test_repo_root\ext


Strangely, if you define externals into a *versioned* subdir, it's
reported with two lines, as you expect:

(continuing from the result of your script)
[[[
svn mkdir ext2
svn ci -mm
svn up
# edit svn:externals property and add two more lines like the
ext-ones, with ext2.
svn ci -mm
svn up
svn st
]]]

Output of 'svn st':
X       dir2_subdir1
X       dir2_subdir2
X       ext
X       ext2\dir1_subdir1
X       ext2\dir1_subdir2


--
Johan
Reply | Threaded
Open this post in threaded view
|

Re: svn status merges intersected external records into single row

Daniel Shahaf-2
Johan Corveleyn wrote on Fri, 30 Jun 2017 00:06 +0200:

> Summarized, you're saying that with this svn:externals definition:
>
>     ^/dir1/dir1_subdir1 ext/dir1_subdir1
>     ^/dir1/dir1_subdir2 ext/dir1_subdir2
>
> (with ext being an unversioned intermediate directory)
> running 'svn status' only reports one X line (for 'ext') instead of a
> line for each external definition (like it does with other externals):
>
>     X       test_repo_root\ext

'ext' is not a file external and is not the root of a directory
external, so it shouldn't be printed with status 'X'; therefore this
output is a bug.

... Right?
Reply | Threaded
Open this post in threaded view
|

Re: svn status merges intersected external records into single row

Johan Corveleyn-3
On Fri, Jun 30, 2017 at 4:12 AM, Daniel Shahaf <[hidden email]> wrote:

> Johan Corveleyn wrote on Fri, 30 Jun 2017 00:06 +0200:
>> Summarized, you're saying that with this svn:externals definition:
>>
>>     ^/dir1/dir1_subdir1 ext/dir1_subdir1
>>     ^/dir1/dir1_subdir2 ext/dir1_subdir2
>>
>> (with ext being an unversioned intermediate directory)
>> running 'svn status' only reports one X line (for 'ext') instead of a
>> line for each external definition (like it does with other externals):
>>
>>     X       test_repo_root\ext
>
> 'ext' is not a file external and is not the root of a directory
> external, so it shouldn't be printed with status 'X'; therefore this
> output is a bug.
>
> ... Right?

Yeah, the more I think about it, the more I think it's a bug indeed.

--
Johan
Reply | Threaded
Open this post in threaded view
|

Re: svn status merges intersected external records into single row

Johan Corveleyn-3
On Fri, Jun 30, 2017 at 7:52 AM, Johan Corveleyn <[hidden email]> wrote:

> On Fri, Jun 30, 2017 at 4:12 AM, Daniel Shahaf <[hidden email]> wrote:
>> Johan Corveleyn wrote on Fri, 30 Jun 2017 00:06 +0200:
>>> Summarized, you're saying that with this svn:externals definition:
>>>
>>>     ^/dir1/dir1_subdir1 ext/dir1_subdir1
>>>     ^/dir1/dir1_subdir2 ext/dir1_subdir2
>>>
>>> (with ext being an unversioned intermediate directory)
>>> running 'svn status' only reports one X line (for 'ext') instead of a
>>> line for each external definition (like it does with other externals):
>>>
>>>     X       test_repo_root\ext
>>
>> 'ext' is not a file external and is not the root of a directory
>> external, so it shouldn't be printed with status 'X'; therefore this
>> output is a bug.
>>
>> ... Right?
>
> Yeah, the more I think about it, the more I think it's a bug indeed.

Apparently, it's not a bug, but is implemented explicitly this way.

Bert Huijben said the following about it on #svn-dev (irc):

[[[
<Bert> This feature was deliberately designed that way... I spend
quite some time to get that working again in WC-NG.

<Bert> I didn't know about that intermediate dir feature before that work on NG.

<Bert> That 'X' on the intermediate dir is produced to 'not show it as
unversioned dir'. Each and every (dir) external is reported separately
after the primary status output.

<jcorvel> Bert: X-feature ... strange. But the individual externals
below "unversioned" are not reported with 'X'. Is dat normal?

<jcorvel> Do you know why this feature was designed that way? Any way
to find out the rationale behind this? If we wanted to "not show it as
an unversioned dir" we might as well just have suppressed it ...

<Bert> We just don't recurse into unversioned dirs... we only show the root.

<jcorvel> Hm, okay, guess that makes sense from the status-walk logic
side of things ...

<jcorvel> it's still strange to see the unversioned
externals-parent-dir being reported with X ... as a user I'd expect
'X' to show the actual externals roots. Confusing ... but okay
]]]

Andrey, you might be able to parse the externals from the "Performing
status on external ..." lines as a workaround.

--
Johan
Reply | Threaded
Open this post in threaded view
|

Re: svn status merges intersected external records into single row

Andry
Hello Johan,

Friday, June 30, 2017, 11:20:11 PM, you wrote:

JC> Andrey, you might be able to parse the externals from the "Performing
JC> status on external ..." lines as a workaround.
It would be excessive that way. Better just to read the EXTERNALS
table from the wc.db directly.

--
Best regards,
 Andry                            mailto:[hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: svn status merges intersected external records into single row

Daniel Shahaf-2
Andry wrote on Sat, 01 Jul 2017 21:45 +0300:
> Hello Johan,
>
> Friday, June 30, 2017, 11:20:11 PM, you wrote:
>
> JC> Andrey, you might be able to parse the externals from the "Performing
> JC> status on external ..." lines as a workaround.
> It would be excessive that way. Better just to read the EXTERNALS
> table from the wc.db directly.

The db schema may change arbitrarily between versions.  If you insist
on this approach, the right way to do it is to check `pragma user_version;`
first and bail out if it's a newer value than your code knows how to handle.

The public API is what Johan suggested, or to use the libsvn_client bindings
in the language of your choice (C/java/python/perl/ruby).
Reply | Threaded
Open this post in threaded view
|

Re: svn status merges intersected external records into single row

Andry
Hello Daniel,

Sunday, July 2, 2017, 7:08:00 AM, you wrote:

DS> Andry wrote on Sat, 01 Jul 2017 21:45 +0300:
>> Hello Johan,
>>
>> Friday, June 30, 2017, 11:20:11 PM, you wrote:
>>
>> JC> Andrey, you might be able to parse the externals from the "Performing
>> JC> status on external ..." lines as a workaround.
>> It would be excessive that way. Better just to read the EXTERNALS
>> table from the wc.db directly.

DS> The db schema may change arbitrarily between versions.  If you insist
DS> on this approach, the right way to do it is to check `pragma user_version;`
DS> first and bail out if it's a newer value than your code knows how to handle.
Yes i know, thanx for the tip

--
Best regards,
 Andry                            mailto:[hidden email]