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