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))