On Fri, Feb 11, 2022 at 09:22:25AM +0100, Martin Obermeir wrote: > Hi, > > When using `svn copy --pin-externals` to create a tag, svn:externals with a > relative path get pinned a non existing path: They get pinned to the > revision before the commit, but the path doesn't exist yet in that revision. > I expected them to be pinned to the revision which gets created during the > svn copy operation. > > In the example below: > actual result: A/D - ../B/lambda@2 lambda > expected result: A/D - ../B/lambda@3 lambda > > Please find the script to reproduce this attached. Commented excerpt: > > cd A/D/ > svn propset svn:externals "../B/lambda lambda" . # relative path > svn commit -m "msg1" # creates revision 2 > cd ../.. > svn copy --pin-externals ${URL}/trunk ${URL}/tags/pinnedExternals -m > "msg2" # creates revision 3 > svn switch ^/tags/pinnedExternals > # gives warnings: > # svn: warning: W205011: Error handling externals definition for > 'A/D/lambda': > # svn: warning: W170000: URL > 'file:///tmp/pinExternalsBug/repos/tags/pinnedExternals/A/B/lambda' at > revision 2 doesn't exist > svn propget -R svn:externals > # gives: A/D - ../B/lambda@2 lambda > # i.e. pinned to revision 2, but the path doesn't exist (created in > revision 3) > # I would expect: A/D - ../B/lambda@3 lambda > > > Tested on Kubuntu 20.04.3 LTS and SUSE Linux Enterprise Server 15 SP3 > (x86_64) with: > - todays trunk (Revision: 1897960): svn, version 1.15.0-dev (under > development) compiled Feb 11 2022, 08:01:11 on x86_64-pc-linux-gnu > - svn, version 1.14.1 (r1886195) > - svn, version 1.13.0 (r1867053) compiled Mar 24 2020, 12:33:36 on > x86_64-pc-linux-gnu > - svn, version 1.10.6 (r1863367) > > Best regards > Martin
Hi Martin, Thank you for this report. This is a problem which was already present in the commit which added this feature (https://svn.apache.org/r1659395). I am afraid it is impossible to implement a solution for the issue as you have presented it because your desired solution has an inherent chicken-and-egg problem: The external definition is created by the client as part of creating the new commit. At this time, the new revision number is not yet known. The client only learns about the new revision number after the commit has been created on the server. And the client must prepare properties which contain external definitions as part of creating the commit. So there is an inherent contradiction between the behaviour you would like to see and the way the system works internally. The revision number cannot even be inferred as something like HEAD+1 because the server can process commits from multiple clients in parallel while clients upload data, assigning a new number to whichever commit finishes first. The best suggestion I have is to only refer to already existing source paths in externals definitions added with your commit which creates your new tag. This means instead of using a relative external that points inside the path space of your new tag, use a path that points into trunk or some other branch where the same files and directories already exist. Because any tag created by a URL-URL copy is a copy of something that already exists somewhere else in the repository, this should always be possible, should it not? Once the tag has been created and the new revision number is known, you could then make a subsequent commit which manually pins the external to a path which now exists inside the tag's path space, if you prefer that. Does this make sense? The behaviour exposed by your script is certainly not ideal. In the URL-URL copy case the client does not check whether the pinned paths even exist! The client could at least check whether the path is is pinning does in fact exist. It could either error out if the path cannot be found, or simply leave the external alone and avoid pinning it. Verifying externals in general is not an easy problem. If an external definition is wrong or no longer working due to circumstances such as URLs having become unusable, SVN will error out when trying to use the external. There is little we can do about that, as it is somewhat inherent in the design of the externals feature. Any external that is valid today could become invalid tomorrow. Regards, Stefan