Thanks for the patch Alexey. Forwarding it to dev@. Alexey Neyman wrote on Tue, Mar 06, 2012 at 16:27:11 -0800: > Hi Daniel, > > On Monday, March 05, 2012 11:33:33 pm Daniel Shahaf wrote: > > Alexey Neyman wrote on Mon, Mar 05, 2012 at 16:14:24 -0800: > > > Hi all, > > > > > > I ran into the following error message with Subversion: > > > > > > svn: Attempted to get textual contents of a *non*-file node > > > > > > The issue, as pointed out by email thread [1], is that the directory > > > being merged contains a file with the same name as the directory. I.e., > > > there is /trunk/foo directory containing /trunk/foo/foo file. > > > > > > However, even if I tried the suggestion from Ben Collins-Sussman, it > > > didn't help: 'svn merge' still complained with the same error message. > > > Reproduction script attached. Is there a way such projects can use 'svn > > > merge' command? > > > > > > I tried with Subversion trunk and, although the error message is > > > different ("svn: E160017: '/trunk/foo' is not a file"), the result is > > > still the same. While it is a better message than the one in 1.6, it > > > still does not explain why Subversion expects /trunk/foo to be a file > > > for the following commands: > > > > > > svn merge -c 4 ^/trunk/foo > > > svn merge -c 4 ^/trunk/foo . > > > svn merge ^/trunk/foo@3 ^/trunk/foo@4 . > > > svn merge -r 3:4 ^/trunk/foo . > > > > Yeah, I just tried with trunk, couldn't get the merge to work, with > > those commands (some of which are made equivalent by the argument > > parser) or with <svn merge ^/trunk/foo@3 ^/trunk/foo@4 foo>. > > > > Looks like a bug to me, assuming it works when the dir and the file are > > not both named the same thing. > > I confirm it works when dir and file do not have the same name. E.g., if you > rename new file 'B' in the attached testcase to, say, 'X' - it passes. There > is one more condition for this bug to manifest: the offending directory must > be the current directory: even though > > $ svn merge -c 4 ^/trunk/foo . > > fails, the following > > $ wc=`pwd` > $ cd .. > $ svn merge -c 4 ^/trunk/foo $wc > > works. I guess, it's sort of a workaround. > > > > As another side note, Subversion leaves behind a zero-sized temporary > > > file created for the merge. > > > > And this one too. (the file is in the wc root) > > > > > Regards, > > > Alexey. > > > > > > [1] http://markmail.org/message/qqh3r6d4tcdyjnz2#query: > > > +page:1+mid:vcjektlfn37mxyld+state:results > > > > Could you file an issue? Perhaps send a patch adding a regression test > > for this (in Python)? (See subversion/tests/cmdline/README) > > Issue 4139 created. Attached is a patch that adds an XFail to the test suite > for this issue. > > Regards, > Alexey.
> Index: subversion/tests/cmdline/merge_tests.py > =================================================================== > --- subversion/tests/cmdline/merge_tests.py (revision 1297725) > +++ subversion/tests/cmdline/merge_tests.py (working copy) > @@ -17467,6 +17467,64 @@ > 'merge', sbox.repo_url + '/A', > A_COPY_path) > > +@XFail() > +@Issue(4139) > +def merge_dir_file_same_name(sbox): > + "merged directory has file with same name" > + sbox.build() > + wc_dir = sbox.wc_dir > + > + # Paths of interest in first WC > + A_B_B_path = os.path.join(wc_dir, 'A', 'B', 'B') > + > + # Create file 'B' in path '/A/B' - revision 2 > + svntest.main.file_write(A_B_B_path, "Project B now has file B") > + svntest.main.run_svn(None, 'add', A_B_B_path) > + expected_output = svntest.wc.State(wc_dir, { > + 'A/B/B' : Item(verb='Adding'), > + }) > + expected_status = svntest.actions.get_virginal_state(wc_dir, 1) > + expected_status.add({ > + 'A/B/B' : Item(status=' ', wc_rev=2), > + }) > + svntest.actions.run_and_verify_commit(wc_dir, expected_output, > + expected_status, None, > + wc_dir) > + > + # Copy '/A' to '/A_COPY' - revision 3 > + sbox.simple_repo_copy('A', 'A_COPY') > + > + # Now modify '/A/B/B' - revision 4 > + svntest.main.file_write(A_B_B_path, "File B is now modified") > + expected_output = svntest.wc.State(wc_dir, { > + 'A/B/B' : Item(verb='Sending'), > + }) > + expected_status = svntest.actions.get_virginal_state(wc_dir, 1) > + expected_status.add({ > + 'A/B/B' : Item(status=' ', wc_rev=4), > + }) > + svntest.actions.run_and_verify_commit(wc_dir, expected_output, > + expected_status, None, > + wc_dir) > + > + # Now check out A_COPY/B in a separate WC > + wc_copy = sbox.add_wc_path('copy') > + svntest.actions.run_and_verify_svn(None, None, [], 'checkout', > + sbox.repo_url + '/A_COPY/B', wc_copy) > + > + # And try to merge the change from revision 4 of /A/B/B to > + # /A_COPY/B/B from the WC dir. > + saved_cwd = os.getcwd() > + os.chdir(wc_copy) > + expected_output = expected_merge_output([[4]], > + ['U B\n', > + ' U \.',]) > + svntest.actions.run_and_verify_svn(None, expected_output, [], > + 'merge', '-c', '4', > + sbox.repo_url + '/A/B') > + os.chdir(saved_cwd) > + > + > ######################################################################## > # Run the tests > > @@ -17599,6 +17657,7 @@ > unnecessary_noninheritable_mergeinfo_shallow_merge, > svnmucc_abuse_1, > merge_source_with_replacement, > + merge_dir_file_same_name, > ] > > if __name__ == '__main__':