Stefan Sperling wrote on Thu, Nov 18, 2010 at 00:54:42 +0100:
> With BDB, svnsync crashes as follows during during svnsync test 29.
> It only happens with BDB. Running "./svnsync_tests.py 29 --fs-type=bdb"
> triggers the problem for me on the 1.6.x branch, too.
> 
> I guess this could be related to this backport item:
>    * improve svnsync handling of dir copies (r962377, -8)
> 
> Details follow:
> 
> SVNProcessTerminatedBySignal
> FAIL:  svnsync_tests.py 29: descending into replaced dir looks in src

The following patch fixes the FAIL on trunk.  (I haven't tested 1.6.x.)
Please review :-)

[[[
Follow-up to r962378 (for issue #3641):

When an API says "COPYFROM_KNOWN might be false", believe that API and
implement a workaround for that case.  Since this has almost doubled the
length of the copyfrom retrieval code, move it to a new static function.

This unbreaks svnsync_tests 29 under BDB.

* subversion/libsvn_repos/replay.c
  (get_copyfrom): New helper.
  (add_subdir): Delegate to get_copyfrom().
]]]

[[[
Index: subversion/libsvn_repos/replay.c
===================================================================
--- subversion/libsvn_repos/replay.c    (revision 1036314)
+++ subversion/libsvn_repos/replay.c    (working copy)
@@ -143,6 +143,36 @@ struct path_driver_cb_baton
   apr_pool_t *pool;
 };
 
+/* Helper: return in *COPYFROM_PATH_P and *COPYFROM_REV_P the copyfrom
+ * information; either from CHANGE, if available there, or those of
+ * COPYTO_ROOT:/COPYTO_PATH (which must be a copied path).
+ */
+static svn_error_t *
+get_copyfrom(const char **copyfrom_path_p,
+             svn_revnum_t *copyfrom_rev_p,
+             svn_fs_path_change2_t *change,
+             svn_fs_root_t *copyto_root,
+             const char *copyto_path,
+             apr_pool_t *pool)
+{
+  svn_fs_history_t *history, *history_prev;
+
+  /* Easy out. */
+  if (change->copyfrom_known)
+    {
+      *copyfrom_path_p = change->copyfrom_path;
+      *copyfrom_rev_p = change->copyfrom_rev;
+      return SVN_NO_ERROR;
+    }
+
+  SVN_ERR(svn_fs_node_history(&history, copyto_root, copyto_path, pool));
+  SVN_ERR(svn_fs_history_prev(&history_prev, history, TRUE /* cross copies */,
+                              pool));
+  SVN_ERR(svn_fs_history_location(copyfrom_path_p, copyfrom_rev_p,
+                                  history_prev, pool));
+  return SVN_NO_ERROR;
+}
+
 /* Recursively traverse PATH (as it exists under SOURCE_ROOT) emitting
    the appropriate editor calls to add it and its children without any
    history.  This is meant to be used when either a subset of the tree
@@ -225,10 +255,10 @@ add_subdir(svn_fs_root_t *source_root,
             continue;
           else if (change->change_kind == svn_fs_path_change_replace)
             {
-              /* ### Can this assert fail? */
-              SVN_ERR_ASSERT(change->copyfrom_known);
-              copyfrom_path = change->copyfrom_path;
-              copyfrom_rev = change->copyfrom_rev;
+              SVN_ERR(get_copyfrom(&copyfrom_path, &copyfrom_rev, change,
+                                   /* copied-to coordinates: */
+                                   target_root, new_path,
+                                   pool));
             }
         }
 
]]]

Thanks,

Daniel

Reply via email to