Hi, I've experienced an issue with merging two working copy paths in which the behaviour of `svn` doesn't seem to match up with the documentation.
My system Subversion version is: > svn, version 1.14.2 (r1899510) > compiled Oct 23 2023, 15:43:14 on x86_64-pc-linux-gnu but I have also reproduced it on revision 1913725 built from source. The only reference I could find to this issue was this users@ mailing list post from almost a decade ago with no responses: https://lists.apache.org/thread/16vf8rr4w7nfkbjlsgfrnrfh0ly4mk41[1] The relevant sections of the documentation are (from `svn help merge`): > usage: 1. merge SOURCE[@REV] [TARGET_WCPATH] > (the 'complete' merge) > 2. merge [-c M[,N...] | -r N:M ...] SOURCE[@REV] [TARGET_WCPATH] > (the 'cherry-pick' merge) > 3. merge SOURCE1[@REV1] SOURCE2[@REV2] [TARGET_WCPATH] > (the '2-URL' merge) and (regarding form 1): > SOURCE is usually a URL. The optional '@REV' specifies both the peg > revision of the URL and the latest revision that will be considered > for merging; if REV is not specified, the HEAD revision is assumed. If > SOURCE is a working copy path, the corresponding URL of the path is > used, and the default value of 'REV' is the base revision (usually the > revision last updated to). However, running a command like `svn merge a b` results in: > svn: E195002: Invalid merge source 'a'; a working copy path can only be used > with a repository revision (a number, a date, or head) I have a reproduction `sh` script: #! /usr/bin/env sh set -e mkdir scratch cd scratch svnadmin create repos svn checkout "file://$(pwd)/repos" working cd working svn mkdir ^/a --message='Created a' svn copy ^/a ^/b --message='Created b' svn update set +e printf '\n=== Merging with two working copy paths (explicit target) ===\n' svn merge a b printf '\n=== Merging with two working copy paths (inside directory target) ===\n' cd b svn merge ../a . cd .. printf '\n=== Merging with a single working copy path (inferred target) ===\n' cd b svn merge ../a cd .. (End of reproduction) The output of this script is: > Checked out revision 0. > Committing transaction... > Committed revision 1. > Committing transaction... > Committed revision 2. > Updating '.': > A a > A b > Updated to revision 2. > > === Merging with two working copy paths (explicit target) === > svn: E195002: Invalid merge source 'a'; a working copy path can only be used > with a repository revision (a number, a date, or head) > > === Merging with two working copy paths (inside directory target) === > svn: E195002: Invalid merge source '../a'; a working copy path can only be > used with a repository revision (a number, a date, or head) > > === Merging with a single working copy path (inferred target) === > --- Recording mergeinfo for merge of r2 into '.': > U . As can be seen in the reproduction, with an explicitly specified `TARGET_WCPATH` there is an error, but when it is omitted, it is assumed to be `.` and succeeds. >From a brief search of the code, I believe the error lies at >`subversion/svn/merge-cmd.c: 334` (I have revision 1913725 checked out). For the lazy, it looks like: > if (targets->nelts <= 1) > { > two_sources_specified = FALSE; > } > else if (targets->nelts == 2) > { > if (svn_path_is_url(sourcepath1) && !svn_path_is_url(sourcepath2)) // > <-- This one > two_sources_specified = FALSE; > } In particular, it checks that `sourcepath1` is a URL, which doesn't seem right to me. It seems like this code was introduced in revision 868224, whose log message makes no mention of intending to change this behaviour (although I can't verify that the behaviour was introduced here as it uses Python 2 as part of the build process). While I can't be sure that this behaviour is not intended, it does not match the documentation, so at least one of the implementation and the documentation must be wrong. I would assume that there is an error in the implementation given the inconsistency between passing the second argument explicitly vs implicitly. I haven't reported any issues to Subversion before, so please tell me if there is anything I have neglected to do or should have done differently.