I (Julian Foad) wrote: > I was just cleaning up this editor, stripping out this "target" path > completely, so that it would simply pass relative paths out to the diff > callbacks and to the notification functions. The merge code knows what > WC path this diff relates to, and so can add the prefix itself inside > its callbacks. That will keep the knowledge about the WC completely > separate from the repos-diff editor, which is a good thing. [...]
Attached is my patch in progress to strip WC path info from the repos-repos diff editor. - Julian
### Patch in progress to remove WC path knowledge from the repos-repos diff editor. Doesn't yet patch up the path in the notification callback. * subversion/libsvn_client/merge.c (merge_dir_props_changed, merge_file_changed, merge_file_added, merge_file_deleted, merge_dir_added, merge_dir_deleted, merge_dir_opened): Assume the received path is relative to the target and so derive the WC abspath. * subversion/libsvn_client/repos_diff.c (edit_baton, dir_baton, file_baton, make_dir_baton, make_file_baton): Remove the 'target' and 'wcpath' paths. (diff_deleted_dir, delete_entry, add_directory, open_directory, open_file, close_file, close_directory, absent_directory, absent_file): Send the relative path, no longer prefixing it with the 'target' path. (svn_client__get_diff_editor): Ignore the 'target' parameter. --This line, and those below, will be ignored-- Index: subversion/libsvn_client/merge.c =================================================================== --- subversion/libsvn_client/merge.c (revision 1162064) +++ subversion/libsvn_client/merge.c (working copy) @@ -1244,7 +1244,7 @@ merge_props_changed(svn_wc_notify_state_ static svn_error_t * merge_dir_props_changed(svn_wc_notify_state_t *state, svn_boolean_t *tree_conflicted, - const char *local_abspath, + const char *source_relpath, svn_boolean_t dir_was_added, const apr_array_header_t *propchanges, apr_hash_t *original_props, @@ -1252,6 +1252,8 @@ merge_dir_props_changed(svn_wc_notify_st apr_pool_t *scratch_pool) { merge_cmd_baton_t *merge_b = diff_baton; + const char *local_abspath = svn_dirent_join(merge_b->target_abspath, + source_relpath, scratch_pool); svn_wc_notify_state_t obstr_state; SVN_ERR(perform_obstruction_check(&obstr_state, NULL, NULL, @@ -1420,7 +1422,7 @@ static svn_error_t * merge_file_changed(svn_wc_notify_state_t *content_state, svn_wc_notify_state_t *prop_state, svn_boolean_t *tree_conflicted, - const char *mine_abspath, + const char *source_relpath, const char *older_abspath, const char *yours_abspath, svn_revnum_t older_rev, @@ -1433,6 +1435,8 @@ merge_file_changed(svn_wc_notify_state_t apr_pool_t *scratch_pool) { merge_cmd_baton_t *merge_b = baton; + const char *mine_abspath = svn_dirent_join(merge_b->target_abspath, + source_relpath, scratch_pool); enum svn_wc_merge_outcome_t merge_outcome; svn_node_kind_t wc_kind; svn_boolean_t is_deleted; @@ -1646,7 +1650,7 @@ static svn_error_t * merge_file_added(svn_wc_notify_state_t *content_state, svn_wc_notify_state_t *prop_state, svn_boolean_t *tree_conflicted, - const char *mine_abspath, + const char *source_relpath, const char *older_abspath, const char *yours_abspath, svn_revnum_t rev1, @@ -1661,6 +1665,8 @@ merge_file_added(svn_wc_notify_state_t * apr_pool_t *scratch_pool) { merge_cmd_baton_t *merge_b = baton; + const char *mine_abspath = svn_dirent_join(merge_b->target_abspath, + source_relpath, scratch_pool); svn_node_kind_t kind; int i; apr_hash_t *file_props; @@ -1981,7 +1987,7 @@ files_same_p(svn_boolean_t *same, static svn_error_t * merge_file_deleted(svn_wc_notify_state_t *state, svn_boolean_t *tree_conflicted, - const char *mine_abspath, + const char *source_relpath, const char *older_abspath, const char *yours_abspath, const char *mimetype1, @@ -1991,6 +1997,8 @@ merge_file_deleted(svn_wc_notify_state_t apr_pool_t *scratch_pool) { merge_cmd_baton_t *merge_b = baton; + const char *mine_abspath = svn_dirent_join(merge_b->target_abspath, + source_relpath, scratch_pool); svn_node_kind_t kind; svn_boolean_t moved_away; svn_wc_conflict_reason_t reason; @@ -2112,7 +2120,7 @@ merge_dir_added(svn_wc_notify_state_t *s svn_boolean_t *tree_conflicted, svn_boolean_t *skip, svn_boolean_t *skip_children, - const char *local_abspath, + const char *source_relpath, svn_revnum_t rev, const char *copyfrom_path, svn_revnum_t copyfrom_revision, @@ -2120,6 +2128,8 @@ merge_dir_added(svn_wc_notify_state_t *s apr_pool_t *scratch_pool) { merge_cmd_baton_t *merge_b = baton; + const char *local_abspath = svn_dirent_join(merge_b->target_abspath, + source_relpath, scratch_pool); svn_node_kind_t kind; const char *copyfrom_url = NULL, *child; svn_revnum_t copyfrom_rev = SVN_INVALID_REVNUM; @@ -2314,11 +2324,13 @@ merge_dir_added(svn_wc_notify_state_t *s static svn_error_t * merge_dir_deleted(svn_wc_notify_state_t *state, svn_boolean_t *tree_conflicted, - const char *local_abspath, + const char *source_relpath, void *baton, apr_pool_t *scratch_pool) { merge_cmd_baton_t *merge_b = baton; + const char *local_abspath = svn_dirent_join(merge_b->target_abspath, + source_relpath, scratch_pool); svn_node_kind_t kind; svn_error_t *err; svn_boolean_t is_versioned; @@ -2454,12 +2466,14 @@ static svn_error_t * merge_dir_opened(svn_boolean_t *tree_conflicted, svn_boolean_t *skip, svn_boolean_t *skip_children, - const char *local_abspath, + const char *source_relpath, svn_revnum_t rev, void *baton, apr_pool_t *scratch_pool) { merge_cmd_baton_t *merge_b = baton; + const char *local_abspath = svn_dirent_join(merge_b->target_abspath, + source_relpath, scratch_pool); svn_depth_t parent_depth; svn_node_kind_t wc_kind; svn_wc_notify_state_t obstr_state; Index: subversion/libsvn_client/repos_diff.c =================================================================== --- subversion/libsvn_client/repos_diff.c (revision 1162065) +++ subversion/libsvn_client/repos_diff.c (working copy) @@ -51,10 +51,6 @@ /* Overall crawler editor baton. */ struct edit_baton { - /* TARGET is a working-copy directory which corresponds to the base - URL open in RA_SESSION below. */ - const char *target; - /* A working copy context for TARGET, NULL if this is purely a repository operation. */ svn_wc_context_t *wc_ctx; @@ -140,9 +136,6 @@ struct dir_baton { /* The path of the directory within the repository */ const char *path; - /* The path of the directory in the wc, relative to cwd */ - const char *wcpath; - /* The baton for the parent directory, or null if this is the root of the hierarchy to be compared. */ struct dir_baton *dir_baton; @@ -179,9 +172,6 @@ struct file_baton { /* The path of the file within the repository */ const char *path; - /* The path of the file in the wc, relative to cwd */ - const char *wcpath; - /* The path and APR file handle to the temporary file that contains the first repository version. Also, the pristine-property list of this file. */ @@ -242,7 +232,6 @@ make_dir_baton(const char *path, dir_baton->skip_children = FALSE; dir_baton->pool = dir_pool; dir_baton->path = apr_pstrdup(dir_pool, path); - dir_baton->wcpath = svn_dirent_join(edit_baton->target, path, dir_pool); dir_baton->propchanges = apr_array_make(pool, 1, sizeof(svn_prop_t)); return dir_baton; @@ -268,7 +257,6 @@ make_file_baton(const char *path, file_baton->skip = FALSE; file_baton->pool = file_pool; file_baton->path = apr_pstrdup(file_pool, path); - file_baton->wcpath = svn_dirent_join(edit_baton->target, path, file_pool); file_baton->propchanges = apr_array_make(pool, 1, sizeof(svn_prop_t)); file_baton->base_revision = edit_baton->revision; @@ -557,7 +545,7 @@ diff_deleted_dir(const char *dir, get_file_mime_types(&mimetype1, &mimetype2, b); SVN_ERR(eb->diff_callbacks->file_deleted( - NULL, NULL, b->wcpath, + NULL, NULL, b->path, b->path_start_revision, b->path_end_revision, mimetype1, mimetype2, @@ -568,10 +556,8 @@ diff_deleted_dir(const char *dir, if (dirent->kind == svn_node_dir) { - const char *wcpath = svn_dirent_join(eb->target, path, iterpool); - SVN_ERR(eb->diff_callbacks->dir_deleted( - NULL, NULL, wcpath, + NULL, NULL, path, eb->diff_cmd_baton, iterpool)); SVN_ERR(diff_deleted_dir(path, revision, @@ -632,7 +618,7 @@ delete_entry(const char *path, get_file_mime_types(&mimetype1, &mimetype2, b); SVN_ERR(eb->diff_callbacks->file_deleted( - &state, &tree_conflicted, b->wcpath, + &state, &tree_conflicted, b->path, b->path_start_revision, b->path_end_revision, mimetype1, mimetype2, @@ -646,7 +632,7 @@ delete_entry(const char *path, { SVN_ERR(eb->diff_callbacks->dir_deleted( &state, &tree_conflicted, - svn_dirent_join(eb->target, path, pool), + path, eb->diff_cmd_baton, scratch_pool)); if (eb->walk_deleted_repos_dirs) @@ -677,9 +663,9 @@ delete_entry(const char *path, if (eb->notify_func) { - const char* deleted_path; + const char *deleted_path = apr_pstrdup(eb->pool, path); deleted_path_notify_t *dpn = apr_pcalloc(eb->pool, sizeof(*dpn)); - deleted_path = svn_dirent_join(eb->target, path, eb->pool); + dpn->kind = kind; dpn->action = tree_conflicted ? svn_wc_notify_tree_conflict : action; dpn->state = state; @@ -723,7 +709,7 @@ add_directory(const char *path, SVN_ERR(eb->diff_callbacks->dir_added( &state, &b->tree_conflicted, - &b->skip, &b->skip_children, b->wcpath, + &b->skip, &b->skip_children, b->path, eb->target_revision, copyfrom_path, copyfrom_revision, eb->diff_cmd_baton, pool)); @@ -742,12 +728,12 @@ add_directory(const char *path, /* Find out if a pending delete notification for this path is * still around. */ - dpn = apr_hash_get(eb->deleted_paths, b->wcpath, APR_HASH_KEY_STRING); + dpn = apr_hash_get(eb->deleted_paths, b->path, APR_HASH_KEY_STRING); if (dpn) { /* If any was found, we will handle the pending 'deleted path * notification' (DPN) here. Remove it from the list. */ - apr_hash_set(eb->deleted_paths, b->wcpath, + apr_hash_set(eb->deleted_paths, b->path, APR_HASH_KEY_STRING, NULL); /* the pending delete might be on a different node kind. */ @@ -773,7 +759,7 @@ add_directory(const char *path, else action = svn_wc_notify_update_add; - notify = svn_wc_create_notify(b->wcpath, action, pool); + notify = svn_wc_create_notify(b->path, action, pool); notify->kind = kind; notify->content_state = notify->prop_state = state; (*eb->notify_func)(eb->notify_baton, notify, pool); @@ -809,7 +795,7 @@ open_directory(const char *path, SVN_ERR(eb->diff_callbacks->dir_opened( &b->tree_conflicted, &b->skip, - &b->skip_children, b->wcpath, base_revision, + &b->skip_children, b->path, base_revision, b->edit_baton->diff_cmd_baton, pool)); return SVN_NO_ERROR; @@ -872,7 +858,7 @@ open_file(const char *path, SVN_ERR(eb->diff_callbacks->file_opened( &b->tree_conflicted, &b->skip, - b->wcpath, base_revision, eb->diff_cmd_baton, pool)); + b->path, base_revision, eb->diff_cmd_baton, pool)); return SVN_NO_ERROR; } @@ -1043,7 +1029,7 @@ close_file(void *file_baton, if (b->added) SVN_ERR(eb->diff_callbacks->file_added( &content_state, &prop_state, &b->tree_conflicted, - b->wcpath, + b->path, b->path_end_revision ? b->path_start_revision : NULL, b->path_end_revision, 0, @@ -1056,7 +1042,7 @@ close_file(void *file_baton, else SVN_ERR(eb->diff_callbacks->file_changed( &content_state, &prop_state, - &b->tree_conflicted, b->wcpath, + &b->tree_conflicted, b->path, b->path_end_revision ? b->path_start_revision : NULL, b->path_end_revision, b->edit_baton->revision, @@ -1074,16 +1060,15 @@ close_file(void *file_baton, svn_wc_notify_t *notify; svn_wc_notify_action_t action; svn_node_kind_t kind = svn_node_file; - const char *moved_to_abspath = NULL; /* Find out if a pending delete notification for this path is * still around. */ - dpn = apr_hash_get(eb->deleted_paths, b->wcpath, APR_HASH_KEY_STRING); + dpn = apr_hash_get(eb->deleted_paths, b->path, APR_HASH_KEY_STRING); if (dpn) { /* If any was found, we will handle the pending 'deleted path * notification' (DPN) here. Remove it from the list. */ - apr_hash_set(eb->deleted_paths, b->wcpath, + apr_hash_set(eb->deleted_paths, b->path, APR_HASH_KEY_STRING, NULL); /* the pending delete might be on a different node kind. */ @@ -1110,30 +1095,9 @@ close_file(void *file_baton, else if (b->added) action = svn_wc_notify_update_add; else - { - svn_error_t *err; - - action = svn_wc_notify_update_update; - - /* If the file was moved-away, use its new path in the - * notification. - * ### This is redundant. The file_changed() callback should - * ### pass the moved-to path back up here. */ - err = svn_wc__node_was_moved_away(&moved_to_abspath, NULL, - eb->wc_ctx, b->wcpath, - scratch_pool, scratch_pool); - if (err) - { - if (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND) - svn_error_clear(err); - else - return svn_error_trace(err); - } - } + action = svn_wc_notify_update_update; - notify = svn_wc_create_notify(moved_to_abspath ? moved_to_abspath - : b->wcpath, - action, scratch_pool); + notify = svn_wc_create_notify(b->path, action, scratch_pool); notify->kind = kind; notify->content_state = content_state; notify->prop_state = prop_state; @@ -1181,7 +1145,7 @@ close_directory(void *dir_baton, svn_boolean_t tree_conflicted = FALSE; SVN_ERR(eb->diff_callbacks->dir_props_changed( &prop_state, &tree_conflicted, - b->wcpath, b->added, + b->path, b->added, b->propchanges, b->pristine_props, b->edit_baton->diff_cmd_baton, scratch_pool)); if (tree_conflicted) @@ -1196,7 +1160,7 @@ close_directory(void *dir_baton, } SVN_ERR(eb->diff_callbacks->dir_closed(NULL, NULL, NULL, - b->wcpath, b->added, + b->path, b->added, b->edit_baton->diff_cmd_baton, scratch_pool)); @@ -1237,7 +1201,7 @@ close_directory(void *dir_baton, else action = svn_wc_notify_update_update; - notify = svn_wc_create_notify(b->wcpath, action, pool); + notify = svn_wc_create_notify(b->path, action, pool); notify->kind = svn_node_dir; /* In case of a tree conflict during merge, the diff callback @@ -1330,11 +1294,8 @@ absent_directory(const char *path, if (eb->notify_func) { svn_wc_notify_t *notify - = svn_wc_create_notify(svn_dirent_join(pb->wcpath, - svn_relpath_basename(path, - NULL), - pool), - svn_wc_notify_skip, pool); + = svn_wc_create_notify(path, svn_wc_notify_skip, pool); + notify->kind = svn_node_dir; notify->content_state = notify->prop_state = svn_wc_notify_state_missing; @@ -1360,11 +1321,8 @@ absent_file(const char *path, if (eb->notify_func) { svn_wc_notify_t *notify - = svn_wc_create_notify(svn_dirent_join(pb->wcpath, - svn_relpath_basename(path, - pool), - pool), - svn_wc_notify_skip, pool); + = svn_wc_create_notify(path, svn_wc_notify_skip, pool); + notify->kind = svn_node_file; notify->content_state = notify->prop_state = svn_wc_notify_state_missing; @@ -1396,12 +1354,9 @@ svn_client__get_diff_editor(const svn_de apr_pool_t *editor_pool = svn_pool_create(result_pool); svn_delta_editor_t *tree_editor = svn_delta_default_editor(editor_pool); struct edit_baton *eb = apr_pcalloc(editor_pool, sizeof(*eb)); - const char *target_abspath; - - SVN_ERR(svn_dirent_get_absolute(&target_abspath, target, editor_pool)); + SVN_DBG(("target '%s'\n", target)); eb->pool = editor_pool; - eb->target = target; eb->wc_ctx = wc_ctx; eb->depth = depth; eb->diff_callbacks = diff_callbacks;