You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by vm...@apache.org on 2012/12/23 19:34:20 UTC
svn commit: r1425508 [13/17] - in /subversion/branches/javahl-ra: ./ build/
build/ac-macros/ build/generator/ build/generator/templates/ build/hudson/
notes/ notes/api-errata/1.8/ notes/obliterate/ notes/tree-conflicts/
subversion/ subversion/bindings/...
Modified: subversion/branches/javahl-ra/subversion/mod_dav_svn/mod_dav_svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/mod_dav_svn/mod_dav_svn.c?rev=1425508&r1=1425507&r2=1425508&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/mod_dav_svn/mod_dav_svn.c (original)
+++ subversion/branches/javahl-ra/subversion/mod_dav_svn/mod_dav_svn.c Sun Dec 23 18:34:14 2012
@@ -88,6 +88,7 @@ typedef struct dir_conf_t {
enum conf_flag autoversioning; /* whether autoversioning is active */
enum conf_flag bulk_updates; /* whether bulk updates are allowed */
enum conf_flag v2_protocol; /* whether HTTP v2 is advertised */
+ enum conf_flag ephemeral_txnprops; /* advertise ephemeral txnprop support? */
enum path_authz_conf path_authz_method; /* how GET subrequests are handled */
enum conf_flag list_parentpath; /* whether to allow GET of parentpath */
const char *root_dir; /* our top-level directory */
@@ -96,7 +97,7 @@ typedef struct dir_conf_t {
enum conf_flag txdelta_cache; /* whether to enable txdelta caching */
enum conf_flag fulltext_cache; /* whether to enable fulltext caching */
enum conf_flag revprop_cache; /* whether to enable revprop caching */
- apr_hash_t *hooks_env; /* environment for hook scripts */
+ const char *hooks_env; /* path to hook script env config file */
} dir_conf_t;
@@ -196,6 +197,7 @@ create_dir_config(apr_pool_t *p, char *d
conf->root_dir = svn_urlpath__canonicalize(dir, p);
conf->bulk_updates = CONF_FLAG_ON;
conf->v2_protocol = CONF_FLAG_ON;
+ conf->ephemeral_txnprops = CONF_FLAG_ON;
conf->hooks_env = NULL;
return conf;
@@ -221,6 +223,8 @@ merge_dir_config(apr_pool_t *p, void *ba
newconf->autoversioning = INHERIT_VALUE(parent, child, autoversioning);
newconf->bulk_updates = INHERIT_VALUE(parent, child, bulk_updates);
newconf->v2_protocol = INHERIT_VALUE(parent, child, v2_protocol);
+ newconf->ephemeral_txnprops = INHERIT_VALUE(parent, child,
+ ephemeral_txnprops);
newconf->path_authz_method = INHERIT_VALUE(parent, child, path_authz_method);
newconf->list_parentpath = INHERIT_VALUE(parent, child, list_parentpath);
newconf->txdelta_cache = INHERIT_VALUE(parent, child, txdelta_cache);
@@ -346,6 +350,20 @@ SVNAdvertiseV2Protocol_cmd(cmd_parms *cm
static const char *
+SVNAdvertiseEphemeralTXNProps_cmd(cmd_parms *cmd, void *config, int arg)
+{
+ dir_conf_t *conf = config;
+
+ if (arg)
+ conf->ephemeral_txnprops = CONF_FLAG_ON;
+ else
+ conf->ephemeral_txnprops = CONF_FLAG_OFF;
+
+ return NULL;
+}
+
+
+static const char *
SVNPathAuthz_cmd(cmd_parms *cmd, void *config, const char *arg1)
{
dir_conf_t *conf = config;
@@ -550,43 +568,9 @@ SVNUseUTF8_cmd(cmd_parms *cmd, void *con
static const char *
SVNHooksEnv_cmd(cmd_parms *cmd, void *config, const char *arg1)
{
- apr_array_header_t *var;
-
- var = svn_cstring_split(arg1, "=", TRUE, cmd->pool);
- if (var && var->nelts >= 2)
- {
- dir_conf_t *conf = config;
- const char *name;
- const char *val;
-
- if (! conf->hooks_env)
- conf->hooks_env = apr_hash_make(cmd->pool);
-
- name = apr_pstrdup(apr_hash_pool_get(conf->hooks_env),
- APR_ARRAY_IDX(var, 0, const char *));
-
- /* Special case for values which contain '='. */
- if (var->nelts > 2)
- {
- svn_stringbuf_t *buf;
- int i;
-
- buf = svn_stringbuf_create(APR_ARRAY_IDX(var, 1, const char *),
- cmd->pool);
- for (i = 2; i < var->nelts; i++)
- {
- svn_stringbuf_appendbyte(buf, '=');
- svn_stringbuf_appendcstr(buf, APR_ARRAY_IDX(var, i, const char *));
- }
-
- val = apr_pstrdup(apr_hash_pool_get(conf->hooks_env), buf->data);
- }
- else
- val = apr_pstrdup(apr_hash_pool_get(conf->hooks_env),
- APR_ARRAY_IDX(var, 1, const char *));
+ dir_conf_t *conf = config;
- apr_hash_set(conf->hooks_env, name, APR_HASH_KEY_STRING, val);
- }
+ conf->hooks_env = svn_dirent_internal_style(arg1, cmd->pool);
return NULL;
}
@@ -795,6 +779,16 @@ dav_svn__get_v2_protocol_flag(request_re
}
+svn_boolean_t
+dav_svn__get_ephemeral_txnprops_flag(request_rec *r)
+{
+ dir_conf_t *conf;
+
+ conf = ap_get_module_config(r->per_dir_config, &dav_svn_module);
+ return conf->ephemeral_txnprops == CONF_FLAG_ON;
+}
+
+
/* FALSE if path authorization should be skipped.
* TRUE if either the bypass or the apache subrequest methods should be used.
*/
@@ -878,7 +872,7 @@ dav_svn__get_compression_level(void)
return svn__compression_level;
}
-apr_hash_t *
+const char *
dav_svn__get_hooks_env(request_rec *r)
{
dir_conf_t *conf;
@@ -1095,6 +1089,12 @@ static const command_rec cmds[] =
"Subversion's HTTP protocol (default values is On)."),
/* per directory/location */
+ AP_INIT_FLAG("SVNAdvertiseEphemeralTXNProps",
+ SVNAdvertiseEphemeralTXNProps_cmd, NULL, ACCESS_CONF|RSRC_CONF,
+ "enables server advertising of support for ephemeral "
+ "commit transaction properties (default value is On)."),
+
+ /* per directory/location */
AP_INIT_FLAG("SVNCacheTextDeltas", SVNCacheTextDeltas_cmd, NULL,
ACCESS_CONF|RSRC_CONF,
"speeds up data access to older revisions by caching "
@@ -1136,10 +1136,12 @@ static const command_rec cmds[] =
"use UTF-8 as native character encoding (default is ASCII)."),
/* per directory/location */
- AP_INIT_ITERATE("SVNHooksEnv", SVNHooksEnv_cmd, NULL,
- ACCESS_CONF|RSRC_CONF,
- "Set the environment of hook scripts via any number of "
- "VAR=VAL arguments (the default hook environment is empty)."),
+ AP_INIT_TAKE1("SVNHooksEnv", SVNHooksEnv_cmd, NULL,
+ ACCESS_CONF|RSRC_CONF,
+ "Sets the path to the configuration file for the environment "
+ "of hook scripts. If not absolute, the path is relative to "
+ "the repository's conf directory (by default the hooks-env "
+ "file in the repository is used)."),
{ NULL }
};
Modified: subversion/branches/javahl-ra/subversion/mod_dav_svn/reports/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/mod_dav_svn/reports/update.c?rev=1425508&r1=1425507&r2=1425508&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/mod_dav_svn/reports/update.c (original)
+++ subversion/branches/javahl-ra/subversion/mod_dav_svn/reports/update.c Sun Dec 23 18:34:14 2012
@@ -1219,7 +1219,7 @@ dav_svn__update_report(const dav_resourc
editor->close_file = upd_close_file;
editor->absent_file = upd_absent_file;
editor->close_edit = upd_close_edit;
- if ((serr = svn_repos_begin_report2(&rbaton, revnum,
+ if ((serr = svn_repos_begin_report3(&rbaton, revnum,
repos->repos,
src_path, target,
dst_path,
@@ -1230,6 +1230,7 @@ dav_svn__update_report(const dav_resourc
editor, &uc,
dav_svn__authz_read_func(&arb),
&arb,
+ 0, /* disable zero-copy for now */
resource->pool)))
{
return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
Modified: subversion/branches/javahl-ra/subversion/mod_dav_svn/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/mod_dav_svn/repos.c?rev=1425508&r1=1425507&r2=1425508&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/mod_dav_svn/repos.c (original)
+++ subversion/branches/javahl-ra/subversion/mod_dav_svn/repos.c Sun Dec 23 18:34:14 2012
@@ -1149,8 +1149,11 @@ create_private_resource(const dav_resour
comb->res.collection = TRUE; /* ### always true? */
/* versioned = baselined = working = FALSE */
- comb->res.uri = apr_pstrcat(base->pool, base->info->repos->root_path,
- path->data, (char *)NULL);
+ if (base->info->repos->root_path[1])
+ comb->res.uri = apr_pstrcat(base->pool, base->info->repos->root_path,
+ path->data, (char *)NULL);
+ else
+ comb->res.uri = path->data;
comb->res.info = &comb->priv;
comb->res.hooks = &dav_svn__hooks_repository;
comb->res.pool = base->pool;
@@ -1908,9 +1911,11 @@ parse_querystring(request_rec *r, const
only use a temporary redirect. */
apr_table_setn(r->headers_out, "Location",
ap_construct_url(r->pool,
- apr_psprintf(r->pool, "%s%s?p=%ld",
- comb->priv.repos->root_path,
- newpath, working_rev),
+ apr_psprintf(r->pool, "%s%s?p=%ld",
+ (comb->priv.repos->root_path[1]
+ ? comb->priv.repos->root_path
+ : ""),
+ newpath, working_rev),
r));
return dav_svn__new_error(r->pool,
prevstr ? HTTP_MOVED_PERMANENTLY
@@ -2217,8 +2222,9 @@ get_resource(request_rec *r,
HTTP_INTERNAL_SERVER_ERROR, r);
}
- /* Configure the hooks environment, if not empty. */
- svn_repos_hooks_setenv(repos->repos, dav_svn__get_hooks_env(r));
+ /* Configure hook script environment variables. */
+ svn_repos_hooks_setenv(repos->repos, dav_svn__get_hooks_env(r),
+ r->connection->pool, r->pool);
}
/* cache the filesystem object */
@@ -3077,6 +3083,13 @@ set_headers(request_rec *r, const dav_re
if ((serr == NULL) && (info.rev != SVN_INVALID_REVNUM))
{
mimetype = SVN_SVNDIFF_MIME_TYPE;
+
+ /* Note the base that this svndiff is based on, and tell any
+ intermediate caching proxies that this header is
+ significant. */
+ apr_table_setn(r->headers_out, "Vary", SVN_DAV_DELTA_BASE_HEADER);
+ apr_table_setn(r->headers_out, SVN_DAV_DELTA_BASE_HEADER,
+ resource->info->delta_base);
}
svn_error_clear(serr);
}
@@ -4345,8 +4358,11 @@ dav_svn__create_working_resource(dav_res
res->baselined = base->baselined;
/* collection = FALSE. ### not necessarily correct */
- res->uri = apr_pstrcat(base->pool, base->info->repos->root_path,
- path, (char *)NULL);
+ if (base->info->repos->root_path[1])
+ res->uri = apr_pstrcat(base->pool, base->info->repos->root_path,
+ path, (char *)NULL);
+ else
+ res->uri = path;
res->hooks = &dav_svn__hooks_repository;
res->pool = base->pool;
Modified: subversion/branches/javahl-ra/subversion/mod_dav_svn/version.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/mod_dav_svn/version.c?rev=1425508&r1=1425507&r2=1425508&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/mod_dav_svn/version.c (original)
+++ subversion/branches/javahl-ra/subversion/mod_dav_svn/version.c Sun Dec 23 18:34:14 2012
@@ -146,6 +146,7 @@ get_vsn_options(apr_pool_t *p, apr_text_
apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_LOG_REVPROPS);
apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_ATOMIC_REVPROPS);
apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_PARTIAL_REPLAY);
+ apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_INHERITED_PROPS);
/* Mergeinfo is a special case: here we merely say that the server
* knows how to handle mergeinfo -- whether the repository does too
* is a separate matter.
@@ -192,6 +193,14 @@ get_option(const dav_resource *resource,
}
}
+ /* If we're allowed (by configuration) to do so, advertise support
+ for ephemeral transaction properties. */
+ if (dav_svn__get_ephemeral_txnprops_flag(r))
+ {
+ apr_table_addn(r->headers_out, "DAV",
+ SVN_DAV_NS_DAV_SVN_EPHEMERAL_TXNPROPS);
+ }
+
if (resource->info->repos->fs)
{
svn_error_t *serr;
@@ -1112,6 +1121,10 @@ deliver_report(request_rec *r,
{
return dav_svn__get_deleted_rev_report(resource, doc, output);
}
+ else if (strcmp(doc->root->name, SVN_DAV__INHERITED_PROPS_REPORT) == 0)
+ {
+ return dav_svn__get_inherited_props_report(resource, doc, output);
+ }
/* NOTE: if you add a report, don't forget to add it to the
* dav_svn__reports_list[] array.
*/
Modified: subversion/branches/javahl-ra/subversion/svn/cl.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/svn/cl.h?rev=1425508&r1=1425507&r2=1425508&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/svn/cl.h (original)
+++ subversion/branches/javahl-ra/subversion/svn/cl.h Sun Dec 23 18:34:14 2012
@@ -236,11 +236,8 @@ typedef struct svn_cl__opt_state_t
svn_boolean_t show_diff; /* produce diff output (maps to --diff) */
svn_boolean_t allow_mixed_rev; /* Allow operation on mixed-revision WC */
svn_boolean_t include_externals; /* Recurses (in)to file & dir externals */
- const char *search_pattern; /* pattern argument for --search */
- svn_boolean_t case_insensitive_search; /* perform case-insensitive search */
-
- svn_wc_conflict_resolver_func2_t conflict_func;
- void *conflict_baton;
+ svn_boolean_t show_inherited_props; /* get inherited properties */
+ apr_array_header_t* search_patterns; /* pattern arguments for --search */
} svn_cl__opt_state_t;
@@ -333,37 +330,58 @@ svn_cl__check_cancel(void *baton);
/* Various conflict-resolution callbacks. */
-typedef struct svn_cl__conflict_baton_t {
- svn_cl__accept_t accept_which;
- apr_hash_t *config;
- const char *editor_cmd;
- svn_boolean_t external_failed;
- svn_cmdline_prompt_baton_t *pb;
- const char *path_prefix;
-} svn_cl__conflict_baton_t;
-
-/* Create and return a conflict baton in *B, allocated from POOL, with the
- * values ACCEPT_WHICH, CONFIG, EDITOR_CMD and PB placed in the same-named
- * fields of the baton, and its 'external_failed' field initialised to FALSE. */
-svn_error_t *
-svn_cl__conflict_baton_make(svn_cl__conflict_baton_t **b,
- svn_cl__accept_t accept_which,
- apr_hash_t *config,
- const char *editor_cmd,
- svn_cmdline_prompt_baton_t *pb,
- apr_pool_t *pool);
+/* Opaque baton type for svn_cl__conflict_func_interactive(). */
+typedef struct svn_cl__interactive_conflict_baton_t
+ svn_cl__interactive_conflict_baton_t;
+
+/* Create and return an baton for use with svn_cl__conflict_func_interactive
+ * in *B, allocated from RESULT_POOL, and initialised with the values
+ * ACCEPT_WHICH, CONFIG, EDITOR_CMD, CANCEL_FUNC and CANCEL_BATON. */
+svn_error_t *
+svn_cl__get_conflict_func_interactive_baton(
+ svn_cl__interactive_conflict_baton_t **b,
+ svn_cl__accept_t accept_which,
+ apr_hash_t *config,
+ const char *editor_cmd,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ apr_pool_t *result_pool);
/* A conflict-resolution callback which prompts the user to choose
one of the 3 fulltexts, edit the merged file on the spot, or just
skip the conflict (to be resolved later).
Implements @c svn_wc_conflict_resolver_func_t. */
svn_error_t *
-svn_cl__conflict_handler(svn_wc_conflict_result_t **result,
- const svn_wc_conflict_description2_t *desc,
- void *baton,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool);
-
+svn_cl__conflict_func_interactive(svn_wc_conflict_result_t **result,
+ const svn_wc_conflict_description2_t *desc,
+ void *baton,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+/* Create an return a baton for use with svn_cl__conflict_func_postpone(),
+ * allocated in RESULT_POOL. */
+void *
+svn_cl__get_conflict_func_postpone_baton(apr_pool_t *result_pool);
+
+/* A conflict-resolution callback which postpones all conflicts and
+ * remembers conflicted paths in BATON. */
+svn_error_t *
+svn_cl__conflict_func_postpone(svn_wc_conflict_result_t **result,
+ const svn_wc_conflict_description2_t *desc,
+ void *baton,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+/* Run the interactive conflict resolver, obtained internally from
+ * svn_cl__get_conflict_func_interactive(), on any conflicted paths
+ * stored in the BATON obtained from svn_cl__get_conflict_func_postpone(). */
+svn_error_t *
+svn_cl__resolve_postponed_conflicts(void *baton,
+ svn_depth_t depth,
+ svn_cl__accept_t accept_which,
+ const char *editor_cmd,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool);
/*** Command-line output functions -- printing to the user. ***/
@@ -460,12 +478,15 @@ svn_cl__print_prop_hash(svn_stream_t *ou
svn_boolean_t names_only,
apr_pool_t *pool);
-/* Same as svn_cl__print_prop_hash(), only output xml to *OUTSTR. If *OUTSTR is
- NULL, allocate it first from POOL, otherwise append to it. */
+/* Similar to svn_cl__print_prop_hash(), only output xml to *OUTSTR.
+ If INHERITED_PROPS is true, then PROP_HASH contains inherited properties,
+ otherwise PROP_HASH contains explicit properties. If *OUTSTR is NULL,
+ allocate it first from POOL, otherwise append to it. */
svn_error_t *
svn_cl__print_xml_prop_hash(svn_stringbuf_t **outstr,
apr_hash_t *prop_hash,
svn_boolean_t names_only,
+ svn_boolean_t inherited_props,
apr_pool_t *pool);
/* Output a commit xml element to *OUTSTR. If *OUTSTR is NULL, allocate it
@@ -618,14 +639,6 @@ svn_cl__notifier_mark_export(void *baton
svn_error_t *
svn_cl__notifier_mark_wc_to_repos_copy(void *baton);
-/* Return TRUE if any conflicts were detected during notification. */
-svn_boolean_t
-svn_cl__notifier_check_conflicts(void *baton);
-
-/* Return a sorted array of conflicted paths detected during notification. */
-apr_array_header_t *
-svn_cl__notifier_get_conflicted_paths(void *baton, apr_pool_t *result_pool);
-
/* Baton for use with svn_cl__check_externals_failed_notify_wrapper(). */
struct svn_cl__check_externals_failed_notify_baton
{
@@ -873,15 +886,6 @@ svn_cl__check_related_source_and_target(
svn_client_ctx_t *ctx,
apr_pool_t *pool);
-/* Run the conflict resolver for all targets in the TARGETS list with
- * the specified DEPTH. */
-svn_error_t *
-svn_cl__resolve_conflicts(apr_array_header_t *targets,
- svn_depth_t depth,
- const svn_cl__opt_state_t *opt_state,
- svn_client_ctx_t *ctx,
- apr_pool_t *scratch_pool);
-
#ifdef __cplusplus
}
#endif /* __cplusplus */
Modified: subversion/branches/javahl-ra/subversion/svn/conflict-callbacks.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/svn/conflict-callbacks.c?rev=1425508&r1=1425507&r2=1425508&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/svn/conflict-callbacks.c (original)
+++ subversion/branches/javahl-ra/subversion/svn/conflict-callbacks.c Sun Dec 23 18:34:14 2012
@@ -33,6 +33,7 @@
#include "svn_dirent_uri.h"
#include "svn_types.h"
#include "svn_pools.h"
+#include "svn_sorts.h"
#include "cl.h"
#include "tree-conflicts.h"
@@ -41,22 +42,37 @@
+struct svn_cl__interactive_conflict_baton_t {
+ svn_cl__accept_t accept_which;
+ apr_hash_t *config;
+ const char *editor_cmd;
+ svn_boolean_t external_failed;
+ svn_cmdline_prompt_baton_t *pb;
+ const char *path_prefix;
+};
svn_error_t *
-svn_cl__conflict_baton_make(svn_cl__conflict_baton_t **b,
- svn_cl__accept_t accept_which,
- apr_hash_t *config,
- const char *editor_cmd,
- svn_cmdline_prompt_baton_t *pb,
- apr_pool_t *pool)
+svn_cl__get_conflict_func_interactive_baton(
+ svn_cl__interactive_conflict_baton_t **b,
+ svn_cl__accept_t accept_which,
+ apr_hash_t *config,
+ const char *editor_cmd,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ apr_pool_t *result_pool)
{
- *b = apr_palloc(pool, sizeof(**b));
+ svn_cmdline_prompt_baton_t *pb = apr_palloc(result_pool, sizeof(*pb));
+ pb->cancel_func = cancel_func;
+ pb->cancel_baton = cancel_baton;
+
+ *b = apr_palloc(result_pool, sizeof(**b));
(*b)->accept_which = accept_which;
(*b)->config = config;
(*b)->editor_cmd = editor_cmd;
(*b)->external_failed = FALSE;
(*b)->pb = pb;
- SVN_ERR(svn_dirent_get_absolute(&(*b)->path_prefix, "", pool));
+ SVN_ERR(svn_dirent_get_absolute(&(*b)->path_prefix, "", result_pool));
+
return SVN_NO_ERROR;
}
@@ -180,7 +196,7 @@ show_conflicts(const svn_wc_conflict_des
static svn_error_t *
open_editor(svn_boolean_t *performed_edit,
const svn_wc_conflict_description2_t *desc,
- svn_cl__conflict_baton_t *b,
+ svn_cl__interactive_conflict_baton_t *b,
apr_pool_t *pool)
{
svn_error_t *err;
@@ -232,7 +248,7 @@ open_editor(svn_boolean_t *performed_edi
static svn_error_t *
launch_resolver(svn_boolean_t *performed_edit,
const svn_wc_conflict_description2_t *desc,
- svn_cl__conflict_baton_t *b,
+ svn_cl__interactive_conflict_baton_t *b,
apr_pool_t *pool)
{
svn_error_t *err;
@@ -265,17 +281,359 @@ launch_resolver(svn_boolean_t *performed
return SVN_NO_ERROR;
}
+/* Ask the user what to do about the text conflict described by DESC.
+ * Return the answer in RESULT. B is the conflict baton for this
+ * conflict resolution session.
+ * SCRATCH_POOL is used for temporary allocations. */
+static svn_error_t *
+handle_text_conflict(svn_wc_conflict_result_t *result,
+ const svn_wc_conflict_description2_t *desc,
+ svn_cl__interactive_conflict_baton_t *b,
+ apr_pool_t *scratch_pool)
+{
+ const char *answer;
+ char *prompt;
+ svn_boolean_t diff_allowed = FALSE;
+ /* Have they done something that might have affected the merged
+ file (so that we need to save a .edited copy)? */
+ svn_boolean_t performed_edit = FALSE;
+ /* Have they done *something* (edit, look at diff, etc) to
+ give them a rational basis for choosing (r)esolved? */
+ svn_boolean_t knows_something = FALSE;
+
+ SVN_ERR_ASSERT(desc->kind == svn_wc_conflict_kind_text);
+
+ SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
+ _("Conflict discovered in file '%s'.\n"),
+ svn_cl__local_style_skip_ancestor(
+ b->path_prefix, desc->local_abspath,
+ scratch_pool)));
+
+ /* Diffing can happen between base and merged, to show conflict
+ markers to the user (this is the typical 3-way merge
+ scenario), or if no base is available, we can show a diff
+ between mine and theirs. */
+ if ((desc->merged_file && desc->base_abspath)
+ || (!desc->base_abspath && desc->my_abspath && desc->their_abspath))
+ diff_allowed = TRUE;
+
+ while (TRUE)
+ {
+ svn_pool_clear(scratch_pool);
+
+ prompt = apr_pstrdup(scratch_pool, _("Select: (p) postpone"));
+
+ if (diff_allowed)
+ {
+ prompt = apr_pstrcat(scratch_pool, prompt,
+ _(", (df) diff-full, (e) edit, (m) merge"),
+ (char *)NULL);
+
+ if (knows_something)
+ prompt = apr_pstrcat(scratch_pool, prompt, _(", (r) resolved"),
+ (char *)NULL);
+
+ if (! desc->is_binary)
+ prompt = apr_pstrcat(scratch_pool, prompt,
+ _(",\n (mc) mine-conflict, "
+ "(tc) theirs-conflict"),
+ (char *)NULL);
+ }
+ else
+ {
+ if (knows_something)
+ prompt = apr_pstrcat(scratch_pool, prompt, _(", (r) resolved"),
+ (char *)NULL);
+ prompt = apr_pstrcat(scratch_pool, prompt,
+ _(",\n "
+ "(mf) mine-full, (tf) theirs-full"),
+ (char *)NULL);
+ }
+
+ prompt = apr_pstrcat(scratch_pool, prompt, ",\n ", (char *)NULL);
+ prompt = apr_pstrcat(scratch_pool, prompt,
+ _("(s) show all options: "),
+ (char *)NULL);
+
+ SVN_ERR(svn_cmdline_prompt_user2(&answer, prompt, b->pb, scratch_pool));
+
+ if (strcmp(answer, "s") == 0)
+ {
+ /* These are used in svn_cl__accept_from_word(). */
+ SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
+ _("\n"
+ " (e) edit - change merged file in an editor\n"
+ " (df) diff-full - show all changes made to merged "
+ "file\n"
+ " (r) resolved - accept merged version of file\n"
+ "\n"
+ " (dc) display-conflict - show all conflicts "
+ "(ignoring merged version)\n"
+ " (mc) mine-conflict - accept my version for all "
+ "conflicts (same)\n"
+ " (tc) theirs-conflict - accept their version for all "
+ "conflicts (same)\n"
+ "\n"
+ " (mf) mine-full - accept my version of entire file "
+ "(even non-conflicts)\n"
+ " (tf) theirs-full - accept their version of entire "
+ "file (same)\n"
+ "\n"
+ " (p) postpone - mark the conflict to be "
+ "resolved later\n"
+ " (m) merge - use internal merge tool to "
+ "resolve conflict\n"
+ " (l) launch - launch external tool to "
+ "resolve conflict\n"
+ " (s) show all - show this list\n\n")));
+ }
+ else if (strcmp(answer, "p") == 0 || strcmp(answer, ":-P") == 0)
+ {
+ /* Do nothing, let file be marked conflicted. */
+ result->choice = svn_wc_conflict_choose_postpone;
+ break;
+ }
+ else if (strcmp(answer, "mc") == 0 || strcmp(answer, "X-)") == 0)
+ {
+ if (desc->is_binary)
+ {
+ SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
+ _("Invalid option; cannot choose "
+ "based on conflicts in a "
+ "binary file.\n\n")));
+ continue;
+ }
+ result->choice = svn_wc_conflict_choose_mine_conflict;
+ if (performed_edit)
+ result->save_merged = TRUE;
+ break;
+ }
+ else if (strcmp(answer, "tc") == 0 || strcmp(answer, "X-(") == 0)
+ {
+ if (desc->is_binary)
+ {
+ SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
+ _("Invalid option; cannot choose "
+ "based on conflicts in a "
+ "binary file.\n\n")));
+ continue;
+ }
+ result->choice = svn_wc_conflict_choose_theirs_conflict;
+ if (performed_edit)
+ result->save_merged = TRUE;
+ break;
+ }
+ else if (strcmp(answer, "mf") == 0 || strcmp(answer, ":-)") == 0)
+ {
+ result->choice = svn_wc_conflict_choose_mine_full;
+ if (performed_edit)
+ result->save_merged = TRUE;
+ break;
+ }
+ else if (strcmp(answer, "tf") == 0 || strcmp(answer, ":-(") == 0)
+ {
+ result->choice = svn_wc_conflict_choose_theirs_full;
+ if (performed_edit)
+ result->save_merged = TRUE;
+ break;
+ }
+ else if (strcmp(answer, "dc") == 0)
+ {
+ if (desc->is_binary)
+ {
+ SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
+ _("Invalid option; cannot "
+ "display conflicts for a "
+ "binary file.\n\n")));
+ continue;
+ }
+ else if (! (desc->my_abspath && desc->base_abspath &&
+ desc->their_abspath))
+ {
+ SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
+ _("Invalid option; original "
+ "files not available.\n\n")));
+ continue;
+ }
+ SVN_ERR(show_conflicts(desc, scratch_pool));
+ knows_something = TRUE;
+ }
+ else if (strcmp(answer, "df") == 0)
+ {
+ if (! diff_allowed)
+ {
+ SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
+ _("Invalid option; there's no "
+ "merged version to diff.\n\n")));
+ continue;
+ }
+
+ SVN_ERR(show_diff(desc, scratch_pool));
+ knows_something = TRUE;
+ }
+ else if (strcmp(answer, "e") == 0 || strcmp(answer, ":-E") == 0)
+ {
+ SVN_ERR(open_editor(&performed_edit, desc, b, scratch_pool));
+ if (performed_edit)
+ knows_something = TRUE;
+ }
+ else if (strcmp(answer, "m") == 0 || strcmp(answer, ":-g") ||
+ strcmp(answer, "=>-") == 0 || strcmp(answer, ":>.") == 0)
+ {
+ if (desc->kind != svn_wc_conflict_kind_text)
+ {
+ SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
+ _("Invalid option; can only "
+ "resolve text conflicts with "
+ "the internal merge tool."
+ "\n\n")));
+ continue;
+ }
+
+ if (desc->base_abspath && desc->their_abspath &&
+ desc->my_abspath && desc->merged_file)
+ {
+ svn_boolean_t remains_in_conflict;
+
+ SVN_ERR(svn_cl__merge_file(desc->base_abspath,
+ desc->their_abspath,
+ desc->my_abspath,
+ desc->merged_file,
+ desc->local_abspath,
+ b->path_prefix,
+ b->editor_cmd,
+ b->config,
+ &remains_in_conflict,
+ scratch_pool));
+ knows_something = !remains_in_conflict;
+ }
+ else
+ SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
+ _("Invalid option.\n\n")));
+ }
+ else if (strcmp(answer, "l") == 0 || strcmp(answer, ":-l") == 0)
+ {
+ if (desc->base_abspath && desc->their_abspath &&
+ desc->my_abspath && desc->merged_file)
+ {
+ SVN_ERR(launch_resolver(&performed_edit, desc, b, scratch_pool));
+ if (performed_edit)
+ knows_something = TRUE;
+ }
+ else
+ SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
+ _("Invalid option.\n\n")));
+ }
+ else if (strcmp(answer, "r") == 0)
+ {
+ /* We only allow the user accept the merged version of
+ the file if they've edited it, or at least looked at
+ the diff. */
+ if (knows_something)
+ {
+ result->choice = svn_wc_conflict_choose_merged;
+ break;
+ }
+ else
+ SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
+ _("Invalid option.\n\n")));
+ }
+ }
+
+ return SVN_NO_ERROR;
+}
+
+/* Ask the user what to do about the property conflict described by DESC.
+ * Return the answer in RESULT. B is the conflict baton for this
+ * conflict resolution session.
+ * SCRATCH_POOL is used for temporary allocations. */
+static svn_error_t *
+handle_prop_conflict(svn_wc_conflict_result_t *result,
+ const svn_wc_conflict_description2_t *desc,
+ svn_cl__interactive_conflict_baton_t *b,
+ apr_pool_t *scratch_pool)
+{
+ const char *answer;
+ const char *prompt;
+ svn_stringbuf_t *prop_reject;
+ apr_pool_t *iterpool;
+
+ SVN_ERR_ASSERT(desc->kind == svn_wc_conflict_kind_property);
+
+ SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
+ _("Conflict for property '%s' discovered"
+ " on '%s'.\n"),
+ desc->property_name,
+ svn_cl__local_style_skip_ancestor(
+ b->path_prefix, desc->local_abspath,
+ scratch_pool)));
+
+ /* ### Currently, the only useful information in a prop conflict
+ * ### description is the .prej file path, which, possibly due to
+ * ### deceitful interference from outer space, is stored in the
+ * ### 'their_abspath' field of the description.
+ * ### This needs to be fixed so we can present better options here. */
+ if (desc->their_abspath)
+ {
+ /* ### The library dumps an svn_string_t into a temp file, and
+ * ### we read it back from the file into an svn_stringbuf_t here.
+ * ### That's rather silly. We should be passed svn_string_t's
+ * ### containing the old/mine/theirs values instead. */
+ SVN_ERR(svn_stringbuf_from_file2(&prop_reject,
+ desc->their_abspath,
+ scratch_pool));
+ /* Print reject file contents. */
+ SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
+ "%s\n", prop_reject->data));
+ }
+ else
+ {
+ /* Nothing much we can do without a prej file... */
+ result->choice = svn_wc_conflict_choose_postpone;
+ return SVN_NO_ERROR;
+ }
+
+ iterpool = svn_pool_create(scratch_pool);
+ while (TRUE)
+ {
+ svn_pool_clear(iterpool);
+
+ prompt = _("Select: (p) postpone, (mf) mine-full, (tf) theirs-full: ");
+
+ SVN_ERR(svn_cmdline_prompt_user2(&answer, prompt, b->pb, iterpool));
+
+ if (strcmp(answer, "p") == 0 || strcmp(answer, ":-P") == 0)
+ {
+ /* Do nothing, let property be marked conflicted. */
+ result->choice = svn_wc_conflict_choose_postpone;
+ break;
+ }
+ else if (strcmp(answer, "mf") == 0 || strcmp(answer, ":-)") == 0)
+ {
+ result->choice = svn_wc_conflict_choose_mine_full;
+ break;
+ }
+ else if (strcmp(answer, "tf") == 0 || strcmp(answer, ":-(") == 0)
+ {
+ result->choice = svn_wc_conflict_choose_theirs_full;
+ break;
+ }
+ }
+ svn_pool_destroy(iterpool);
+
+ return SVN_NO_ERROR;
+}
/* Implement svn_wc_conflict_resolver_func2_t; resolves based on
--accept option if given, else by prompting. */
svn_error_t *
-svn_cl__conflict_handler(svn_wc_conflict_result_t **result,
- const svn_wc_conflict_description2_t *desc,
- void *baton,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
+svn_cl__conflict_func_interactive(svn_wc_conflict_result_t **result,
+ const svn_wc_conflict_description2_t *desc,
+ void *baton,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
- svn_cl__conflict_baton_t *b = baton;
+ svn_cl__interactive_conflict_baton_t *b = baton;
svn_error_t *err;
apr_pool_t *subpool;
@@ -409,333 +767,11 @@ svn_cl__conflict_handler(svn_wc_conflict
*/
if (((desc->node_kind == svn_node_file)
&& (desc->action == svn_wc_conflict_action_edit)
- && (desc->reason == svn_wc_conflict_reason_edited))
- || (desc->kind == svn_wc_conflict_kind_property))
- {
- const char *answer;
- char *prompt;
- svn_boolean_t diff_allowed = FALSE;
- /* Have they done something that might have affected the merged
- file (so that we need to save a .edited copy)? */
- svn_boolean_t performed_edit = FALSE;
- /* Have they done *something* (edit, look at diff, etc) to
- give them a rational basis for choosing (r)esolved? */
- svn_boolean_t knows_something = FALSE;
-
- if (desc->kind == svn_wc_conflict_kind_text)
- SVN_ERR(svn_cmdline_fprintf(stderr, subpool,
- _("Conflict discovered in file '%s'.\n"),
- svn_cl__local_style_skip_ancestor(
- b->path_prefix, desc->local_abspath,
- subpool)));
- else if (desc->kind == svn_wc_conflict_kind_property)
- {
- SVN_ERR(svn_cmdline_fprintf(stderr, subpool,
- _("Conflict for property '%s' discovered"
- " on '%s'.\n"),
- desc->property_name,
- svn_cl__local_style_skip_ancestor(
- b->path_prefix, desc->local_abspath,
- subpool)));
-
- if ((!desc->my_abspath && desc->their_abspath)
- || (desc->my_abspath && !desc->their_abspath))
- {
- /* One agent wants to change the property, one wants to
- delete it. This is not something we can diff, so we
- just tell the user. */
- svn_stringbuf_t *myval = NULL, *theirval = NULL;
-
- if (desc->my_abspath)
- {
- SVN_ERR(svn_stringbuf_from_file2(&myval, desc->my_abspath,
- subpool));
- SVN_ERR(svn_cmdline_fprintf(stderr, subpool,
- _("They want to delete the property, "
- "you want to change the value to '%s'.\n"),
- myval->data));
- }
- else
- {
- SVN_ERR(svn_stringbuf_from_file2(&theirval,
- desc->their_abspath,
- subpool));
- SVN_ERR(svn_cmdline_fprintf(stderr, subpool,
- _("They want to change the property value to '%s', "
- "you want to delete the property.\n"),
- theirval->data));
- }
- }
- }
- else
- /* We don't recognize any other sort of conflict yet */
- return SVN_NO_ERROR;
-
- /* Diffing can happen between base and merged, to show conflict
- markers to the user (this is the typical 3-way merge
- scenario), or if no base is available, we can show a diff
- between mine and theirs. */
- if ((desc->merged_file && desc->base_abspath)
- || (!desc->base_abspath && desc->my_abspath && desc->their_abspath))
- diff_allowed = TRUE;
-
- while (TRUE)
- {
- svn_pool_clear(subpool);
-
- prompt = apr_pstrdup(subpool, _("Select: (p) postpone"));
-
- if (diff_allowed)
- {
- prompt = apr_pstrcat(subpool, prompt,
- _(", (df) diff-full, (e) edit, (m) merge"),
- (char *)NULL);
-
- if (knows_something)
- prompt = apr_pstrcat(subpool, prompt, _(", (r) resolved"),
- (char *)NULL);
-
- if (! desc->is_binary &&
- desc->kind != svn_wc_conflict_kind_property)
- prompt = apr_pstrcat(subpool, prompt,
- _(",\n (mc) mine-conflict, "
- "(tc) theirs-conflict"),
- (char *)NULL);
- }
- else
- {
- if (knows_something)
- prompt = apr_pstrcat(subpool, prompt, _(", (r) resolved"),
- (char *)NULL);
- prompt = apr_pstrcat(subpool, prompt,
- _(",\n "
- "(mf) mine-full, (tf) theirs-full"),
- (char *)NULL);
- }
-
- prompt = apr_pstrcat(subpool, prompt, ",\n ", (char *)NULL);
- prompt = apr_pstrcat(subpool, prompt,
- _("(s) show all options: "),
- (char *)NULL);
-
- SVN_ERR(svn_cmdline_prompt_user2(&answer, prompt, b->pb, subpool));
-
- if (strcmp(answer, "s") == 0)
- {
- /* These are used in svn_cl__accept_from_word(). */
- SVN_ERR(svn_cmdline_fprintf(stderr, subpool,
- _("\n"
- " (e) edit - change merged file in an editor\n"
- " (df) diff-full - show all changes made to merged "
- "file\n"
- " (r) resolved - accept merged version of file\n"
- "\n"
- " (dc) display-conflict - show all conflicts "
- "(ignoring merged version)\n"
- " (mc) mine-conflict - accept my version for all "
- "conflicts (same)\n"
- " (tc) theirs-conflict - accept their version for all "
- "conflicts (same)\n"
- "\n"
- " (mf) mine-full - accept my version of entire file "
- "(even non-conflicts)\n"
- " (tf) theirs-full - accept their version of entire "
- "file (same)\n"
- "\n"
- " (p) postpone - mark the conflict to be "
- "resolved later\n"
- " (m) merge - use internal merge tool to "
- "resolve conflict\n"
- " (l) launch - launch external tool to "
- "resolve conflict\n"
- " (s) show all - show this list\n\n")));
- }
- else if (strcmp(answer, "p") == 0 || strcmp(answer, ":-P") == 0)
- {
- /* Do nothing, let file be marked conflicted. */
- (*result)->choice = svn_wc_conflict_choose_postpone;
- break;
- }
- else if (strcmp(answer, "mc") == 0 || strcmp(answer, "X-)") == 0)
- {
- if (desc->is_binary)
- {
- SVN_ERR(svn_cmdline_fprintf(stderr, subpool,
- _("Invalid option; cannot choose "
- "based on conflicts in a "
- "binary file.\n\n")));
- continue;
- }
- else if (desc->kind == svn_wc_conflict_kind_property)
- {
- SVN_ERR(svn_cmdline_fprintf(stderr, subpool,
- _("Invalid option; cannot choose "
- "based on conflicts for "
- "properties.\n\n")));
- continue;
- }
-
- (*result)->choice = svn_wc_conflict_choose_mine_conflict;
- if (performed_edit)
- (*result)->save_merged = TRUE;
- break;
- }
- else if (strcmp(answer, "tc") == 0 || strcmp(answer, "X-(") == 0)
- {
- if (desc->is_binary)
- {
- SVN_ERR(svn_cmdline_fprintf(stderr, subpool,
- _("Invalid option; cannot choose "
- "based on conflicts in a "
- "binary file.\n\n")));
- continue;
- }
- else if (desc->kind == svn_wc_conflict_kind_property)
- {
- SVN_ERR(svn_cmdline_fprintf(stderr, subpool,
- _("Invalid option; cannot choose "
- "based on conflicts for "
- "properties.\n\n")));
- continue;
- }
- (*result)->choice = svn_wc_conflict_choose_theirs_conflict;
- if (performed_edit)
- (*result)->save_merged = TRUE;
- break;
- }
- else if (strcmp(answer, "mf") == 0 || strcmp(answer, ":-)") == 0)
- {
- (*result)->choice = svn_wc_conflict_choose_mine_full;
- if (performed_edit)
- (*result)->save_merged = TRUE;
- break;
- }
- else if (strcmp(answer, "tf") == 0 || strcmp(answer, ":-(") == 0)
- {
- (*result)->choice = svn_wc_conflict_choose_theirs_full;
- if (performed_edit)
- (*result)->save_merged = TRUE;
- break;
- }
- else if (strcmp(answer, "dc") == 0)
- {
- if (desc->is_binary)
- {
- SVN_ERR(svn_cmdline_fprintf(stderr, subpool,
- _("Invalid option; cannot "
- "display conflicts for a "
- "binary file.\n\n")));
- continue;
- }
- else if (desc->kind == svn_wc_conflict_kind_property)
- {
- SVN_ERR(svn_cmdline_fprintf(stderr, subpool,
- _("Invalid option; cannot "
- "display conflicts for "
- "properties.\n\n")));
- continue;
- }
- else if (! (desc->my_abspath && desc->base_abspath &&
- desc->their_abspath))
- {
- SVN_ERR(svn_cmdline_fprintf(stderr, subpool,
- _("Invalid option; original "
- "files not available.\n\n")));
- continue;
- }
- SVN_ERR(show_conflicts(desc, subpool));
- knows_something = TRUE;
- }
- else if (strcmp(answer, "df") == 0)
- {
- if (! diff_allowed)
- {
- SVN_ERR(svn_cmdline_fprintf(stderr, subpool,
- _("Invalid option; there's no "
- "merged version to diff.\n\n")));
- continue;
- }
+ && (desc->reason == svn_wc_conflict_reason_edited)))
+ SVN_ERR(handle_text_conflict(*result, desc, b, subpool));
+ else if (desc->kind == svn_wc_conflict_kind_property)
+ SVN_ERR(handle_prop_conflict(*result, desc, b, subpool));
- SVN_ERR(show_diff(desc, subpool));
- knows_something = TRUE;
- }
- else if (strcmp(answer, "e") == 0 || strcmp(answer, ":-E") == 0)
- {
- SVN_ERR(open_editor(&performed_edit, desc, b, subpool));
- if (performed_edit)
- knows_something = TRUE;
- }
- else if (strcmp(answer, "m") == 0 || strcmp(answer, ":-M") == 0)
- {
- if (desc->kind != svn_wc_conflict_kind_text)
- {
- SVN_ERR(svn_cmdline_fprintf(stderr, subpool,
- _("Invalid option; can only "
- "resolve text conflicts with "
- "the internal merge tool."
- "\n\n")));
- continue;
- }
-
- if (desc->base_abspath && desc->their_abspath &&
- desc->my_abspath && desc->merged_file)
- {
- svn_boolean_t remains_in_conflict;
-
- SVN_ERR(svn_cl__merge_file(desc->base_abspath,
- desc->their_abspath,
- desc->my_abspath,
- desc->merged_file,
- desc->local_abspath,
- b->path_prefix,
- b->editor_cmd,
- b->config,
- &remains_in_conflict,
- subpool));
- knows_something = !remains_in_conflict;
- }
- else
- SVN_ERR(svn_cmdline_fprintf(stderr, subpool,
- _("Invalid option.\n\n")));
- }
- else if (strcmp(answer, "l") == 0 || strcmp(answer, ":-l") == 0)
- {
- if (desc->kind == svn_wc_conflict_kind_property)
- {
- SVN_ERR(svn_cmdline_fprintf(stderr, subpool,
- _("Invalid option; cannot "
- "resolve property conflicts "
- "with an external merge tool."
- "\n\n")));
- continue;
- }
- if (desc->base_abspath && desc->their_abspath &&
- desc->my_abspath && desc->merged_file)
- {
- SVN_ERR(launch_resolver(&performed_edit, desc, b, subpool));
- if (performed_edit)
- knows_something = TRUE;
- }
- else
- SVN_ERR(svn_cmdline_fprintf(stderr, subpool,
- _("Invalid option.\n\n")));
- }
- else if (strcmp(answer, "r") == 0)
- {
- /* We only allow the user accept the merged version of
- the file if they've edited it, or at least looked at
- the diff. */
- if (knows_something)
- {
- (*result)->choice = svn_wc_conflict_choose_merged;
- break;
- }
- else
- SVN_ERR(svn_cmdline_fprintf(stderr, subpool,
- _("Invalid option.\n\n")));
- }
- }
- }
/*
Dealing with obstruction of additions can be tricky. The
obstructing item could be unversioned, versioned, or even
@@ -856,16 +892,77 @@ svn_cl__conflict_handler(svn_wc_conflict
return SVN_NO_ERROR;
}
+/* Implement svn_wc_conflict_resolver_func2_t; postpones all conflicts
+ * and remembers conflicted paths in BATON. */
svn_error_t *
-svn_cl__resolve_conflicts(apr_array_header_t *targets,
- svn_depth_t depth,
- const svn_cl__opt_state_t *opt_state,
- svn_client_ctx_t *ctx,
- apr_pool_t *scratch_pool)
+svn_cl__conflict_func_postpone(svn_wc_conflict_result_t **result,
+ const svn_wc_conflict_description2_t *desc,
+ void *baton,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
+ apr_hash_t *conflicted_paths = baton;
+
+ apr_hash_set(conflicted_paths,
+ apr_pstrdup(apr_hash_pool_get(conflicted_paths),
+ desc->local_abspath),
+ APR_HASH_KEY_STRING, "");
+
+ *result = svn_wc_create_conflict_result(svn_wc_conflict_choose_postpone,
+ NULL, result_pool);
+ return SVN_NO_ERROR;
+}
+
+void *
+svn_cl__get_conflict_func_postpone_baton(apr_pool_t *result_pool)
+{
+ return apr_hash_make(result_pool);
+}
+
+static apr_array_header_t *
+get_postponed_conflicted_paths(void *baton, apr_pool_t *result_pool)
+{
+ apr_hash_t *conflicted_paths = baton;
+ apr_array_header_t *sorted_array;
+ apr_array_header_t *result_array;
+ int i;
+
+ if (apr_hash_count(conflicted_paths) == 0)
+ return NULL;
+
+ sorted_array = svn_sort__hash(conflicted_paths,
+ svn_sort_compare_items_as_paths,
+ apr_hash_pool_get(conflicted_paths));
+ result_array = apr_array_make(result_pool, sorted_array->nelts,
+ sizeof(const char *));
+ for (i = 0; i < sorted_array->nelts; i++)
+ {
+ svn_sort__item_t item;
+
+ item = APR_ARRAY_IDX(sorted_array, i, svn_sort__item_t);
+ APR_ARRAY_PUSH(result_array, const char *) = apr_pstrdup(result_pool,
+ item.key);
+ }
+
+ return result_array;
+}
+
+svn_error_t *
+svn_cl__resolve_postponed_conflicts(void *baton,
+ svn_depth_t depth,
+ svn_cl__accept_t accept_which,
+ const char *editor_cmd,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ apr_array_header_t *targets;
int i;
apr_pool_t *iterpool;
+ targets = get_postponed_conflicted_paths(baton, scratch_pool);
+ if (targets == NULL)
+ return SVN_NO_ERROR;
+
iterpool = svn_pool_create(scratch_pool);
for (i = 0; i < targets->nelts; i++)
{
@@ -874,19 +971,25 @@ svn_cl__resolve_conflicts(apr_array_head
const char *local_abspath;
svn_wc_conflict_resolver_func2_t conflict_func2;
void *conflict_baton2;
+ svn_cl__interactive_conflict_baton_t *b;
svn_pool_clear(iterpool);
SVN_ERR(svn_dirent_get_absolute(&local_abspath, target, iterpool));
-
/* Store old state */
conflict_func2 = ctx->conflict_func2;
conflict_baton2 = ctx->conflict_baton2;
- /* Store interactive resolver */
- ctx->conflict_func2 = opt_state->conflict_func;
- ctx->conflict_baton2 = opt_state->conflict_baton;
+ /* Set up the interactive resolver. */
+ ctx->conflict_func2 = svn_cl__conflict_func_interactive;
+ SVN_ERR(svn_cl__get_conflict_func_interactive_baton(&b, accept_which,
+ ctx->config,
+ editor_cmd,
+ ctx->cancel_func,
+ ctx->cancel_baton,
+ scratch_pool));
+ ctx->conflict_baton2 = b;
err = svn_client_resolve(local_abspath, depth,
svn_wc_conflict_choose_unspecified,
Modified: subversion/branches/javahl-ra/subversion/svn/file-merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/svn/file-merge.c?rev=1425508&r1=1425507&r2=1425508&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/svn/file-merge.c (original)
+++ subversion/branches/javahl-ra/subversion/svn/file-merge.c Sun Dec 23 18:34:14 2012
@@ -365,7 +365,7 @@ static const char *
prepare_line_for_display(const char *line, apr_pool_t *pool)
{
svn_stringbuf_t *buf = svn_stringbuf_create(line, pool);
- int width;
+ size_t width;
int line_width = LINE_DISPLAY_WIDTH;
apr_pool_t *iterpool;
@@ -596,7 +596,7 @@ merge_chunks(apr_array_header_t **merged
prompt = svn_stringbuf_create(
apr_psprintf(scratch_pool, "%s\n%s|%s\n%s",
- _("Conflicting section found during merge."),
+ _("Conflicting section found during merge:"),
prepare_line_for_display(
apr_psprintf(scratch_pool,
_("(1) their version (at line %lu)"),
@@ -851,6 +851,7 @@ svn_cl__merge_file(const char *base_path
apr_file_t *merged_file;
const char *merged_file_name;
struct file_merge_baton fmb;
+ svn_boolean_t executable;
SVN_ERR(svn_cmdline_printf(
@@ -912,7 +913,9 @@ svn_cl__merge_file(const char *base_path
return SVN_NO_ERROR;
}
- SVN_ERR_W(svn_io_file_move(merged_file_name, merged_path, scratch_pool),
+ SVN_ERR(svn_io_is_file_executable(&executable, merged_path, scratch_pool));
+ SVN_ERR_W(svn_io_copy_file(merged_file_name, merged_path, FALSE,
+ scratch_pool),
apr_psprintf(scratch_pool,
_("Could not write merged result to '%s', saved "
"instead at '%s'.\n'%s' remains in conflict.\n"),
@@ -924,6 +927,9 @@ svn_cl__merge_file(const char *base_path
svn_dirent_local_style(
svn_dirent_skip_ancestor(path_prefix, wc_path),
scratch_pool)));
+ SVN_ERR(svn_io_set_file_executable(merged_path, executable, FALSE,
+ scratch_pool));
+ SVN_ERR(svn_io_remove_file2(merged_file_name, TRUE, scratch_pool));
/* The merge was not aborted and we could install the merged result. The
* file remains in conflict unless all conflicting sections were resolved. */
Modified: subversion/branches/javahl-ra/subversion/svn/log-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/svn/log-cmd.c?rev=1425508&r1=1425507&r2=1425508&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/svn/log-cmd.c (original)
+++ subversion/branches/javahl-ra/subversion/svn/log-cmd.c Sun Dec 23 18:34:14 2012
@@ -71,10 +71,9 @@ struct log_receiver_baton
/* Stack which keeps track of merge revision nesting, using svn_revnum_t's */
apr_array_header_t *merge_stack;
- /* Log message search pattern. Log entries will only be shown if the author,
- * the log message, or a changed path matches this pattern. */
- const char *search_pattern;
- svn_boolean_t case_insensitive_search;
+ /* Log message search patterns. Log entries will only be shown if the author,
+ * the log message, or a changed path matches one of these patterns. */
+ apr_array_header_t *search_patterns;
/* Pool for persistent allocations. */
apr_pool_t *pool;
@@ -156,12 +155,11 @@ match_search_pattern(const char *search_
const char *date,
const char *log_message,
apr_hash_t *changed_paths,
- svn_boolean_t case_insensitive_search,
apr_pool_t *pool)
{
/* Match any substring containing the pattern, like UNIX 'grep' does. */
const char *pattern = apr_psprintf(pool, "*%s*", search_pattern);
- int flags = (case_insensitive_search ? APR_FNM_CASE_BLIND : 0);
+ int flags = APR_FNM_CASE_BLIND;
/* Does the author match the search pattern? */
if (author && apr_fnmatch(pattern, author, flags) == APR_SUCCESS)
@@ -203,6 +201,50 @@ match_search_pattern(const char *search_
return FALSE;
}
+/* Match all search patterns in SEARCH_PATTERNS against AUTHOR, DATE, MESSAGE,
+ * and CHANGED_PATHS. Return TRUE if any pattern matches, else FALSE.
+ * SCRACH_POOL is used for temporary allocations. */
+static svn_boolean_t
+match_search_patterns(apr_array_header_t *search_patterns,
+ const char *author,
+ const char *date,
+ const char *message,
+ apr_hash_t *changed_paths,
+ apr_pool_t *scratch_pool)
+{
+ int i;
+ svn_boolean_t match = FALSE;
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+
+ for (i = 0; i < search_patterns->nelts; i++)
+ {
+ apr_array_header_t *pattern_group;
+ int j;
+
+ pattern_group = APR_ARRAY_IDX(search_patterns, i, apr_array_header_t *);
+
+ /* All patterns within the group must match. */
+ for (j = 0; j < pattern_group->nelts; j++)
+ {
+ const char *pattern;
+
+ svn_pool_clear(iterpool);
+
+ pattern = APR_ARRAY_IDX(pattern_group, j, const char *);
+ match = match_search_pattern(pattern, author, date, message,
+ changed_paths, iterpool);
+ if (!match)
+ break;
+ }
+
+ match = (match && j == pattern_group->nelts);
+ if (match)
+ break;
+ }
+ svn_pool_destroy(iterpool);
+
+ return match;
+}
/* Implement `svn_log_entry_receiver_t', printing the logs in
* a human-readable and machine-parseable format.
@@ -320,10 +362,9 @@ log_entry_receiver(void *baton,
if (! lb->omit_log_message && message == NULL)
message = "";
- if (lb->search_pattern &&
- ! match_search_pattern(lb->search_pattern, author, date, message,
- log_entry->changed_paths2,
- lb->case_insensitive_search, pool))
+ if (lb->search_patterns &&
+ ! match_search_patterns(lb->search_patterns, author, date, message,
+ log_entry->changed_paths2, pool))
{
if (log_entry->has_children)
APR_ARRAY_PUSH(lb->merge_stack, svn_revnum_t) = log_entry->revision;
@@ -505,10 +546,9 @@ log_entry_receiver_xml(void *baton,
}
/* Match search pattern before XML-escaping. */
- if (lb->search_pattern &&
- ! match_search_pattern(lb->search_pattern, author, date, message,
- log_entry->changed_paths2,
- lb->case_insensitive_search, pool))
+ if (lb->search_patterns &&
+ ! match_search_patterns(lb->search_patterns, author, date, message,
+ log_entry->changed_paths2, pool))
{
if (log_entry->has_children)
APR_ARRAY_PUSH(lb->merge_stack, svn_revnum_t) = log_entry->revision;
@@ -586,7 +626,13 @@ log_entry_receiver_xml(void *baton,
/* <path action="X"> */
svn_xml_make_open_tag(&sb, pool, svn_xml_protect_pcdata, "path",
"action", action,
- "kind", svn_cl__node_kind_str_xml(log_item->node_kind), NULL);
+ "kind", svn_cl__node_kind_str_xml(
+ log_item->node_kind),
+ "text-mods", svn_tristate__to_word(
+ log_item->text_modified),
+ "prop-mods", svn_tristate__to_word(
+ log_item->props_modified),
+ NULL);
}
/* xxx</path> */
svn_xml_escape_cdata_cstring(&sb, path, pool);
@@ -609,7 +655,7 @@ log_entry_receiver_xml(void *baton,
svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "revprops", NULL);
SVN_ERR(svn_cl__print_xml_prop_hash(&sb, log_entry->revprops,
FALSE, /* name_only */
- pool));
+ FALSE, pool));
svn_xml_make_close_tag(&sb, pool, "revprops");
}
@@ -740,8 +786,7 @@ svn_cl__log(apr_getopt_t *os,
: opt_state->depth;
lb.diff_extensions = opt_state->extensions;
lb.merge_stack = apr_array_make(pool, 0, sizeof(svn_revnum_t));
- lb.search_pattern = opt_state->search_pattern;
- lb.case_insensitive_search = opt_state->case_insensitive_search;
+ lb.search_patterns = opt_state->search_patterns;
lb.pool = pool;
if (opt_state->xml)