diff options
author | Peter Wemm <peter@FreeBSD.org> | 2018-05-08 03:44:38 +0000 |
---|---|---|
committer | Peter Wemm <peter@FreeBSD.org> | 2018-05-08 03:44:38 +0000 |
commit | 3faf8d6bffc5d0fb2525ba37bb504c53366caf9d (patch) | |
tree | 7e47911263e75034b767fe34b2f8d3d17e91f66d /subversion/libsvn_wc/diff_editor.c | |
parent | a55fb3c0d5eca7d887798125d5b95942b1f01d4b (diff) |
Notes
Diffstat (limited to 'subversion/libsvn_wc/diff_editor.c')
-rw-r--r-- | subversion/libsvn_wc/diff_editor.c | 182 |
1 files changed, 152 insertions, 30 deletions
diff --git a/subversion/libsvn_wc/diff_editor.c b/subversion/libsvn_wc/diff_editor.c index fc059a5d4dea..9b1b0d50baa0 100644 --- a/subversion/libsvn_wc/diff_editor.c +++ b/subversion/libsvn_wc/diff_editor.c @@ -145,6 +145,9 @@ struct dir_baton_t /* TRUE if the node is to be compared with an unrelated node*/ svn_boolean_t ignoring_ancestry; + /* TRUE if the directory was reported incomplete to the repository */ + svn_boolean_t is_incomplete; + /* Processor state */ void *pdb; svn_boolean_t skip; @@ -741,9 +744,29 @@ walk_local_nodes_diff(struct edit_baton_t *eb, if (eb->local_before_remote && local_only) { + const char *moved_from_relpath; + + if (info->moved_here) + { + const char *moved_from_abspath; + + SVN_ERR(svn_wc__db_scan_moved(&moved_from_abspath, + NULL, NULL, NULL, + db, child_abspath, + iterpool, iterpool)); + SVN_ERR_ASSERT(moved_from_abspath != NULL); + + moved_from_relpath = svn_dirent_skip_ancestor( + eb->anchor_abspath, + moved_from_abspath); + } + else + moved_from_relpath = NULL; + if (info->kind == svn_node_file && diff_files) SVN_ERR(svn_wc__diff_local_only_file(db, child_abspath, child_relpath, + moved_from_relpath, eb->processor, dir_baton, eb->diff_pristine, eb->cancel_func, @@ -753,6 +776,7 @@ walk_local_nodes_diff(struct edit_baton_t *eb, SVN_ERR(svn_wc__diff_local_only_dir(db, child_abspath, child_relpath, depth_below_here, + moved_from_relpath, eb->processor, dir_baton, eb->diff_pristine, eb->cancel_func, @@ -807,9 +831,29 @@ walk_local_nodes_diff(struct edit_baton_t *eb, if (!eb->local_before_remote && local_only) { + const char *moved_from_relpath; + + if (info->moved_here) + { + const char *moved_from_abspath; + + SVN_ERR(svn_wc__db_scan_moved(&moved_from_abspath, + NULL, NULL, NULL, + db, child_abspath, + iterpool, iterpool)); + SVN_ERR_ASSERT(moved_from_abspath != NULL); + + moved_from_relpath = svn_dirent_skip_ancestor( + eb->anchor_abspath, + moved_from_abspath); + } + else + moved_from_relpath = NULL; + if (info->kind == svn_node_file && diff_files) SVN_ERR(svn_wc__diff_local_only_file(db, child_abspath, child_relpath, + moved_from_relpath, eb->processor, dir_baton, eb->diff_pristine, eb->cancel_func, @@ -817,12 +861,13 @@ walk_local_nodes_diff(struct edit_baton_t *eb, iterpool)); else if (info->kind == svn_node_dir && diff_dirs) SVN_ERR(svn_wc__diff_local_only_dir(db, child_abspath, - child_relpath, depth_below_here, - eb->processor, dir_baton, - eb->diff_pristine, - eb->cancel_func, - eb->cancel_baton, - iterpool)); + child_relpath, depth_below_here, + moved_from_relpath, + eb->processor, dir_baton, + eb->diff_pristine, + eb->cancel_func, + eb->cancel_baton, + iterpool)); } } } @@ -873,6 +918,7 @@ svn_error_t * svn_wc__diff_local_only_file(svn_wc__db_t *db, const char *local_abspath, const char *relpath, + const char *moved_from_relpath, const svn_diff_tree_processor_t *processor, void *processor_parent_baton, svn_boolean_t diff_pristine, @@ -935,6 +981,7 @@ svn_wc__diff_local_only_file(svn_wc__db_t *db, { copyfrom_src = svn_diff__source_create(original_revision, scratch_pool); copyfrom_src->repos_relpath = original_repos_relpath; + copyfrom_src->moved_from_relpath = moved_from_relpath; } if (props_mod || !SVN_IS_VALID_REVNUM(revision)) @@ -1013,6 +1060,7 @@ svn_wc__diff_local_only_dir(svn_wc__db_t *db, const char *local_abspath, const char *relpath, svn_depth_t depth, + const char *moved_from_relpath, const svn_diff_tree_processor_t *processor, void *processor_parent_baton, svn_boolean_t diff_pristine, @@ -1049,6 +1097,7 @@ svn_wc__diff_local_only_dir(svn_wc__db_t *db, { copyfrom_src = svn_diff__source_create(original_revision, scratch_pool); copyfrom_src->repos_relpath = original_repos_relpath; + copyfrom_src->moved_from_relpath = moved_from_relpath; } /* svn_wc__db_status_incomplete should never happen, as the result won't be @@ -1136,12 +1185,40 @@ svn_wc__diff_local_only_dir(svn_wc__db_t *db, child_relpath = svn_relpath_join(relpath, name, iterpool); + if (info->moved_here) + { + const char *moved_from_abspath; + const char *a_abspath; + const char *a_relpath; + + a_relpath = relpath; + a_abspath = local_abspath; + while (*a_relpath) + { + a_relpath = svn_relpath_dirname(a_relpath, iterpool); + a_abspath = svn_dirent_dirname(a_abspath, iterpool); + } + + SVN_ERR(svn_wc__db_scan_moved(&moved_from_abspath, + NULL, NULL, NULL, + db, child_abspath, + iterpool, iterpool)); + SVN_ERR_ASSERT(moved_from_abspath != NULL); + + moved_from_relpath = svn_dirent_skip_ancestor( + a_abspath, + moved_from_abspath); + } + else + moved_from_relpath = NULL; + switch (info->kind) { case svn_node_file: case svn_node_symlink: SVN_ERR(svn_wc__diff_local_only_file(db, child_abspath, child_relpath, + moved_from_relpath, processor, pdb, diff_pristine, cancel_func, cancel_baton, @@ -1154,6 +1231,7 @@ svn_wc__diff_local_only_dir(svn_wc__db_t *db, SVN_ERR(svn_wc__diff_local_only_dir(db, child_abspath, child_relpath, depth_below_here, + moved_from_relpath, processor, pdb, diff_pristine, cancel_func, @@ -1202,6 +1280,8 @@ handle_local_only(struct dir_baton_t *pb, { struct edit_baton_t *eb = pb->eb; const struct svn_wc__db_info_t *info; + const char *child_abspath; + const char *moved_from_relpath; svn_boolean_t repos_delete = (pb->deletes && svn_hash_gets(pb->deletes, name)); @@ -1220,10 +1300,8 @@ handle_local_only(struct dir_baton_t *pb, switch (info->status) { - case svn_wc__db_status_incomplete: - return SVN_NO_ERROR; /* Not local only */ - case svn_wc__db_status_normal: + case svn_wc__db_status_incomplete: if (!repos_delete) return SVN_NO_ERROR; /* Local and remote */ svn_hash_sets(pb->deletes, name, NULL); @@ -1239,6 +1317,25 @@ handle_local_only(struct dir_baton_t *pb, break; } + child_abspath = svn_dirent_join(pb->local_abspath, name, scratch_pool); + + if (info->moved_here) + { + const char *moved_from_abspath; + + SVN_ERR(svn_wc__db_scan_moved(&moved_from_abspath, + NULL, NULL, NULL, + eb->db, child_abspath, + scratch_pool, scratch_pool)); + SVN_ERR_ASSERT(moved_from_abspath != NULL); + + moved_from_relpath = svn_dirent_skip_ancestor( + eb->anchor_abspath, + moved_from_abspath); + } + else + moved_from_relpath = NULL; + if (info->kind == svn_node_dir) { svn_depth_t depth ; @@ -1250,9 +1347,10 @@ handle_local_only(struct dir_baton_t *pb, SVN_ERR(svn_wc__diff_local_only_dir( eb->db, - svn_dirent_join(pb->local_abspath, name, scratch_pool), + child_abspath, svn_relpath_join(pb->relpath, name, scratch_pool), repos_delete ? svn_depth_infinity : depth, + moved_from_relpath, eb->processor, pb->pdb, eb->diff_pristine, eb->cancel_func, eb->cancel_baton, @@ -1261,8 +1359,9 @@ handle_local_only(struct dir_baton_t *pb, else SVN_ERR(svn_wc__diff_local_only_file( eb->db, - svn_dirent_join(pb->local_abspath, name, scratch_pool), + child_abspath, svn_relpath_join(pb->relpath, name, scratch_pool), + moved_from_relpath, eb->processor, pb->pdb, eb->diff_pristine, eb->cancel_func, eb->cancel_baton, @@ -1608,25 +1707,47 @@ open_directory(const char *path, db->repos_only = TRUE; if (!db->repos_only) - switch (info->status) - { - case svn_wc__db_status_normal: - break; - case svn_wc__db_status_deleted: - db->repos_only = TRUE; - - if (!info->have_more_work) - svn_hash_sets(pb->compared, - apr_pstrdup(pb->pool, db->name), ""); - break; - case svn_wc__db_status_added: - if (eb->ignore_ancestry) - db->ignoring_ancestry = TRUE; - else + { + switch (info->status) + { + case svn_wc__db_status_normal: + case svn_wc__db_status_incomplete: + db->is_incomplete = (info->status == + svn_wc__db_status_incomplete); + break; + case svn_wc__db_status_deleted: db->repos_only = TRUE; - break; - default: - SVN_ERR_MALFUNCTION(); + + if (!info->have_more_work) + svn_hash_sets(pb->compared, + apr_pstrdup(pb->pool, db->name), ""); + break; + case svn_wc__db_status_added: + if (eb->ignore_ancestry) + db->ignoring_ancestry = TRUE; + else + db->repos_only = TRUE; + break; + default: + SVN_ERR_MALFUNCTION(); + } + + if (info->status == svn_wc__db_status_added + || info->status == svn_wc__db_status_deleted) + { + svn_wc__db_status_t base_status; + + /* Node is shadowed; check BASE */ + SVN_ERR(svn_wc__db_base_get_info(&base_status, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, + eb->db, db->local_abspath, + dir_pool, dir_pool)); + + if (base_status == svn_wc__db_status_incomplete) + db->is_incomplete = TRUE; + } } if (!db->repos_only) @@ -1714,7 +1835,7 @@ close_directory(void *dir_baton, { apr_hash_t *repos_props; - if (db->added) + if (db->added || db->is_incomplete) { repos_props = apr_hash_make(scratch_pool); } @@ -1891,6 +2012,7 @@ open_file(const char *path, switch (info->status) { case svn_wc__db_status_normal: + case svn_wc__db_status_incomplete: break; case svn_wc__db_status_deleted: fb->repos_only = TRUE; |