http://subversion.tigris.org/issues/show_bug.cgi?id=3807

I've had a look at the above, and I'm attaching a patch.  I'd like to get
review of this patch --- I have not worked enough on wc internals to feel
confident about it, and I wrote at least part of it by an "Add an if() until
the tests stop segfault" approach.

Thanks.

Daniel
Fix issue #3807, "'svn up' of a nonexistent child in a copied dir triggers
an assertion".  This patch makes a couple of places look for the attributes
of added nodes, where previously if a node was added they had ignored it.

###: not sure about the adm_crawler.c changes

###: what *should* the 'svn up' do?  Should it always succeed silently, or 
should 
###  'svn cp A A2; svn mkdir ^/A/foo; svn up A2/foo' pull the new directory?

* subversion/libsvn_wc/update_editor.c
  (make_dir_baton):
    Scan more than the BASE tree when computing NEW_RELPATH.
  (make_editor):
    Look for REPOS_ROOT_URL and REPOS_UUID for added nodes, too.

* subversion/libsvn_wc/adm_crawler.c
  (svn_wc_crawl_revisions5):
    Consider svn_wc__db_status_absent the same as svn_wc__db_status_not_present.
Index: subversion/libsvn_wc/update_editor.c
===================================================================
--- subversion/libsvn_wc/update_editor.c        (revision 1073712)
+++ subversion/libsvn_wc/update_editor.c        (working copy)
@@ -600,9 +600,33 @@ make_dir_baton(struct dir_baton **d_p,
         {
           /* Get the original REPOS_RELPATH. An update will not be
              changing its value.  */
-          SVN_ERR(svn_wc__db_scan_base_repos(&d->new_relpath, NULL, NULL,
+          svn_wc__db_status_t status;
+          const char *repos_relpath, *original_repos_relpath;
+          SVN_ERR(svn_wc__db_read_info(&status, NULL, NULL, &repos_relpath,
+                                       NULL, NULL, NULL, NULL, NULL, NULL,
+                                       NULL, NULL, NULL, NULL, NULL,
+                                       &original_repos_relpath,
+                                       NULL, NULL, NULL, NULL, NULL, NULL,
+                                       NULL, NULL,
+                                       eb->db, d->local_abspath,
+                                       dir_pool, scratch_pool));
+          if (status == svn_wc__db_status_added)
+            SVN_ERR(svn_wc__db_scan_addition(NULL, NULL,
+                                             &repos_relpath, NULL, NULL,
+                                             &original_repos_relpath, NULL, 
NULL,
+                                             NULL,
                                              eb->db, d->local_abspath,
                                              dir_pool, scratch_pool));
+
+          if (original_repos_relpath)
+            d->new_relpath = original_repos_relpath;
+          else if (repos_relpath)
+            d->new_relpath = repos_relpath;
+          else
+            SVN_ERR(svn_wc__db_scan_base_repos(&d->new_relpath, NULL, NULL,
+                                               eb->db, d->local_abspath,
+                                               dir_pool, scratch_pool));
+          SVN_ERR_ASSERT(d->new_relpath);
         }
     }
 
@@ -4858,17 +4882,27 @@ make_editor(svn_revnum_t *target_revision,
   svn_delta_editor_t *tree_editor = svn_delta_default_editor(edit_pool);
   const svn_delta_editor_t *inner_editor;
   const char *repos_root, *repos_uuid;
+  svn_wc__db_status_t status;
 
   /* An unknown depth can't be sticky. */
   if (depth == svn_depth_unknown)
     depth_is_sticky = FALSE;
 
   /* Get the anchor's repository root and uuid. */
-  SVN_ERR(svn_wc__db_read_info(NULL,NULL, NULL, NULL, &repos_root, &repos_uuid,
+  SVN_ERR(svn_wc__db_read_info(&status, NULL, NULL, NULL,
+                               &repos_root, &repos_uuid,
                                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                NULL, NULL, wc_ctx->db, anchor_abspath,
                                result_pool, scratch_pool));
+  
+  /* For adds, REPOS_ROOT and REPOS_UUID would be NULL now. */
+  if (status == svn_wc__db_status_added)
+    SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL,
+                                     &repos_root, &repos_uuid,
+                                     NULL, NULL, NULL, NULL,
+                                     wc_ctx->db, anchor_abspath,
+                                     result_pool, scratch_pool));
 
   /* With WC-NG we need a valid repository root */
   SVN_ERR_ASSERT(repos_root != NULL && repos_uuid != NULL);
Index: subversion/libsvn_wc/adm_crawler.c
===================================================================
--- subversion/libsvn_wc/adm_crawler.c  (revision 1073712)
+++ subversion/libsvn_wc/adm_crawler.c  (working copy)
@@ -786,7 +786,8 @@ svn_wc_crawl_revisions5(svn_wc_context_t *wc_ctx,
         status = svn_wc__db_status_not_present; /* As checkout */
     }
 
-  if ((status == svn_wc__db_status_not_present)
+  if (status == svn_wc__db_status_not_present
+      || status == svn_wc__db_status_absent
       || (target_kind == svn_wc__db_kind_dir
           && status != svn_wc__db_status_normal
           && status != svn_wc__db_status_incomplete))

Reply via email to