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__':

Reply via email to