diff options
Diffstat (limited to 'subversion/libsvn_wc/status.c')
-rw-r--r-- | subversion/libsvn_wc/status.c | 190 |
1 files changed, 44 insertions, 146 deletions
diff --git a/subversion/libsvn_wc/status.c b/subversion/libsvn_wc/status.c index 1440b2ee5e4a..fa57b0aee5e5 100644 --- a/subversion/libsvn_wc/status.c +++ b/subversion/libsvn_wc/status.c @@ -242,144 +242,7 @@ struct file_baton /** Code **/ -/* Fill in *INFO with the information it would contain if it were - obtained from svn_wc__db_read_children_info. */ -static svn_error_t * -read_info(const struct svn_wc__db_info_t **info, - const char *local_abspath, - svn_wc__db_t *db, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool) -{ - struct svn_wc__db_info_t *mtb = apr_pcalloc(result_pool, sizeof(*mtb)); - const svn_checksum_t *checksum; - const char *original_repos_relpath; - - SVN_ERR(svn_wc__db_read_info(&mtb->status, &mtb->kind, - &mtb->revnum, &mtb->repos_relpath, - &mtb->repos_root_url, &mtb->repos_uuid, - &mtb->changed_rev, &mtb->changed_date, - &mtb->changed_author, &mtb->depth, - &checksum, NULL, &original_repos_relpath, NULL, - NULL, NULL, &mtb->lock, &mtb->recorded_size, - &mtb->recorded_time, &mtb->changelist, - &mtb->conflicted, &mtb->op_root, - &mtb->had_props, &mtb->props_mod, - &mtb->have_base, &mtb->have_more_work, NULL, - db, local_abspath, - result_pool, scratch_pool)); - - SVN_ERR(svn_wc__db_wclocked(&mtb->locked, db, local_abspath, scratch_pool)); - - /* Maybe we have to get some shadowed lock from BASE to make our test suite - happy... (It might be completely unrelated, but...) */ - if (mtb->have_base - && (mtb->status == svn_wc__db_status_added - || mtb->status == svn_wc__db_status_deleted - || mtb->kind == svn_node_file)) - { - svn_boolean_t update_root; - svn_wc__db_lock_t **lock_arg = NULL; - - if (mtb->status == svn_wc__db_status_added - || mtb->status == svn_wc__db_status_deleted) - lock_arg = &mtb->lock; - - SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, - lock_arg, NULL, NULL, &update_root, - db, local_abspath, - result_pool, scratch_pool)); - - mtb->file_external = (update_root && mtb->kind == svn_node_file); - - if (mtb->status == svn_wc__db_status_deleted) - { - const char *moved_to_abspath; - const char *moved_to_op_root_abspath; - - /* NOTE: we can't use op-root-ness as a condition here since a base - * node can be the root of a move and still not be an explicit - * op-root (having a working node with op_depth == pathelements). - * - * Both these (almost identical) situations showcase this: - * svn mv a/b bb - * svn del a - * and - * svn mv a aa - * svn mv aa/b bb - * In both, 'bb' is moved from 'a/b', but 'a/b' has no op_depth>0 - * node at all, as its parent 'a' is locally deleted. */ - - SVN_ERR(svn_wc__db_scan_deletion(NULL, - &moved_to_abspath, - NULL, - &moved_to_op_root_abspath, - db, local_abspath, - scratch_pool, scratch_pool)); - if (moved_to_abspath != NULL - && moved_to_op_root_abspath != NULL - && strcmp(moved_to_abspath, moved_to_op_root_abspath) == 0) - { - mtb->moved_to_abspath = apr_pstrdup(result_pool, - moved_to_abspath); - } - /* ### ^^^ THIS SUCKS. For at least two reasons: - * 1) We scan the node deletion and that's technically not necessary. - * We'd be fine to know if this is an actual root of a move. - * 2) From the elaborately calculated results, we backwards-guess - * whether this is a root. - * It works ok, and this code only gets called when a node is an - * explicit target of a 'status'. But it would be better to do this - * differently. - * We could return moved-to via svn_wc__db_base_get_info() (called - * just above), but as moved-to is only intended to be returned for - * roots of a move, that doesn't fit too well. */ - } - } - - /* ### svn_wc__db_read_info() could easily return the moved-here flag. But - * for now... (The per-dir query for recursive status is far more optimal.) - * Note that this actually scans around to get the full path, for a bool. - * This bool then gets returned, later is evaluated, and if true leads to - * the same paths being scanned again. We'd want to obtain this bool here as - * cheaply as svn_wc__db_read_children_info() does. */ - if (mtb->status == svn_wc__db_status_added) - { - svn_wc__db_status_t status; - SVN_ERR(svn_wc__db_scan_addition(&status, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - db, local_abspath, - result_pool, scratch_pool)); - - mtb->moved_here = (status == svn_wc__db_status_moved_here); - mtb->incomplete = (status == svn_wc__db_status_incomplete); - } - - mtb->has_checksum = (checksum != NULL); - mtb->copied = (original_repos_relpath != NULL); - -#ifdef HAVE_SYMLINK - if (mtb->kind == svn_node_file - && (mtb->had_props || mtb->props_mod)) - { - apr_hash_t *properties; - - if (mtb->props_mod) - SVN_ERR(svn_wc__db_read_props(&properties, db, local_abspath, - scratch_pool, scratch_pool)); - else - SVN_ERR(svn_wc__db_read_pristine_props(&properties, db, local_abspath, - scratch_pool, scratch_pool)); - - mtb->special = (NULL != svn_hash_gets(properties, SVN_PROP_SPECIAL)); - } -#endif - *info = mtb; - - return SVN_NO_ERROR; -} /* Return *REPOS_RELPATH and *REPOS_ROOT_URL for LOCAL_ABSPATH using information in INFO if available, falling back on @@ -421,13 +284,42 @@ get_repos_root_url_relpath(const char **repos_relpath, db, local_abspath, result_pool, scratch_pool)); } - else if (info->have_base) + else if (info->status == svn_wc__db_status_deleted + && !info->have_more_work + && info->have_base) { SVN_ERR(svn_wc__db_scan_base_repos(repos_relpath, repos_root_url, repos_uuid, db, local_abspath, result_pool, scratch_pool)); } + else if (info->status == svn_wc__db_status_deleted) + { + const char *work_del_abspath; + const char *add_abspath; + + /* Handles working DELETE and the special case where there is just + svn_wc__db_status_not_present in WORKING */ + + SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL, &work_del_abspath, NULL, + db, local_abspath, + scratch_pool, scratch_pool)); + + /* The parent of what has been deleted must be added */ + add_abspath = svn_dirent_dirname(work_del_abspath, scratch_pool); + + SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, repos_relpath, + repos_root_url, repos_uuid, NULL, + NULL, NULL, NULL, + db, add_abspath, + result_pool, scratch_pool)); + + *repos_relpath = svn_relpath_join(*repos_relpath, + svn_dirent_skip_ancestor( + add_abspath, + local_abspath), + result_pool); + } else { *repos_relpath = NULL; @@ -493,7 +385,8 @@ assemble_status(svn_wc_status3_t **status, if (!info) - SVN_ERR(read_info(&info, local_abspath, db, result_pool, scratch_pool)); + SVN_ERR(svn_wc__db_read_single_info(&info, db, local_abspath, + result_pool, scratch_pool)); if (!info->repos_relpath || !parent_repos_relpath) switched_p = FALSE; @@ -799,8 +692,11 @@ assemble_status(svn_wc_status3_t **status, stat->changelist = apr_pstrdup(result_pool, info->changelist); stat->moved_from_abspath = moved_from_abspath; - if (info->moved_to_abspath) - stat->moved_to_abspath = apr_pstrdup(result_pool, info->moved_to_abspath); + + /* ### TODO: Handle multiple moved_to values properly */ + if (info->moved_to) + stat->moved_to_abspath = apr_pstrdup(result_pool, + info->moved_to->moved_to_abspath); stat->file_external = info->file_external; @@ -1345,8 +1241,8 @@ get_dir_status(const struct walk_status_baton *wb, SVN_ERR(err); if (!dir_info) - SVN_ERR(read_info(&dir_info, local_abspath, wb->db, - scratch_pool, iterpool)); + SVN_ERR(svn_wc__db_read_single_info(&dir_info, wb->db, local_abspath, + scratch_pool, iterpool)); SVN_ERR(get_repos_root_url_relpath(&dir_repos_relpath, &dir_repos_root_url, &dir_repos_uuid, dir_info, @@ -1506,8 +1402,9 @@ get_child_status(const struct walk_status_baton *wb, if (dirent->kind == svn_node_none) dirent = NULL; - SVN_ERR(read_info(&dir_info, parent_abspath, wb->db, - scratch_pool, scratch_pool)); + SVN_ERR(svn_wc__db_read_single_info(&dir_info, + wb->db, parent_abspath, + scratch_pool, scratch_pool)); SVN_ERR(get_repos_root_url_relpath(&dir_repos_relpath, &dir_repos_root_url, &dir_repos_uuid, dir_info, @@ -2710,7 +2607,8 @@ svn_wc__internal_walk_status(svn_wc__db_t *db, ignore_patterns = ignores; } - err = read_info(&info, local_abspath, db, scratch_pool, scratch_pool); + err = svn_wc__db_read_single_info(&info, db, local_abspath, + scratch_pool, scratch_pool); if (err) { |