[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: [PATCH] Fix issue #1673 - svn merge reports File Not Found (single, unmodifi

From: Marcos Chaves <mchvs_at_hotmail.com>
Date: 2004-08-09 00:11:45 CEST

Hi Philip. Thanks for the fast response.

>Your mailer appears to have mangled the patch.

This time I attached the patch files too.

>Don't check ENOENT explicitly, use APR_STATUS_IS_ENOENT instead.

Done.

>An svn_error_t cannot simply be abandoned, it must either be returned
>or passed to svn_error_clear.

Oops... sure not! Fixed.

Here are both patches again. They are attached to this message
too.

Thanks,

Marcos

- - - - - 8< - - - - -

* subversion/libsvn_client/diff.c
   (do_single_file_merge): ignore ENOENT from svn_io_remove_file()
     because the temporary files may not exist if they were renamed.

Index: subversion/libsvn_client/diff.c
===================================================================
--- subversion/libsvn_client/diff.c (revision 10521)
+++ subversion/libsvn_client/diff.c (working copy)
@@ -1411,6 +1411,7 @@
   svn_wc_notify_state_t text_state = svn_wc_notify_state_unknown;
   const char *URL1, *path1, *URL2, *path2;
   svn_opt_revision_t *revision1, *revision2;
+ svn_error_t *err;

   SVN_ERR (svn_ra_init_ra_libs (&ra_baton, pool));

@@ -1475,8 +1476,19 @@
                                mimetype1, mimetype2,
                                merge_b));

- SVN_ERR (svn_io_remove_file (tmpfile1, pool));
- SVN_ERR (svn_io_remove_file (tmpfile2, pool));
+ /* Ignore if temporary file not found. It may have been renamed. */
+ if ((err = svn_io_remove_file (tmpfile1, pool))
+ && !APR_STATUS_IS_ENOENT(err->apr_err))
+ {
+ return err;
+ }
+ svn_error_clear (err);
+ if ((err = svn_io_remove_file (tmpfile2, pool))
+ && !APR_STATUS_IS_ENOENT(err->apr_err))
+ {
+ return err;
+ }
+ svn_error_clear (err);

   /* Deduce property diffs, and merge those too. */
   SVN_ERR (svn_prop_diffs (&propchanges, props2, props1, pool));

- - - - - 8< - - - - -

* subversion/tests/clients/cmdline/merge_tests.py
  (merge_binary_with_common_ancestry): regression test for
    issue #1673.

Index: subversion/tests/clients/cmdline/merge_tests.py
===================================================================
--- subversion/tests/clients/cmdline/merge_tests.py (revision 10521)
+++ subversion/tests/clients/cmdline/merge_tests.py (working copy)
@@ -1794,7 +1794,198 @@
                                        1, # please check props
                                        1) # and do a dry-run also)

+#----------------------------------------------------------------------

+# Regression test for issue #1673
+# Merge a binary file from two URL with a common ancestry
+
+def merge_binary_with_common_ancestry(sbox):
+ "merge binary files with common ancestry"
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ # Create the common ancestry path
+ I_path = os.path.join(wc_dir, 'I')
+ svntest.main.run_svn(None, 'mkdir', I_path)
+
+ # Add a binary file to the common ancestry path
+ fp = open(os.path.join(sys.path[0], "theta.bin"))
+ theta_contents = fp.read()
+ fp.close()
+ theta_I_path = os.path.join(wc_dir, 'I', 'theta')
+ fp = open(theta_I_path, 'w')
+ fp.write(theta_contents)
+ fp.close()
+ svntest.main.run_svn(None, 'add', theta_I_path)
+ svntest.main.run_svn(None, 'propset', 'svn:mime-type',
+ 'application/octet-stream', theta_I_path)
+
+ # Commit the ancestry
+ expected_output = wc.State(wc_dir, {
+ 'I' : Item(verb='Adding'),
+ 'I/theta' : Item(verb='Adding (bin)'),
+ })
+
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.tweak(repos_rev=2)
+ expected_status.add({
+ 'I' : Item(status=' ', wc_rev=2, repos_rev=2),
+ 'I/theta' : Item(status=' ', wc_rev=2, repos_rev=2),
+ })
+
+ svntest.actions.run_and_verify_commit(wc_dir,
+ expected_output, expected_status,
+ None,
+ None, None,
+ None, None,
+ wc_dir)
+
+ # Create the first branch
+ J_path = os.path.join(wc_dir, 'J')
+ svntest.main.run_svn(None, 'copy', I_path, J_path)
+
+ # Commit the first branch
+ expected_output = wc.State(wc_dir, {
+ 'J' : Item(verb='Adding'),
+ })
+
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.tweak(repos_rev=3)
+ expected_status.add({
+ 'I' : Item(status=' ', wc_rev=2, repos_rev=3),
+ 'I/theta' : Item(status=' ', wc_rev=2, repos_rev=3),
+ 'J' : Item(status=' ', wc_rev=3, repos_rev=3),
+ 'J/theta' : Item(status=' ', wc_rev=3, repos_rev=3),
+ })
+
+ svntest.actions.run_and_verify_commit(wc_dir,
+ expected_output, expected_status,
+ None,
+ None, None,
+ None, None,
+ wc_dir)
+
+ # Create the path where the files will be merged
+ K_path = os.path.join(wc_dir, 'K')
+ svntest.main.run_svn(None, 'mkdir', K_path)
+
+ # Commit the new path
+ expected_output = wc.State(wc_dir, {
+ 'K' : Item(verb='Adding'),
+ })
+
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.tweak(repos_rev=4)
+ expected_status.add({
+ 'I' : Item(status=' ', wc_rev=2, repos_rev=4),
+ 'I/theta' : Item(status=' ', wc_rev=2, repos_rev=4),
+ 'J' : Item(status=' ', wc_rev=3, repos_rev=4),
+ 'J/theta' : Item(status=' ', wc_rev=3, repos_rev=4),
+ 'K' : Item(status=' ', wc_rev=4, repos_rev=4),
+ })
+
+ svntest.actions.run_and_verify_commit(wc_dir,
+ expected_output, expected_status,
+ None,
+ None, None,
+ None, None,
+ wc_dir)
+
+ # Copy 'I/theta' to 'K/'. This file will be merged later.
+ theta_K_path = os.path.join(wc_dir, 'K', 'theta')
+ svntest.main.run_svn(None, 'copy', theta_I_path, theta_K_path)
+
+ # Commit the new file
+ expected_output = wc.State(wc_dir, {
+ 'K/theta' : Item(verb='Adding (bin)'),
+ })
+
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.tweak(repos_rev=5)
+ expected_status.add({
+ 'I' : Item(status=' ', wc_rev=2, repos_rev=5),
+ 'I/theta' : Item(status=' ', wc_rev=2, repos_rev=5),
+ 'J' : Item(status=' ', wc_rev=3, repos_rev=5),
+ 'J/theta' : Item(status=' ', wc_rev=3, repos_rev=5),
+ 'K' : Item(status=' ', wc_rev=4, repos_rev=5),
+ 'K/theta' : Item(status=' ', wc_rev=5, repos_rev=5),
+ })
+
+ svntest.actions.run_and_verify_commit(wc_dir,
+ expected_output, expected_status,
+ None,
+ None, None,
+ None, None,
+ wc_dir)
+
+ # Modify the original ancestry 'I/theta'
+ svntest.main.file_append(theta_I_path, "some extra junk")
+
+ # Commit the modification
+ expected_output = wc.State(wc_dir, {
+ 'I/theta' : Item(verb='Sending'),
+ })
+
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.tweak(repos_rev=6)
+ expected_status.add({
+ 'I' : Item(status=' ', wc_rev=2, repos_rev=6),
+ 'I/theta' : Item(status=' ', wc_rev=6, repos_rev=6),
+ 'J' : Item(status=' ', wc_rev=3, repos_rev=6),
+ 'J/theta' : Item(status=' ', wc_rev=3, repos_rev=6),
+ 'K' : Item(status=' ', wc_rev=4, repos_rev=6),
+ 'K/theta' : Item(status=' ', wc_rev=5, repos_rev=6),
+ })
+
+ svntest.actions.run_and_verify_commit(wc_dir,
+ expected_output, expected_status,
+ None,
+ None, None,
+ None, None,
+ wc_dir)
+
+ # Create the second branch from the modified ancestry
+ L_path = os.path.join(wc_dir, 'L')
+ svntest.main.run_svn(None, 'copy', I_path, L_path)
+
+ # Commit the second branch
+ expected_output = wc.State(wc_dir, {
+ 'L' : Item(verb='Adding'),
+ 'L/theta' : Item(verb='Adding (bin)'),
+ })
+
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_status.tweak(repos_rev=7)
+ expected_status.add({
+ 'I' : Item(status=' ', wc_rev=2, repos_rev=7),
+ 'I/theta' : Item(status=' ', wc_rev=6, repos_rev=7),
+ 'J' : Item(status=' ', wc_rev=3, repos_rev=7),
+ 'J/theta' : Item(status=' ', wc_rev=3, repos_rev=7),
+ 'K' : Item(status=' ', wc_rev=4, repos_rev=7),
+ 'K/theta' : Item(status=' ', wc_rev=5, repos_rev=7),
+ 'L' : Item(status=' ', wc_rev=7, repos_rev=7),
+ 'L/theta' : Item(status=' ', wc_rev=7, repos_rev=7),
+ })
+
+ svntest.actions.run_and_verify_commit(wc_dir,
+ expected_output, expected_status,
+ None,
+ None, None,
+ None, None,
+ wc_dir)
+
+ # Now merge first ('J/') and second ('L/') branches into 'K/'
+ saved_cwd = os.getcwd()
+ try:
+ os.chdir(K_path)
+ theta_J_url = svntest.main.current_repo_url + '/J/theta'
+ theta_L_url = svntest.main.current_repo_url + '/L/theta'
+ svntest.actions.run_and_verify_svn(None, ['U theta\n'], [], 'merge',
theta_J_url, theta_L_url)
+ finally:
+ os.chdir(saved_cwd)
+
+
########################################################################
# Run the tests

@@ -1816,6 +2007,7 @@
               merge_skips_obstructions,
               merge_into_missing,
               dry_run_adds_file_with_prop,
+ merge_binary_with_common_ancestry,
               # property_merges_galore, # Would be nice to have this.
               # tree_merges_galore, # Would be nice to have this.
               # various_merges_galore, # Would be nice to have this.

_________________________________________________________________
MSN Messenger: converse com os seus amigos online.
http://messenger.msn.com.br

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

Received on Mon Aug 9 00:11:56 2004

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.