Modified: subversion/branches/multi-wc-format/subversion/libsvn_client/blame.c URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/libsvn_client/blame.c?rev=1897034&r1=1897033&r2=1897034&view=diff ============================================================================== --- subversion/branches/multi-wc-format/subversion/libsvn_client/blame.c (original) +++ subversion/branches/multi-wc-format/subversion/libsvn_client/blame.c Fri Jan 14 14:01:45 2022 @@ -456,7 +456,7 @@ file_rev_handler(void *baton, const char SVN_ERR_CLIENT_IS_BINARY_FILE, NULL, _("Cannot calculate blame information for binary file '%s'"), (svn_path_is_url(frb->target) - ? frb->target + ? frb->target : svn_dirent_local_style(frb->target, pool))); } } @@ -553,7 +553,7 @@ file_rev_handler(void *baton, const char || frb->include_merged_revisions); /* The file existed before start_rev; generate no blame info for - lines from this revision (or before). + lines from this revision (or before). This revision specifies the state as it was at the start revision */ @@ -656,14 +656,16 @@ normalize_blames(struct blame_chain *cha } svn_error_t * -svn_client_blame5(const char *target, +svn_client_blame6(svn_revnum_t *start_revnum_p, + svn_revnum_t *end_revnum_p, + const char *target, const svn_opt_revision_t *peg_revision, const svn_opt_revision_t *start, const svn_opt_revision_t *end, const svn_diff_file_options_t *diff_options, svn_boolean_t ignore_mime_type, svn_boolean_t include_merged_revisions, - svn_client_blame_receiver3_t receiver, + svn_client_blame_receiver4_t receiver, void *receiver_baton, svn_client_ctx_t *ctx, apr_pool_t *pool) @@ -696,10 +698,13 @@ svn_client_blame5(const char *target, SVN_ERR(svn_client__get_revision_number(&start_revnum, NULL, ctx->wc_ctx, target_abspath_or_url, ra_session, start, pool)); - + if (start_revnum_p) + *start_revnum_p = start_revnum; SVN_ERR(svn_client__get_revision_number(&end_revnum, NULL, ctx->wc_ctx, target_abspath_or_url, ra_session, end, pool)); + if (end_revnum_p) + *end_revnum_p = end_revnum; { svn_client__pathrev_t *loc; @@ -734,7 +739,7 @@ svn_client_blame5(const char *target, mime_type = svn_prop_get_value(props, SVN_PROP_MIME_TYPE); } - else + else { const svn_string_t *value; @@ -897,9 +902,9 @@ svn_client_blame5(const char *target, /* If we never created any blame for the original chain, create it now, with the most recent changed revision. This could occur if a file was created on a branch and them merged to another branch. This is - semanticly a copy, and we want to use the revision on the branch as + semantically a copy, and we want to use the revision on the branch as the most recently changed revision. ### Is this really what we want - to do here? Do the sematics of copy change? */ + to do here? Do the semantics of copy change? */ if (!frb.chain->blame) frb.chain->blame = blame_create(frb.chain, frb.last_rev, 0); @@ -941,18 +946,21 @@ svn_client_blame5(const char *target, SVN_ERR(ctx->cancel_func(ctx->cancel_baton)); if (!eof || sb->len) { + svn_string_t line; + line.data = sb->data; + line.len = sb->len; if (walk->rev) - SVN_ERR(receiver(receiver_baton, start_revnum, end_revnum, + SVN_ERR(receiver(receiver_baton, line_no, walk->rev->revision, walk->rev->rev_props, merged_rev, merged_rev_props, merged_path, - sb->data, FALSE, iterpool)); + &line, FALSE, iterpool)); else - SVN_ERR(receiver(receiver_baton, start_revnum, end_revnum, + SVN_ERR(receiver(receiver_baton, line_no, SVN_INVALID_REVNUM, NULL, SVN_INVALID_REVNUM, NULL, NULL, - sb->data, TRUE, iterpool)); + &line, TRUE, iterpool)); } if (eof) break; }
Modified: subversion/branches/multi-wc-format/subversion/libsvn_client/client.h URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/libsvn_client/client.h?rev=1897034&r1=1897033&r2=1897034&view=diff ============================================================================== --- subversion/branches/multi-wc-format/subversion/libsvn_client/client.h (original) +++ subversion/branches/multi-wc-format/subversion/libsvn_client/client.h Fri Jan 14 14:01:45 2022 @@ -877,6 +877,18 @@ svn_client__condense_commit_items(const apr_array_header_t *commit_items, apr_pool_t *pool); +/* Rewrite the COMMIT_ITEMS array to be sorted by URL. + Rewrite the items' URLs to be relative to BASE_URL. + + COMMIT_ITEMS is an array of (svn_client_commit_item3_t *) items. + + Afterwards, some of the items in COMMIT_ITEMS may contain data + allocated in POOL. */ +svn_error_t * +svn_client__condense_commit_items2(const char *base_url, + apr_array_header_t *commit_items, + apr_pool_t *pool); + /* Commit the items in the COMMIT_ITEMS array using EDITOR/EDIT_BATON to describe the committed local mods. Prior to this call, COMMIT_ITEMS should have been run through (and BASE_URL generated Modified: subversion/branches/multi-wc-format/subversion/libsvn_client/commit.c URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/libsvn_client/commit.c?rev=1897034&r1=1897033&r2=1897034&view=diff ============================================================================== --- subversion/branches/multi-wc-format/subversion/libsvn_client/commit.c (original) +++ subversion/branches/multi-wc-format/subversion/libsvn_client/commit.c Fri Jan 14 14:01:45 2022 @@ -500,6 +500,129 @@ append_externals_as_explicit_targets(apr return SVN_NO_ERROR; } +/* Crawl the working copy for commit items. + */ +static svn_error_t * +harvest_committables(apr_array_header_t **commit_items_p, + apr_hash_t **committables_by_path_p, + apr_hash_t **lock_tokens, + const char *base_dir_abspath, + const apr_array_header_t *targets, + int depth_empty_start, + svn_depth_t depth, + svn_boolean_t just_locked, + const apr_array_header_t *changelists, + svn_client_ctx_t *ctx, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) +{ + struct check_url_kind_baton cukb; + svn_client__committables_t *committables; + apr_hash_index_t *hi; + + /* Prepare for when we have a copy containing not-present nodes. */ + cukb.pool = scratch_pool; + cukb.session = NULL; /* ### Can we somehow reuse session? */ + cukb.repos_root_url = NULL; + cukb.ctx = ctx; + + SVN_ERR(svn_client__harvest_committables(&committables, lock_tokens, + base_dir_abspath, targets, + depth_empty_start, depth, + just_locked, + changelists, + check_url_kind, &cukb, + ctx, result_pool, scratch_pool)); + if (apr_hash_count(committables->by_repository) == 0) + { + *commit_items_p = NULL; + return SVN_NO_ERROR; /* Nothing to do */ + } + else if (apr_hash_count(committables->by_repository) > 1) + { + return svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL, + _("Commit can only commit to a single repository at a time.\n" + "Are all targets part of the same working copy?")); + } + + hi = apr_hash_first(scratch_pool, committables->by_repository); + *commit_items_p = apr_hash_this_val(hi); + if (committables_by_path_p) + *committables_by_path_p = committables->by_path; + return SVN_NO_ERROR; +} + +svn_error_t * +svn_client__wc_replay(const char *src_wc_abspath, + const apr_array_header_t *targets, + svn_depth_t depth, + const apr_array_header_t *changelists, + const svn_delta_editor_t *editor, + void *edit_baton, + svn_wc_notify_func2_t notify_func, + void *notify_baton, + svn_client_ctx_t *ctx, + apr_pool_t *pool) +{ + const char *base_abspath; + apr_array_header_t *rel_targets; + apr_hash_t *lock_tokens; + apr_array_header_t *commit_items; + svn_client__pathrev_t *base; + const char *base_url; + svn_wc_notify_func2_t saved_notify_func; + void *saved_notify_baton; + + /* Condense the target list. This makes all targets absolute. */ + SVN_ERR(svn_dirent_condense_targets(&base_abspath, &rel_targets, targets, + FALSE, pool, pool)); + + /* No targets means nothing to commit, so just return. */ + if (base_abspath == NULL) + return SVN_NO_ERROR; + + SVN_ERR_ASSERT(rel_targets != NULL); + + /* If we calculated only a base and no relative targets, this + must mean that we are being asked to commit (effectively) a + single path. */ + if (rel_targets->nelts == 0) + APR_ARRAY_PUSH(rel_targets, const char *) = ""; + + /* Crawl the working copy for commit items. */ + SVN_ERR(harvest_committables(&commit_items, NULL /*committables_by_path_p*/, + &lock_tokens, + base_abspath, rel_targets, + -1 /*depth_empty_start*/, + depth, + FALSE /*just_locked*/, + changelists, + ctx, pool, pool)); + if (!commit_items) + { + return SVN_NO_ERROR; + } + + SVN_ERR(svn_client__wc_node_get_base(&base, + src_wc_abspath, ctx->wc_ctx, pool, pool)); + base_url = base->url; + /* Sort our COMMIT_ITEMS by URL and find their relative URL-paths. */ + SVN_ERR(svn_client__condense_commit_items2(base_url, commit_items, pool)); + + saved_notify_func = ctx->notify_func2; + saved_notify_baton = ctx->notify_baton2; + ctx->notify_func2 = notify_func; + ctx->notify_baton2 = notify_baton; + /* BASE_URL is only used here in notifications & errors */ + SVN_ERR(svn_client__do_commit(base_url, commit_items, + editor, edit_baton, + NULL /*notify_prefix*/, NULL /*sha1_checksums*/, + ctx, pool, pool)); + ctx->notify_func2 = saved_notify_func; + ctx->notify_baton2 = saved_notify_baton; + return SVN_NO_ERROR; +} + svn_error_t * svn_client_commit6(const apr_array_header_t *targets, svn_depth_t depth, @@ -525,7 +648,7 @@ svn_client_commit6(const apr_array_heade apr_array_header_t *rel_targets; apr_array_header_t *lock_targets; apr_array_header_t *locks_obtained; - svn_client__committables_t *committables; + apr_hash_t *committables_by_path; apr_hash_t *lock_tokens; apr_hash_t *sha1_checksums; apr_array_header_t *commit_items; @@ -615,55 +738,27 @@ svn_client_commit6(const apr_array_heade pool); /* Crawl the working copy for commit items. */ - { - struct check_url_kind_baton cukb; - - /* Prepare for when we have a copy containing not-present nodes. */ - cukb.pool = iterpool; - cukb.session = NULL; /* ### Can we somehow reuse session? */ - cukb.repos_root_url = NULL; - cukb.ctx = ctx; - - cmt_err = svn_error_trace( - svn_client__harvest_committables(&committables, - &lock_tokens, - base_abspath, - rel_targets, - depth_empty_after, - depth, - ! keep_locks, - changelists, - check_url_kind, - &cukb, - ctx, - pool, - iterpool)); - - svn_pool_clear(iterpool); - } + cmt_err = svn_error_trace( + harvest_committables(&commit_items, &committables_by_path, + &lock_tokens, + base_abspath, + rel_targets, + depth_empty_after, + depth, + ! keep_locks, + changelists, + ctx, + pool, + iterpool)); + svn_pool_clear(iterpool); if (cmt_err) goto cleanup; - if (apr_hash_count(committables->by_repository) == 0) + if (!commit_items) { goto cleanup; /* Nothing to do */ } - else if (apr_hash_count(committables->by_repository) > 1) - { - cmt_err = svn_error_create( - SVN_ERR_UNSUPPORTED_FEATURE, NULL, - _("Commit can only commit to a single repository at a time.\n" - "Are all targets part of the same working copy?")); - goto cleanup; - } - - { - apr_hash_index_t *hi = apr_hash_first(iterpool, - committables->by_repository); - - commit_items = apr_hash_this_val(hi); - } /* If our array of targets contains only locks (and no actual file or prop modifications), then we return here to avoid committing a @@ -713,7 +808,7 @@ svn_client_commit6(const apr_array_heade if (moved_from_abspath && delete_op_root_abspath) { svn_client_commit_item3_t *delete_half = - svn_hash_gets(committables->by_path, delete_op_root_abspath); + svn_hash_gets(committables_by_path, delete_op_root_abspath); if (!delete_half) { @@ -769,7 +864,7 @@ svn_client_commit6(const apr_array_heade if (moved_to_abspath && copy_op_root_abspath && strcmp(moved_to_abspath, copy_op_root_abspath) == 0 && - svn_hash_gets(committables->by_path, copy_op_root_abspath) + svn_hash_gets(committables_by_path, copy_op_root_abspath) == NULL) { cmt_err = svn_error_createf( Modified: subversion/branches/multi-wc-format/subversion/libsvn_client/commit_util.c URL: http://svn.apache.org/viewvc/subversion/branches/multi-wc-format/subversion/libsvn_client/commit_util.c?rev=1897034&r1=1897033&r2=1897034&view=diff ============================================================================== --- subversion/branches/multi-wc-format/subversion/libsvn_client/commit_util.c (original) +++ subversion/branches/multi-wc-format/subversion/libsvn_client/commit_util.c Fri Jan 14 14:01:45 2022 @@ -1392,6 +1392,29 @@ sort_commit_item_urls(const void *a, con } +svn_error_t * +svn_client__condense_commit_items2(const char *base_url, + apr_array_header_t *commit_items, + apr_pool_t *pool) +{ + apr_array_header_t *ci = commit_items; /* convenience */ + int i; + + /* Sort our commit items by their URLs. */ + svn_sort__array(ci, sort_commit_item_urls); + + /* Hack BASE_URL off each URL; store the result as session_relpath. */ + for (i = 0; i < ci->nelts; i++) + { + svn_client_commit_item3_t *this_item + = APR_ARRAY_IDX(ci, i, svn_client_commit_item3_t *); + + this_item->session_relpath = svn_uri_skip_ancestor(base_url, + this_item->url, pool); + } + + return SVN_NO_ERROR; +} svn_error_t * svn_client__condense_commit_items(const char **base_url, @@ -1501,8 +1524,6 @@ struct file_mod_t /* A baton for use while driving a path-based editor driver for commit */ struct item_commit_baton { - const svn_delta_editor_t *editor; /* commit editor */ - void *edit_baton; /* commit editor's baton */ apr_hash_t *file_mods; /* hash: path->file_mod_t */ const char *notify_path_prefix; /* notification path prefix (NULL is okay, else abs path) */ @@ -1524,6 +1545,8 @@ struct item_commit_baton * This implements svn_delta_path_driver_cb_func_t. */ static svn_error_t * do_item_commit(void **dir_baton, + const svn_delta_editor_t *editor, + void *edit_baton, void *parent_baton, void *callback_baton, const char *path, @@ -1535,7 +1558,6 @@ do_item_commit(void **dir_baton, svn_node_kind_t kind = item->kind; void *file_baton = NULL; apr_pool_t *file_pool = NULL; - const svn_delta_editor_t *editor = icb->editor; apr_hash_t *file_mods = icb->file_mods; svn_client_ctx_t *ctx = icb->ctx; svn_error_t *err; @@ -1737,7 +1759,7 @@ do_item_commit(void **dir_baton, { if (! parent_baton) { - err = editor->open_root(icb->edit_baton, item->revision, + err = editor->open_root(edit_baton, item->revision, pool, dir_baton); } else @@ -1871,8 +1893,6 @@ svn_client__do_commit(const char *base_u } /* Setup the callback baton. */ - cb_baton.editor = editor; - cb_baton.edit_baton = edit_baton; cb_baton.file_mods = file_mods; cb_baton.notify_path_prefix = notify_path_prefix; cb_baton.ctx = ctx; @@ -1880,7 +1900,7 @@ svn_client__do_commit(const char *base_u cb_baton.base_url = base_url; /* Drive the commit editor! */ - SVN_ERR(svn_delta_path_driver2(editor, edit_baton, paths, TRUE, + SVN_ERR(svn_delta_path_driver3(editor, edit_baton, paths, TRUE, do_item_commit, &cb_baton, scratch_pool)); /* Transmit outstanding text deltas. */ @@ -2011,7 +2031,7 @@ svn_client__get_log_msg(const char **log old_item->kind = item->kind; old_item->url = item->url; /* The pre-1.3 API used the revision field for copyfrom_rev - and revision depeding of copyfrom_url. */ + and revision depending of copyfrom_url. */ old_item->revision = item->copyfrom_url ? item->copyfrom_rev : item->revision; old_item->copyfrom_url = item->copyfrom_url;
