You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by gb...@apache.org on 2013/11/16 15:36:47 UTC
svn commit: r1542514 [3/3] - in /subversion/branches/invoke-diff3-feature:
./ subversion/include/ subversion/include/private/
subversion/libsvn_client/ subversion/libsvn_subr/ subversion/libsvn_wc/
subversion/svn/ subversion/tests/cmdline/getopt_tests_...
Modified: subversion/branches/invoke-diff3-feature/subversion/include/private/svn_wc_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff3-feature/subversion/include/private/svn_wc_private.h?rev=1542514&r1=1542513&r2=1542514&view=diff
==============================================================================
--- subversion/branches/invoke-diff3-feature/subversion/include/private/svn_wc_private.h (original)
+++ subversion/branches/invoke-diff3-feature/subversion/include/private/svn_wc_private.h Sat Nov 16 14:36:46 2013
@@ -77,6 +77,7 @@ svn_wc__get_file_external_editor(const s
apr_array_header_t *iprops,
svn_boolean_t use_commit_times,
const char *diff3_cmd,
+ const char *invoke_diff3_cmd,
const apr_array_header_t *preserved_exts,
const char *record_ancestor_abspath,
const char *recorded_url,
@@ -1507,6 +1508,7 @@ svn_wc__get_update_editor(const svn_delt
svn_boolean_t server_performs_filtering,
svn_boolean_t clean_checkout,
const char *diff3_cmd,
+ const char *invoke_diff3_cmd,
const apr_array_header_t *preserved_exts,
svn_wc_dirents_func_t fetch_dirents_func,
void *fetch_dirents_baton,
@@ -1549,6 +1551,7 @@ svn_wc__get_switch_editor(const svn_delt
svn_boolean_t allow_unver_obstructions,
svn_boolean_t server_performs_filtering,
const char *diff3_cmd,
+ const char *invoke_diff3_cmd,
const apr_array_header_t *preserved_exts,
svn_wc_dirents_func_t fetch_dirents_func,
void *fetch_dirents_baton,
Modified: subversion/branches/invoke-diff3-feature/subversion/include/svn_config.h
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff3-feature/subversion/include/svn_config.h?rev=1542514&r1=1542513&r2=1542514&view=diff
==============================================================================
--- subversion/branches/invoke-diff3-feature/subversion/include/svn_config.h (original)
+++ subversion/branches/invoke-diff3-feature/subversion/include/svn_config.h Sat Nov 16 14:36:46 2013
@@ -116,6 +116,8 @@ typedef struct svn_config_t svn_config_t
#define SVN_CONFIG_OPTION_DIFF3_HAS_PROGRAM_ARG "diff3-has-program-arg"
/** @since New in 1.9. */
#define SVN_CONFIG_OPTION_INVOKE_DIFF_CMD "invoke-diff-cmd"
+/** @since New in 1.9. */
+#define SVN_CONFIG_OPTION_INVOKE_DIFF3_CMD "invoke-diff3-cmd"
#define SVN_CONFIG_OPTION_MERGE_TOOL_CMD "merge-tool-cmd"
#define SVN_CONFIG_SECTION_MISCELLANY "miscellany"
#define SVN_CONFIG_OPTION_GLOBAL_IGNORES "global-ignores"
Modified: subversion/branches/invoke-diff3-feature/subversion/include/svn_error_codes.h
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff3-feature/subversion/include/svn_error_codes.h?rev=1542514&r1=1542513&r2=1542514&view=diff
==============================================================================
--- subversion/branches/invoke-diff3-feature/subversion/include/svn_error_codes.h (original)
+++ subversion/branches/invoke-diff3-feature/subversion/include/svn_error_codes.h Sat Nov 16 14:36:46 2013
@@ -1451,8 +1451,13 @@ SVN_ERROR_START
SVN_ERR_CL_CATEGORY_START + 10,
"No external merge tool available")
- SVN_ERRDEF(SVN_ERR_CL_ERROR_PROCESSING_EXTERNALS,
+ /** @since New in 1.9. */
+ SVN_ERRDEF(SVN_ERR_CL_NO_EXTERNAL_DIFF3_TOOL,
SVN_ERR_CL_CATEGORY_START + 11,
+ "No external invoke-diff3 tool available")
+
+ SVN_ERRDEF(SVN_ERR_CL_ERROR_PROCESSING_EXTERNALS,
+ SVN_ERR_CL_CATEGORY_START + 12,
"Failed processing one or more externals definitions")
/* ra_svn errors */
Modified: subversion/branches/invoke-diff3-feature/subversion/include/svn_io.h
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff3-feature/subversion/include/svn_io.h?rev=1542514&r1=1542513&r2=1542514&view=diff
==============================================================================
--- subversion/branches/invoke-diff3-feature/subversion/include/svn_io.h (original)
+++ subversion/branches/invoke-diff3-feature/subversion/include/svn_io.h Sat Nov 16 14:36:46 2013
@@ -2378,6 +2378,25 @@ svn_io_run_external_diff(const char *dir
const char *external_diff_cmd,
apr_pool_t *scratch_pool);
+/** Run the external merge command defined by the invoke-diff3-cmd
+ * option.
+ *
+ * @since New in 1.9.
+ */
+svn_error_t *
+svn_io_run_invoke_diff3(int *exitcode,
+ const char *dir,
+ const char *mine,
+ const char *older,
+ const char *yours,
+ const char *mine_label,
+ const char *older_label,
+ const char *yours_label,
+ apr_file_t *merged,
+ const char *diff3_cmd,
+ apr_pool_t *pool);
+
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
Modified: subversion/branches/invoke-diff3-feature/subversion/include/svn_wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff3-feature/subversion/include/svn_wc.h?rev=1542514&r1=1542513&r2=1542514&view=diff
==============================================================================
--- subversion/branches/invoke-diff3-feature/subversion/include/svn_wc.h (original)
+++ subversion/branches/invoke-diff3-feature/subversion/include/svn_wc.h Sat Nov 16 14:36:46 2013
@@ -7011,6 +7011,35 @@ typedef enum svn_wc_merge_outcome_t
* @since New in 1.8.
*/
svn_error_t *
+svn_wc_merge6(enum svn_wc_merge_outcome_t *merge_content_outcome,
+ enum svn_wc_notify_state_t *merge_props_state,
+ svn_wc_context_t *wc_ctx,
+ const char *left_abspath,
+ const char *right_abspath,
+ const char *target_abspath,
+ const char *left_label,
+ const char *right_label,
+ const char *target_label,
+ const svn_wc_conflict_version_t *left_version,
+ const svn_wc_conflict_version_t *right_version,
+ svn_boolean_t dry_run,
+ const char *diff3_cmd,
+ const char *invoke_diff3_cmd,
+ const apr_array_header_t *merge_options,
+ apr_hash_t *original_props,
+ const apr_array_header_t *prop_diff,
+ svn_wc_conflict_resolver_func2_t conflict_func,
+ void *conflict_baton,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ apr_pool_t *scratch_pool);
+
+/** Similar to svn_wc_merge6() but with @a invoke_diff3_cmd.
+ *
+ * @since New in 1.9.
+ */
+SVN_DEPRECATED
+svn_error_t *
svn_wc_merge5(enum svn_wc_merge_outcome_t *merge_content_outcome,
enum svn_wc_notify_state_t *merge_props_state,
svn_wc_context_t *wc_ctx,
Modified: subversion/branches/invoke-diff3-feature/subversion/libsvn_client/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff3-feature/subversion/libsvn_client/externals.c?rev=1542514&r1=1542513&r2=1542514&view=diff
==============================================================================
--- subversion/branches/invoke-diff3-feature/subversion/libsvn_client/externals.c (original)
+++ subversion/branches/invoke-diff3-feature/subversion/libsvn_client/externals.c Sat Nov 16 14:36:46 2013
@@ -364,7 +364,8 @@ switch_file_external(const char *local_a
? svn_hash_gets(ctx->config, SVN_CONFIG_CATEGORY_CONFIG)
: NULL;
svn_boolean_t use_commit_times;
- const char *diff3_cmd;
+ const char *diff3_cmd = NULL;
+ const char *invoke_diff3_cmd = NULL;
const char *preserved_exts_str;
const apr_array_header_t *preserved_exts;
svn_node_kind_t kind, external_kind;
@@ -376,13 +377,23 @@ switch_file_external(const char *local_a
SVN_CONFIG_SECTION_MISCELLANY,
SVN_CONFIG_OPTION_USE_COMMIT_TIMES, FALSE));
- /* Get the external diff3, if any. */
+ /* Get the external *_diff3_cmd, if any.
+ Precedence: If there is no invoke_diff3_cmd on the cmd line,
+ check if there is a diff3-cmd in the config file. If there is,
+ do not check invoke_diff3_cmd in the config file.*/
svn_config_get(cfg, &diff3_cmd, SVN_CONFIG_SECTION_HELPERS,
SVN_CONFIG_OPTION_DIFF3_CMD, NULL);
if (diff3_cmd != NULL)
SVN_ERR(svn_path_cstring_to_utf8(&diff3_cmd, diff3_cmd, scratch_pool));
-
+ else
+ {
+ svn_config_get(cfg, &invoke_diff3_cmd, SVN_CONFIG_SECTION_HELPERS,
+ SVN_CONFIG_OPTION_INVOKE_DIFF3_CMD, NULL);
+ if (invoke_diff3_cmd != NULL)
+ SVN_ERR(svn_path_cstring_to_utf8(&invoke_diff3_cmd,
+ invoke_diff3_cmd, scratch_pool));
+ }
/* See which files the user wants to preserve the extension of when
conflict files are made. */
svn_config_get(cfg, &preserved_exts_str, SVN_CONFIG_SECTION_MISCELLANY,
@@ -483,7 +494,8 @@ switch_file_external(const char *local_a
switch_loc->repos_uuid,
inherited_props,
use_commit_times,
- diff3_cmd, preserved_exts,
+ diff3_cmd, invoke_diff3_cmd,
+ preserved_exts,
def_dir_abspath,
url, peg_revision, revision,
ctx->conflict_func2,
Modified: subversion/branches/invoke-diff3-feature/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff3-feature/subversion/libsvn_client/merge.c?rev=1542514&r1=1542513&r2=1542514&view=diff
==============================================================================
--- subversion/branches/invoke-diff3-feature/subversion/libsvn_client/merge.c (original)
+++ subversion/branches/invoke-diff3-feature/subversion/libsvn_client/merge.c Sat Nov 16 14:36:46 2013
@@ -316,10 +316,13 @@ typedef struct merge_cmd_baton_t {
/* A list of tree conflict victim absolute paths which may be NULL. */
apr_hash_t *tree_conflicted_abspaths;
- /* The diff3_cmd in ctx->config, if any, else null. We could just
- extract this as needed, but since more than one caller uses it,
- we just set it up when this baton is created. */
+ /* The diff3_cmd and invoke_diff3_cmd in ctx->config, if any, else
+ null. We could just extract this as needed, but since more than
+ one caller uses it, we just set it up when this baton is
+ created. */
const char *diff3_cmd;
+ const char *invoke_diff3_cmd;
+
const apr_array_header_t *merge_options;
/* RA sessions used throughout a merge operation. Opened/re-parented
@@ -2040,11 +2043,13 @@ merge_file_changed(const char *relpath,
/* Do property merge and text merge in one step so that keyword expansion
takes into account the new property values. */
- SVN_ERR(svn_wc_merge5(&content_outcome, &property_state, ctx->wc_ctx,
+ SVN_ERR(svn_wc_merge6(&content_outcome, &property_state, ctx->wc_ctx,
left_file, right_file, local_abspath,
left_label, right_label, target_label,
left, right,
- merge_b->dry_run, merge_b->diff3_cmd,
+ merge_b->dry_run,
+ merge_b->diff3_cmd,
+ merge_b->invoke_diff3_cmd,
merge_b->merge_options,
left_props, prop_changes,
NULL, NULL,
@@ -9667,7 +9672,8 @@ do_merge(apr_hash_t **modified_subtrees,
{
merge_cmd_baton_t merge_cmd_baton = { 0 };
svn_config_t *cfg;
- const char *diff3_cmd;
+ const char *diff3_cmd = NULL;
+ const char *invoke_diff3_cmd = NULL;
int i;
svn_boolean_t checked_mergeinfo_capability = FALSE;
svn_ra_session_t *ra_session1 = NULL, *ra_session2 = NULL;
@@ -9718,7 +9724,11 @@ do_merge(apr_hash_t **modified_subtrees,
if (depth == svn_depth_unknown)
depth = svn_depth_infinity;
- /* Set up the diff3 command, so various callers don't have to. */
+ /* Get the external *_diff3_cmd, if any.
+ Precedence: If there is no invoke_diff3_cmd on the cmd line,
+ check if there is a diff3-cmd in the config file. If there is,
+ do not check invoke_diff3_cmd in the config file.*/
+
cfg = ctx->config
? svn_hash_gets(ctx->config, SVN_CONFIG_CATEGORY_CONFIG)
: NULL;
@@ -9727,6 +9737,14 @@ do_merge(apr_hash_t **modified_subtrees,
if (diff3_cmd != NULL)
SVN_ERR(svn_path_cstring_to_utf8(&diff3_cmd, diff3_cmd, scratch_pool));
+ else
+ {
+ svn_config_get(cfg, &invoke_diff3_cmd, SVN_CONFIG_SECTION_HELPERS,
+ SVN_CONFIG_OPTION_INVOKE_DIFF3_CMD, NULL);
+ if (invoke_diff3_cmd != NULL)
+ SVN_ERR(svn_path_cstring_to_utf8(&invoke_diff3_cmd,
+ invoke_diff3_cmd, scratch_pool));
+ }
/* Build the merge context baton (or at least the parts of it that
don't need to be reset for each merge source). */
@@ -9743,6 +9761,7 @@ do_merge(apr_hash_t **modified_subtrees,
merge_cmd_baton.pool = iterpool;
merge_cmd_baton.merge_options = merge_options;
merge_cmd_baton.diff3_cmd = diff3_cmd;
+ merge_cmd_baton.invoke_diff3_cmd = invoke_diff3_cmd;
merge_cmd_baton.use_sleep = use_sleep;
/* Do we already know the specific subtrees with mergeinfo we want
Modified: subversion/branches/invoke-diff3-feature/subversion/libsvn_client/switch.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff3-feature/subversion/libsvn_client/switch.c?rev=1542514&r1=1542513&r2=1542514&view=diff
==============================================================================
--- subversion/branches/invoke-diff3-feature/subversion/libsvn_client/switch.c (original)
+++ subversion/branches/invoke-diff3-feature/subversion/libsvn_client/switch.c Sat Nov 16 14:36:46 2013
@@ -106,6 +106,7 @@ switch_internal(svn_revnum_t *result_rev
svn_ra_session_t *ra_session;
svn_revnum_t revnum;
const char *diff3_cmd;
+ const char *invoke_diff3_cmd;
apr_hash_t *wcroot_iprops;
apr_array_header_t *inherited_props;
svn_boolean_t use_commit_times;
@@ -134,6 +135,17 @@ switch_internal(svn_revnum_t *result_rev
if (diff3_cmd != NULL)
SVN_ERR(svn_path_cstring_to_utf8(&diff3_cmd, diff3_cmd, pool));
+ else
+ /* Get the external invoke_diff3_cmd, if any. */
+ svn_config_get(cfg, &invoke_diff3_cmd, SVN_CONFIG_SECTION_HELPERS,
+ SVN_CONFIG_OPTION_INVOKE_DIFF3_CMD, NULL);
+
+ if (diff3_cmd != NULL)
+ SVN_ERR(svn_path_cstring_to_utf8(&diff3_cmd, diff3_cmd, pool));
+ else
+ if (invoke_diff3_cmd != NULL)
+ SVN_ERR(svn_path_cstring_to_utf8(&invoke_diff3_cmd, invoke_diff3_cmd, pool));
+
/* See if the user wants last-commit timestamps instead of current ones. */
SVN_ERR(svn_config_get_bool(cfg, &use_commit_times,
@@ -312,7 +324,8 @@ switch_internal(svn_revnum_t *result_rev
use_commit_times, depth,
depth_is_sticky, allow_unver_obstructions,
server_supports_depth,
- diff3_cmd, preserved_exts,
+ diff3_cmd, invoke_diff3_cmd,
+ preserved_exts,
svn_client__dirent_fetcher, &dfb,
conflicted_paths ? record_conflict : NULL,
conflicted_paths,
Modified: subversion/branches/invoke-diff3-feature/subversion/libsvn_client/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff3-feature/subversion/libsvn_client/update.c?rev=1542514&r1=1542513&r2=1542514&view=diff
==============================================================================
--- subversion/branches/invoke-diff3-feature/subversion/libsvn_client/update.c (original)
+++ subversion/branches/invoke-diff3-feature/subversion/libsvn_client/update.c Sat Nov 16 14:36:46 2013
@@ -226,7 +226,8 @@ update_internal(svn_revnum_t *result_rev
svn_revnum_t revnum;
svn_boolean_t use_commit_times;
svn_boolean_t clean_checkout = FALSE;
- const char *diff3_cmd;
+ const char *diff3_cmd = NULL;
+ const char *invoke_diff3_cmd = NULL;
apr_hash_t *wcroot_iprops;
svn_opt_revision_t opt_rev;
svn_ra_session_t *ra_session;
@@ -332,13 +333,24 @@ update_internal(svn_revnum_t *result_rev
/* check whether the "clean c/o" optimization is applicable */
SVN_ERR(is_empty_wc(&clean_checkout, local_abspath, anchor_abspath, pool));
- /* Get the external diff3, if any. */
+ /* Get the external *_diff3_cmd, if any.
+ Precedence: If there is no invoke_diff3_cmd on the cmd line,
+ check if there is a diff3-cmd in the config file. If there is,
+ do not check invoke_diff3_cmd in the config file.*/
svn_config_get(cfg, &diff3_cmd, SVN_CONFIG_SECTION_HELPERS,
SVN_CONFIG_OPTION_DIFF3_CMD, NULL);
if (diff3_cmd != NULL)
SVN_ERR(svn_path_cstring_to_utf8(&diff3_cmd, diff3_cmd, pool));
-
+ else
+ {
+ svn_config_get(cfg, &invoke_diff3_cmd, SVN_CONFIG_SECTION_HELPERS,
+ SVN_CONFIG_OPTION_INVOKE_DIFF3_CMD, NULL);
+ if (invoke_diff3_cmd != NULL)
+ SVN_ERR(svn_path_cstring_to_utf8(&invoke_diff3_cmd,
+ invoke_diff3_cmd, pool));
+ }
+
/* See if the user wants last-commit timestamps instead of current ones. */
SVN_ERR(svn_config_get_bool(cfg, &use_commit_times,
SVN_CONFIG_SECTION_MISCELLANY,
@@ -429,7 +441,8 @@ update_internal(svn_revnum_t *result_rev
adds_as_modification,
server_supports_depth,
clean_checkout,
- diff3_cmd, preserved_exts,
+ diff3_cmd, invoke_diff3_cmd,
+ preserved_exts,
svn_client__dirent_fetcher, &dfb,
conflicted_paths ? record_conflict : NULL,
conflicted_paths,
Modified: subversion/branches/invoke-diff3-feature/subversion/libsvn_subr/config_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff3-feature/subversion/libsvn_subr/config_file.c?rev=1542514&r1=1542513&r2=1542514&view=diff
==============================================================================
--- subversion/branches/invoke-diff3-feature/subversion/libsvn_subr/config_file.c (original)
+++ subversion/branches/invoke-diff3-feature/subversion/libsvn_subr/config_file.c Sat Nov 16 14:36:46 2013
@@ -1192,6 +1192,11 @@ svn_config_ensure(const char *config_dir
"### This will override the compile-time default, which is to use" NL
"### Subversion's internal diff implementation." NL
"# invoke-diff-cmd = (see svn help diff for examples)" NL
+ "### Set invoke-diff3-cmd to the absolute path of your 'diff'" NL
+ "### program." NL
+ "### This will override the compile-time default, which is to use" NL
+ "### Subversion's internal merge implementation." NL
+ "# invoke-diff3-cmd = (see svn help merge for examples)" NL
"### Set merge-tool-cmd to the command used to invoke your external" NL
"### merging tool of choice. Subversion will pass 5 arguments to" NL
"### the specified command: base theirs mine merged wcfile" NL
Modified: subversion/branches/invoke-diff3-feature/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff3-feature/subversion/libsvn_subr/io.c?rev=1542514&r1=1542513&r2=1542514&view=diff
==============================================================================
--- subversion/branches/invoke-diff3-feature/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/invoke-diff3-feature/subversion/libsvn_subr/io.c Sat Nov 16 14:36:46 2013
@@ -3371,6 +3371,59 @@ svn_io_run_diff3_3(int *exitcode,
return SVN_NO_ERROR;
}
+svn_error_t *
+svn_io_run_invoke_diff3(int *exitcode,
+ const char *dir,
+ const char *mine,
+ const char *older,
+ const char *yours,
+ const char *mine_label,
+ const char *older_label,
+ const char *yours_label,
+ apr_file_t *merged,
+ const char *invoke_diff3_cmd,
+ apr_pool_t *pool)
+{
+
+ const char ** cmd;
+
+ apr_pool_t *scratch_pool = svn_pool_create(pool);
+
+ if (0 == strlen(invoke_diff3_cmd))
+ return svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL, NULL);
+
+ cmd = svn_io__create_custom_diff_cmd(mine_label, yours_label, older_label,
+ mine, yours, older,
+ invoke_diff3_cmd, scratch_pool);
+
+ SVN_ERR(svn_io_run_cmd(dir, cmd[0], cmd, exitcode, NULL, TRUE,
+ NULL, merged, NULL, scratch_pool));
+
+
+ /* According to the diff3 docs, a '0' means the merge was clean, and
+ '1' means conflict markers were found. Anything else is real
+ error. */
+ if ((*exitcode != 0) && (*exitcode != 1))
+ {
+
+ int i;
+ const char *failed_command = "";
+
+ for (i = 0; cmd[i]; ++i)
+ failed_command = apr_pstrcat(pool, failed_command,
+ cmd[i], " ", (char*) NULL);
+ svn_pool_destroy(scratch_pool);
+ return svn_error_createf(SVN_ERR_EXTERNAL_PROGRAM, NULL,
+ _("'%s' was expanded to '%s' and returned %d"),
+ invoke_diff3_cmd,
+ failed_command,
+ *exitcode);
+ }
+ else
+ svn_pool_destroy(scratch_pool);
+
+ return SVN_NO_ERROR;
+}
/* Canonicalize a string for hashing. Modifies KEY in place. */
static APR_INLINE char *
Modified: subversion/branches/invoke-diff3-feature/subversion/libsvn_wc/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff3-feature/subversion/libsvn_wc/deprecated.c?rev=1542514&r1=1542513&r2=1542514&view=diff
==============================================================================
--- subversion/branches/invoke-diff3-feature/subversion/libsvn_wc/deprecated.c (original)
+++ subversion/branches/invoke-diff3-feature/subversion/libsvn_wc/deprecated.c Sat Nov 16 14:36:46 2013
@@ -3492,6 +3492,7 @@ svn_wc_get_update_editor4(const svn_delt
server_performs_filtering,
clean_checkout,
diff3_cmd,
+ NULL,
preserved_exts,
fetch_dirents_func, fetch_dirents_baton,
conflict_func, conflict_baton,
@@ -3676,6 +3677,7 @@ svn_wc_get_switch_editor4(const svn_delt
allow_unver_obstructions,
server_performs_filtering,
diff3_cmd,
+ NULL,
preserved_exts,
fetch_dirents_func, fetch_dirents_baton,
conflict_func, conflict_baton,
@@ -4402,6 +4404,53 @@ svn_wc_copy(const char *src_path,
/*** From merge.c ***/
svn_error_t *
+svn_wc_merge5(enum svn_wc_merge_outcome_t *merge_content_outcome,
+ enum svn_wc_notify_state_t *merge_props_outcome,
+ svn_wc_context_t *wc_ctx,
+ const char *left_abspath,
+ const char *right_abspath,
+ const char *target_abspath,
+ const char *left_label,
+ const char *right_label,
+ const char *target_label,
+ const svn_wc_conflict_version_t *left_version,
+ const svn_wc_conflict_version_t *right_version,
+ svn_boolean_t dry_run,
+ const char *diff3_cmd,
+ const apr_array_header_t *merge_options,
+ apr_hash_t *original_props,
+ const apr_array_header_t *prop_diff,
+ svn_wc_conflict_resolver_func2_t conflict_func,
+ void *conflict_baton,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ apr_pool_t *scratch_pool)
+{
+ return svn_wc_merge6(merge_content_outcome,
+ merge_props_outcome,
+ wc_ctx,
+ left_abspath,
+ right_abspath,
+ target_abspath,
+ left_label,
+ right_label,
+ target_label,
+ left_version,
+ right_version,
+ dry_run,
+ diff3_cmd,
+ NULL,
+ merge_options,
+ original_props,
+ prop_diff,
+ conflict_func,
+ conflict_baton,
+ cancel_func,
+ cancel_baton,
+ scratch_pool);
+}
+
+svn_error_t *
svn_wc_merge4(enum svn_wc_merge_outcome_t *merge_outcome,
svn_wc_context_t *wc_ctx,
const char *left_abspath,
@@ -4816,3 +4865,4 @@ svn_wc__conflict_description2_dup(const
return new_conflict;
}
+
Modified: subversion/branches/invoke-diff3-feature/subversion/libsvn_wc/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff3-feature/subversion/libsvn_wc/externals.c?rev=1542514&r1=1542513&r2=1542514&view=diff
==============================================================================
--- subversion/branches/invoke-diff3-feature/subversion/libsvn_wc/externals.c (original)
+++ subversion/branches/invoke-diff3-feature/subversion/libsvn_wc/externals.c Sat Nov 16 14:36:46 2013
@@ -402,7 +402,8 @@ struct edit_baton
/* Information from the caller */
svn_boolean_t use_commit_times;
const apr_array_header_t *ext_patterns;
- const char *diff3cmd;
+ const char *diff3_cmd;
+ const char *invoke_diff3_cmd;
const char *url;
const char *repos_root_url;
@@ -813,7 +814,8 @@ close_file(void *file_baton,
eb->original_revision,
*eb->target_revision,
eb->propchanges,
- eb->diff3cmd,
+ eb->diff3_cmd,
+ eb->invoke_diff3_cmd,
eb->cancel_func,
eb->cancel_baton,
pool, pool));
@@ -984,6 +986,7 @@ svn_wc__get_file_external_editor(const s
apr_array_header_t *iprops,
svn_boolean_t use_commit_times,
const char *diff3_cmd,
+ const char *invoke_diff3_cmd,
const apr_array_header_t *preserved_exts,
const char *record_ancestor_abspath,
const char *recorded_url,
@@ -1021,7 +1024,8 @@ svn_wc__get_file_external_editor(const s
eb->use_commit_times = use_commit_times;
eb->ext_patterns = preserved_exts;
- eb->diff3cmd = diff3_cmd;
+ eb->diff3_cmd = diff3_cmd;
+ eb->invoke_diff3_cmd = invoke_diff3_cmd;
eb->record_ancestor_abspath = apr_pstrdup(edit_pool,record_ancestor_abspath);
eb->recorded_repos_relpath = svn_uri_skip_ancestor(repos_root_url, recorded_url,
Modified: subversion/branches/invoke-diff3-feature/subversion/libsvn_wc/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff3-feature/subversion/libsvn_wc/merge.c?rev=1542514&r1=1542513&r2=1542514&view=diff
==============================================================================
--- subversion/branches/invoke-diff3-feature/subversion/libsvn_wc/merge.c (original)
+++ subversion/branches/invoke-diff3-feature/subversion/libsvn_wc/merge.c Sat Nov 16 14:36:46 2013
@@ -45,11 +45,12 @@ typedef struct merge_target_t
const char *local_abspath; /* The absolute path to target */
const char *wri_abspath; /* The working copy of target */
- apr_hash_t *old_actual_props; /* The set of actual properties
+ apr_hash_t *old_actual_props; /* The set of actual properties
before merging */
const apr_array_header_t *prop_diff; /* The property changes */
const char *diff3_cmd; /* The diff3 command and options */
+ const char *invoke_diff3_cmd; /* The invoke_diff3_cmd command */
const apr_array_header_t *merge_options;
} merge_target_t;
@@ -437,6 +438,7 @@ static svn_error_t *
do_text_merge_external(svn_boolean_t *contains_conflicts,
apr_file_t *result_f,
const char *diff3_cmd,
+ const char *invoke_diff3_cmd,
const apr_array_header_t *merge_options,
const char *detranslated_target,
const char *left_abspath,
@@ -448,17 +450,26 @@ do_text_merge_external(svn_boolean_t *co
{
int exit_code;
- SVN_ERR(svn_io_run_diff3_3(&exit_code, ".",
- detranslated_target, left_abspath, right_abspath,
- target_label, left_label, right_label,
- result_f, diff3_cmd,
- merge_options, scratch_pool));
-
- *contains_conflicts = exit_code == 1;
+ if (diff3_cmd)
+ SVN_ERR(svn_io_run_diff3_3(&exit_code, ".",
+ detranslated_target, left_abspath, right_abspath,
+ target_label, left_label, right_label,
+ result_f, diff3_cmd,
+ merge_options, scratch_pool));
+ else
+ SVN_ERR(svn_io_run_invoke_diff3(&exit_code, ".",
+ detranslated_target,
+ left_abspath, right_abspath,
+ target_label, left_label, right_label,
+ result_f, invoke_diff3_cmd,
+ scratch_pool));
+
+ *contains_conflicts = (exit_code == 1);
return SVN_NO_ERROR;
}
+
/* Preserve the three pre-merge files.
Create three empty files, with unique names that each include the
@@ -843,11 +854,13 @@ merge_text_file(svn_skel_t **work_items,
temp_dir, base_name, ".tmp",
svn_io_file_del_none, pool, pool));
- /* Run the external or internal merge, as requested. */
- if (mt->diff3_cmd)
+ /* Run the external (old-style or new-style) or internal merge, as
+ requested. */
+ if (mt->diff3_cmd || mt->invoke_diff3_cmd)
SVN_ERR(do_text_merge_external(&contains_conflicts,
result_f,
mt->diff3_cmd,
+ mt->invoke_diff3_cmd,
mt->merge_options,
detranslated_target_abspath,
left_abspath,
@@ -1080,6 +1093,7 @@ svn_wc__internal_merge(svn_skel_t **work
apr_hash_t *old_actual_props,
svn_boolean_t dry_run,
const char *diff3_cmd,
+ const char *invoke_diff3_cmd,
const apr_array_header_t *merge_options,
const apr_array_header_t *prop_diff,
svn_cancel_func_t cancel_func,
@@ -1106,6 +1120,7 @@ svn_wc__internal_merge(svn_skel_t **work
mt.old_actual_props = old_actual_props;
mt.prop_diff = prop_diff;
mt.diff3_cmd = diff3_cmd;
+ mt.invoke_diff3_cmd = invoke_diff3_cmd;
mt.merge_options = merge_options;
/* Decide if the merge target is a text or binary file. */
@@ -1121,7 +1136,9 @@ svn_wc__internal_merge(svn_skel_t **work
}
SVN_ERR(detranslate_wc_file(&detranslated_target_abspath, &mt,
- (! is_binary) && diff3_cmd != NULL,
+ (! is_binary)
+ && diff3_cmd != NULL
+ && invoke_diff3_cmd != NULL,
target_abspath,
cancel_func, cancel_baton,
scratch_pool, scratch_pool));
@@ -1193,7 +1210,7 @@ svn_wc__internal_merge(svn_skel_t **work
svn_error_t *
-svn_wc_merge5(enum svn_wc_merge_outcome_t *merge_content_outcome,
+svn_wc_merge6(enum svn_wc_merge_outcome_t *merge_content_outcome,
enum svn_wc_notify_state_t *merge_props_outcome,
svn_wc_context_t *wc_ctx,
const char *left_abspath,
@@ -1206,6 +1223,7 @@ svn_wc_merge5(enum svn_wc_merge_outcome_
const svn_wc_conflict_version_t *right_version,
svn_boolean_t dry_run,
const char *diff3_cmd,
+ const char *invoke_diff3_cmd,
const apr_array_header_t *merge_options,
apr_hash_t *original_props,
const apr_array_header_t *prop_diff,
@@ -1345,6 +1363,7 @@ svn_wc_merge5(enum svn_wc_merge_outcome_
old_actual_props,
dry_run,
diff3_cmd,
+ invoke_diff3_cmd,
merge_options,
prop_diff,
cancel_func, cancel_baton,
Modified: subversion/branches/invoke-diff3-feature/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff3-feature/subversion/libsvn_wc/update_editor.c?rev=1542514&r1=1542513&r2=1542514&view=diff
==============================================================================
--- subversion/branches/invoke-diff3-feature/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/invoke-diff3-feature/subversion/libsvn_wc/update_editor.c Sat Nov 16 14:36:46 2013
@@ -223,6 +223,10 @@ struct edit_baton
internal merge code is used). */
const char *diff3_cmd;
+ /* External custom invoke diff3 to use for merges (can be null, in
+ which case internal merge code is used). */
+ const char *invoke_diff3_cmd;
+
/* Externals handler */
svn_wc_external_update_t external_func;
void *external_baton;
@@ -3900,6 +3904,7 @@ svn_wc__perform_file_merge(svn_skel_t **
svn_revnum_t target_revision,
const apr_array_header_t *propchanges,
const char *diff3_cmd,
+ const char *invoke_diff3_cmd,
svn_cancel_func_t cancel_func,
void *cancel_baton,
apr_pool_t *result_pool,
@@ -3977,7 +3982,8 @@ svn_wc__perform_file_merge(svn_skel_t **
oldrev_str, newrev_str, mine_str,
old_actual_props,
FALSE /* dry_run */,
- diff3_cmd, NULL, propchanges,
+ diff3_cmd, invoke_diff3_cmd,
+ NULL, propchanges,
cancel_func, cancel_baton,
result_pool, scratch_pool));
@@ -4138,6 +4144,7 @@ merge_file(svn_skel_t **work_items,
*eb->target_revision,
fb->propchanges,
eb->diff3_cmd,
+ eb->invoke_diff3_cmd,
eb->cancel_func, eb->cancel_baton,
result_pool, scratch_pool));
} /* end: working file exists and has mods */
@@ -4831,6 +4838,7 @@ make_editor(svn_revnum_t *target_revisio
svn_wc_external_update_t external_func,
void *external_baton,
const char *diff3_cmd,
+ const char *invoke_diff3_cmd,
const apr_array_header_t *preserved_exts,
const svn_delta_editor_t **editor,
void **edit_baton,
@@ -4901,6 +4909,7 @@ make_editor(svn_revnum_t *target_revisio
eb->external_func = external_func;
eb->external_baton = external_baton;
eb->diff3_cmd = diff3_cmd;
+ eb->invoke_diff3_cmd = invoke_diff3_cmd;
eb->cancel_func = cancel_func;
eb->cancel_baton = cancel_baton;
eb->conflict_func = conflict_func;
@@ -5107,6 +5116,7 @@ svn_wc__get_update_editor(const svn_delt
svn_boolean_t server_performs_filtering,
svn_boolean_t clean_checkout,
const char *diff3_cmd,
+ const char *invoke_diff3_cmd,
const apr_array_header_t *preserved_exts,
svn_wc_dirents_func_t fetch_dirents_func,
void *fetch_dirents_baton,
@@ -5131,7 +5141,8 @@ svn_wc__get_update_editor(const svn_delt
fetch_dirents_func, fetch_dirents_baton,
conflict_func, conflict_baton,
external_func, external_baton,
- diff3_cmd, preserved_exts, editor, edit_baton,
+ diff3_cmd, invoke_diff3_cmd,
+ preserved_exts, editor, edit_baton,
result_pool, scratch_pool);
}
@@ -5150,6 +5161,7 @@ svn_wc__get_switch_editor(const svn_delt
svn_boolean_t allow_unver_obstructions,
svn_boolean_t server_performs_filtering,
const char *diff3_cmd,
+ const char *invoke_diff3_cmd,
const apr_array_header_t *preserved_exts,
svn_wc_dirents_func_t fetch_dirents_func,
void *fetch_dirents_baton,
@@ -5178,7 +5190,8 @@ svn_wc__get_switch_editor(const svn_delt
fetch_dirents_func, fetch_dirents_baton,
conflict_func, conflict_baton,
external_func, external_baton,
- diff3_cmd, preserved_exts,
+ diff3_cmd, invoke_diff3_cmd,
+ preserved_exts,
editor, edit_baton,
result_pool, scratch_pool);
}
Modified: subversion/branches/invoke-diff3-feature/subversion/libsvn_wc/wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff3-feature/subversion/libsvn_wc/wc.h?rev=1542514&r1=1542513&r2=1542514&view=diff
==============================================================================
--- subversion/branches/invoke-diff3-feature/subversion/libsvn_wc/wc.h (original)
+++ subversion/branches/invoke-diff3-feature/subversion/libsvn_wc/wc.h Sat Nov 16 14:36:46 2013
@@ -413,8 +413,8 @@ svn_wc__internal_file_modified_p(svn_boo
When DRY_RUN is true, no actual changes are made to the working copy.
- If DIFF3_CMD is specified, the given external diff3 tool will
- be used instead of our built in diff3 routines.
+ If DIFF3_CMD or INVOKE_DIFF3_CMD is specified, the given external
+ diff3 tool will be used instead of our built in diff3 routines.
When MERGE_OPTIONS are specified, they are used by the internal
diff3 routines, or passed to the external diff3 tool.
@@ -453,6 +453,7 @@ svn_wc__internal_merge(svn_skel_t **work
const char *target_label,
apr_hash_t *old_actual_props,
svn_boolean_t dry_run,
+ const char *invoke_diff3_cmd,
const char *diff3_cmd,
const apr_array_header_t *merge_options,
const apr_array_header_t *prop_diff,
@@ -461,6 +462,7 @@ svn_wc__internal_merge(svn_skel_t **work
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
+
/* A default error handler for svn_wc_walk_entries3(). Returns ERR in
all cases. */
svn_error_t *
@@ -730,6 +732,7 @@ svn_wc__perform_file_merge(svn_skel_t **
svn_revnum_t target_revision,
const apr_array_header_t *propchanges,
const char *diff3_cmd,
+ const char *invoke_diff3_cmd,
svn_cancel_func_t cancel_func,
void *cancel_baton,
apr_pool_t *result_pool,
Modified: subversion/branches/invoke-diff3-feature/subversion/libsvn_wc/wc_db_update_move.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff3-feature/subversion/libsvn_wc/wc_db_update_move.c?rev=1542514&r1=1542513&r2=1542514&view=diff
==============================================================================
--- subversion/branches/invoke-diff3-feature/subversion/libsvn_wc/wc_db_update_move.c (original)
+++ subversion/branches/invoke-diff3-feature/subversion/libsvn_wc/wc_db_update_move.c Sat Nov 16 14:36:46 2013
@@ -961,8 +961,9 @@ update_working_file(const char *local_re
NULL, NULL, NULL, /* diff labels */
actual_props,
FALSE, /* dry-run */
- NULL, /* diff3-cmd */
- NULL, /* merge options */
+ NULL, /* diff3-cmd */
+ NULL, /* invoke-diff3-cmd */
+ NULL, /* merge options */
propchanges,
NULL, NULL, /* cancel_func + baton */
scratch_pool, scratch_pool));
Modified: subversion/branches/invoke-diff3-feature/subversion/svn/cl.h
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff3-feature/subversion/svn/cl.h?rev=1542514&r1=1542513&r2=1542514&view=diff
==============================================================================
--- subversion/branches/invoke-diff3-feature/subversion/svn/cl.h (original)
+++ subversion/branches/invoke-diff3-feature/subversion/svn/cl.h Sat Nov 16 14:36:46 2013
@@ -83,7 +83,11 @@ typedef enum svn_cl__accept_t
svn_cl__accept_edit,
/* Launch user's resolver and resolve conflict with edited file. */
- svn_cl__accept_launch
+ svn_cl__accept_launch,
+
+ /* Launch user's resolver with the invoke_diff3_cmd in the config
+ file and resolve conflict with edited file. */
+ svn_cl__accept_invoke_diff3_config
} svn_cl__accept_t;
@@ -97,6 +101,7 @@ typedef enum svn_cl__accept_t
#define SVN_CL__ACCEPT_THEIRS_FULL "theirs-full"
#define SVN_CL__ACCEPT_EDIT "edit"
#define SVN_CL__ACCEPT_LAUNCH "launch"
+#define SVN_CL__ACCEPT_INVOKE_DIFF3_CONFIG "invoke-diff3-config"
/* Return the svn_cl__accept_t value corresponding to WORD, using exact
* case-sensitive string comparison. Return svn_cl__accept_invalid if WORD
@@ -204,6 +209,9 @@ typedef struct svn_cl__opt_state_t
svn_boolean_t revprop; /* operate on a revision property */
const char *merge_cmd; /* the external merge command to use
(not converted to UTF-8) */
+ const char *invoke_diff3_cmd; /* the format string for the external
+ merge command to use (not
+ converted to UTF-8) */
const char *editor_cmd; /* the external editor command to use
(not converted to UTF-8) */
svn_boolean_t record_only; /* whether to record mergeinfo */
@@ -531,6 +539,21 @@ svn_cl__merge_file_externally(const char
svn_boolean_t *remains_in_conflict,
apr_pool_t *pool);
+/* As svn_cl__merge_file_externally, but for the invoke_diff3_cmd
+ selected merge tool */
+svn_error_t *
+svn_cl__invoke_diff3_cmd_externally(const char *base_label,
+ const char *their_label,
+ const char *my_label,
+ const char *base_file,
+ const char *their_file,
+ const char *my_file,
+ apr_hash_t *config,
+ svn_boolean_t *remains_in_conflict,
+ const char *opt_code,
+ apr_pool_t *pool);
+
+
/* Like svn_cl__merge_file_externally, but using a built-in merge tool
* with help from an external editor specified by EDITOR_CMD. */
svn_error_t *
Modified: subversion/branches/invoke-diff3-feature/subversion/svn/conflict-callbacks.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff3-feature/subversion/svn/conflict-callbacks.c?rev=1542514&r1=1542513&r2=1542514&view=diff
==============================================================================
--- subversion/branches/invoke-diff3-feature/subversion/svn/conflict-callbacks.c (original)
+++ subversion/branches/invoke-diff3-feature/subversion/svn/conflict-callbacks.c Sat Nov 16 14:36:46 2013
@@ -118,6 +118,11 @@ svn_cl__accept_from_word(const char *wor
if (strcmp(word, SVN_CL__ACCEPT_LAUNCH) == 0
|| strcmp(word, "l") == 0 || strcmp(word, ":-l") == 0)
return svn_cl__accept_launch;
+ if (strcmp(word, SVN_CL__ACCEPT_INVOKE_DIFF3_CONFIG) == 0
+ /* FIX ME: Which smiley to select? */
+ || strcmp(word, "3f") == 0 || strcmp(word, ":-?") == 0)
+ return svn_cl__accept_launch;
+
/* word is an invalid action. */
return svn_cl__accept_invalid;
}
@@ -409,6 +414,37 @@ launch_resolver(svn_boolean_t *performed
return SVN_NO_ERROR;
}
+/* Run an external merge tool, passing it the 'base', 'their', 'my' and
+ * 'merged' files in DESC. The tool to use is determined by B->config and
+ * environment variables; see svn_cl__merge_file_externally() for details.
+ *
+ * If the tool runs, set *PERFORMED_EDIT to true; if a tool is not
+ * configured or cannot run, do not touch *PERFORMED_EDIT, report the error
+ * on stderr, and return SVN_NO_ERROR; if any other error is encountered,
+ * return that error. */
+static svn_error_t *
+invoke_diff3_resolver(svn_boolean_t *performed_edit,
+ const svn_wc_conflict_description2_t *desc,
+ svn_cl__interactive_conflict_baton_t *b,
+ const char *opt_code,
+ apr_pool_t *pool)
+{
+
+ SVN_ERR(svn_cl__invoke_diff3_cmd_externally("BASE",
+ "OLD",
+ "NEW",
+ desc->base_abspath,
+ desc->their_abspath,
+ desc->my_abspath,
+ b->config, NULL,
+ opt_code,
+ pool));
+ if (performed_edit)
+ *performed_edit = TRUE;
+
+ return SVN_NO_ERROR;
+}
+
/* Maximum line length for the prompt string. */
#define MAX_PROMPT_WIDTH 70
@@ -458,6 +494,15 @@ static const resolver_option_t text_conf
-1 },
{ "l", N_("launch tool"), N_("launch external tool to resolve "
"conflict [launch]"), -1 },
+ { "3f", N_("invoke-diff3-cmd given in config file"),
+ N_("use invoke-diff3 command defined in "
+ "the config file to resolve conflict "
+ "[invoke-diff3-config]"), -1 },
+
+ { "i", N_("interactive invoke-diff3-cmd selection"),
+ N_("interactively select tool now to "
+ "resolve conflict"), -1 },
+
{ "p", N_("postpone"), N_("mark the conflict to be resolved later"
" [postpone]"),
svn_wc_conflict_choose_postpone },
@@ -734,6 +779,8 @@ handle_text_conflict(svn_wc_conflict_res
*next_option++ = "df";
*next_option++ = "e";
*next_option++ = "m";
+ *next_option++ = "3f";
+ *next_option++ = "i";
if (knows_something)
*next_option++ = "r";
@@ -798,8 +845,8 @@ handle_text_conflict(svn_wc_conflict_res
if (! diff_allowed)
{
SVN_ERR(svn_cmdline_fprintf(stderr, iterpool,
- _("Invalid option; there's no "
- "merged version to diff.\n\n")));
+ _("Invalid option; there's no "
+ "merged version to diff.\n\n")));
continue;
}
@@ -887,8 +934,79 @@ handle_text_conflict(svn_wc_conflict_res
{
SVN_ERR(svn_cmdline_fprintf(stderr, iterpool, "%s\n",
err->message ? err->message :
- _("Error running merge tool, "
- "try '(m) merge' instead.")));
+ _("Error running merge tool, "
+ "try '(m) merge' instead.")));
+ svn_error_clear(err);
+ }
+ else if (err)
+ return svn_error_trace(err);
+
+ if (performed_edit)
+ knows_something = TRUE;
+ }
+ else
+ SVN_ERR(svn_cmdline_fprintf(stderr, iterpool,
+ _("Invalid option.\n\n")));
+ }
+ else if (strcmp(opt->code, "i") == 0)
+ { /* interactively get the invoke-diff3-cmd */
+
+ if (desc->base_abspath && desc->their_abspath &&
+ desc->my_abspath && desc->merged_file)
+ {
+ const char *answer;
+ svn_error_t *err;
+
+ SVN_ERR(svn_cmdline_prompt_user2(&answer,
+ "Enter the invoke-diff3-cmd: ",
+ b->pb, iterpool));
+ err = invoke_diff3_resolver(&performed_edit, desc, b, answer, iterpool);
+
+ if (err && err->apr_err == SVN_ERR_EXTERNAL_PROGRAM)
+ {
+ SVN_ERR(svn_cmdline_fprintf(stderr, iterpool, "%s\n",
+ err->message ? err->message :
+ _("Error executing the interactive, "
+ "invoke-diff3-cmd.\n")));
+ svn_error_clear(err);
+ }
+ else if (err)
+ return svn_error_trace(err);
+
+ if (performed_edit)
+ knows_something = TRUE;
+ }
+ else
+ SVN_ERR(svn_cmdline_fprintf(stderr, iterpool,
+ _("Invalid option.\n\n")));
+ }
+ else if (strcmp(opt->code, "3f") == 0)
+ {
+ if (desc->base_abspath && desc->their_abspath &&
+ desc->my_abspath && desc->merged_file)
+ {
+
+ svn_error_t *err;
+ /* ### This check should be earlier as it's nasty to offer an option
+ * and then when the user chooses it say 'Invalid option'. */
+ /* ### 'merged_file' shouldn't be necessary *before* we launch the
+ * resolver: it should be the *result* of doing so. */
+
+ err = invoke_diff3_resolver(&performed_edit, desc, b, opt->code, iterpool);
+ if (err && err->apr_err == SVN_ERR_CL_NO_EXTERNAL_DIFF3_TOOL)
+ {
+ SVN_ERR(svn_cmdline_fprintf(stderr, iterpool, "%s\n",
+ err->message ? err->message :
+ _("No invoke-diff3 tool found, "
+ "try '(m) merge' instead.\n")));
+ svn_error_clear(err);
+ }
+ else if (err && err->apr_err == SVN_ERR_EXTERNAL_PROGRAM)
+ {
+ SVN_ERR(svn_cmdline_fprintf(stderr, iterpool, "%s\n",
+ err->message ? err->message :
+ _("Error running invoke-diff3 tool, "
+ "try '(m) merge' instead.")));
svn_error_clear(err);
}
else if (err)
@@ -921,9 +1039,9 @@ handle_text_conflict(svn_wc_conflict_res
&& ! knows_something)
{
SVN_ERR(svn_cmdline_fprintf(
- stderr, iterpool,
- _("Invalid option; use diff/edit/merge/launch "
- "before choosing 'mark resolved'.\n\n")));
+ stderr, iterpool,
+ _("Invalid option; use diff/edit/merge/launch "
+ "before choosing 'mark resolved'.\n\n")));
continue;
}
@@ -1294,6 +1412,57 @@ conflict_func_interactive(svn_wc_conflic
}
/* else, fall through to prompting. */
break;
+ case svn_cl__accept_invoke_diff3_config:
+ if (desc->base_abspath && desc->their_abspath
+ && desc->my_abspath && desc->merged_file)
+ {
+ svn_boolean_t remains_in_conflict;
+
+ if (b->external_failed)
+ {
+ (*result)->choice = svn_wc_conflict_choose_postpone;
+ return SVN_NO_ERROR;
+ }
+ err = svn_cl__invoke_diff3_cmd_externally("BASE",
+ "NEW",
+ "OLD",
+ desc->base_abspath,
+ desc->their_abspath,
+ desc->my_abspath,
+ b->config,
+ &remains_in_conflict,
+ "3f",
+ scratch_pool);
+ if (err && err->apr_err == SVN_ERR_CL_NO_EXTERNAL_MERGE_TOOL)
+ {
+ SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "%s\n",
+ err->message ? err->message :
+ _("No invoke-diff3-cmd tool found;"
+ " leaving all conflicts.")));
+ b->external_failed = TRUE;
+ return svn_error_trace(err);
+ }
+ else if (err && err->apr_err == SVN_ERR_EXTERNAL_PROGRAM)
+ {
+ SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "%s\n",
+ err->message ? err->message :
+ _("Error running invoke-diff3-cmd tool;"
+ " leaving all conflicts.")));
+ b->external_failed = TRUE;
+ return svn_error_trace(err);
+ }
+ else if (err)
+ return svn_error_trace(err);
+
+ if (remains_in_conflict)
+ (*result)->choice = svn_wc_conflict_choose_postpone;
+ else
+ (*result)->choice = svn_wc_conflict_choose_merged;
+ return SVN_NO_ERROR;
+ }
+ /* else, fall through to prompting. */
+ break;
+
}
/* Print a summary of conflicts before starting interactive resolution */
Modified: subversion/branches/invoke-diff3-feature/subversion/svn/svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff3-feature/subversion/svn/svn.c?rev=1542514&r1=1542513&r2=1542514&view=diff
==============================================================================
--- subversion/branches/invoke-diff3-feature/subversion/svn/svn.c (original)
+++ subversion/branches/invoke-diff3-feature/subversion/svn/svn.c Sat Nov 16 14:36:46 2013
@@ -95,6 +95,7 @@ typedef enum svn_cl__longopt_t {
opt_ignore_externals,
opt_incremental,
opt_merge_cmd,
+ opt_invoke_diff3_cmd,
opt_native_eol,
opt_new_cmd,
opt_no_auth_cache,
@@ -250,6 +251,24 @@ const apr_getopt_option_t svn_cl__option
{"ignore-externals", opt_ignore_externals, 0,
N_("ignore externals definitions")},
{"diff3-cmd", opt_merge_cmd, 1, N_("use ARG as merge command")},
+ {"invoke-diff3-cmd", opt_invoke_diff3_cmd, 1,
+ N_("use ARG as format string for external merge program\n"
+ " "
+ "invocation. Substitutions: \n"
+ " "
+ " %svn_mine 'mine' file\n"
+ " "
+ " %svn_yours 'yours' file\n"
+ " "
+ " %svn_base 'base' file\n"
+ " "
+ " %svn_label_mine label of the 'mine file\n"
+ " "
+ " %svn_label_yours label of the 'yours' file\n"
+ " "
+ " %svn_label_base label of the 'mine file\n"
+ " "
+ "See 'help diff' for example usage.")},
{"editor-cmd", opt_editor_cmd, 1, N_("use ARG as external editor")},
{"record-only", opt_record_only, 0,
N_("merge only mergeinfo differences")},
@@ -546,8 +565,8 @@ const svn_opt_subcommand_desc2_t svn_cl_
" for writing by another Subversion client.\n"
" Note that the 'svn status' command shows unversioned items as '?',\n"
" and ignored items as 'I' if the --no-ignore option is given to it.\n"),
- {opt_merge_cmd, opt_remove_unversioned, opt_remove_ignored,
- opt_include_externals, 'q'} },
+ {opt_merge_cmd, opt_invoke_diff3_cmd, opt_remove_unversioned,
+ opt_remove_ignored, opt_include_externals, 'q'} },
{ "commit", svn_cl__commit, {"ci"},
N_("Send changes from your working copy to the repository.\n"
@@ -1140,8 +1159,8 @@ const svn_opt_subcommand_desc2_t svn_cl_
" target. Also, merge-tracking is not supported for merges from foreign\n"
" repositories.\n"),
{'r', 'c', 'N', opt_depth, 'q', opt_force, opt_dry_run, opt_merge_cmd,
- opt_record_only, 'x', opt_ignore_ancestry, opt_accept, opt_reintegrate,
- opt_allow_mixed_revisions, 'v'} },
+ opt_invoke_diff3_cmd, opt_record_only, 'x', opt_ignore_ancestry,
+ opt_accept, opt_reintegrate, opt_allow_mixed_revisions, 'v'} },
{ "mergeinfo", svn_cl__mergeinfo, {0}, N_
("Display merge-related information.\n"
@@ -1604,8 +1623,9 @@ const svn_opt_subcommand_desc2_t svn_cl_
" svn switch --relocate http:// svn://\n"
" svn switch --relocate http://www.example.com/repo/project \\\n"
" svn://svn.example.com/repo/project\n"),
- { 'r', 'N', opt_depth, opt_set_depth, 'q', opt_merge_cmd, opt_relocate,
- opt_ignore_externals, opt_ignore_ancestry, opt_force, opt_accept},
+ { 'r', 'N', opt_depth, opt_set_depth, 'q', opt_merge_cmd,
+ opt_invoke_diff3_cmd, opt_relocate, opt_ignore_externals,
+ opt_ignore_ancestry, opt_force, opt_accept},
{{opt_ignore_ancestry,
N_("allow switching to a node with no common ancestor")}}
},
@@ -1663,9 +1683,9 @@ const svn_opt_subcommand_desc2_t svn_cl_
"\n"
" Use the --set-depth option to set a new working copy depth on the\n"
" targets of this operation.\n"),
- {'r', 'N', opt_depth, opt_set_depth, 'q', opt_merge_cmd, opt_force,
- opt_ignore_externals, opt_changelist, opt_editor_cmd, opt_accept,
- opt_parents} },
+ {'r', 'N', opt_depth, opt_set_depth, 'q', opt_merge_cmd,
+ opt_invoke_diff3_cmd, opt_force, opt_ignore_externals, opt_changelist,
+ opt_editor_cmd, opt_accept, opt_parents} },
{ "upgrade", svn_cl__upgrade, {0}, N_
("Upgrade the metadata storage format for a working copy.\n"
@@ -2174,6 +2194,9 @@ sub_main(int argc, const char *argv[], a
case opt_merge_cmd:
opt_state.merge_cmd = apr_pstrdup(pool, opt_arg);
break;
+ case opt_invoke_diff3_cmd:
+ opt_state.invoke_diff3_cmd = apr_pstrdup(pool, opt_arg);
+ break;
case opt_record_only:
opt_state.record_only = TRUE;
break;
@@ -2611,6 +2634,16 @@ sub_main(int argc, const char *argv[], a
return EXIT_ERROR(err);
}
+ /* Check for mutually exclusive args --diff3-cmd and
+ --invoke-diff3-cmd */
+ if (opt_state.merge_cmd && opt_state.invoke_diff3_cmd)
+ {
+ err = svn_error_create(SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
+ _("--diff3-cmd and --invoke-diff3-cmd are "
+ "mutually exclusive"));
+ return EXIT_ERROR(err);
+ }
+
/* Ensure that 'revision_ranges' has at least one item, and make
'start_revision' and 'end_revision' match that item. */
if (opt_state.revision_ranges->nelts == 0)
@@ -2830,8 +2863,15 @@ sub_main(int argc, const char *argv[], a
svn_config_set(cfg_config, SVN_CONFIG_SECTION_HELPERS,
SVN_CONFIG_OPTION_INVOKE_DIFF_CMD, opt_state.diff.invoke_diff_cmd);
if (opt_state.merge_cmd)
- svn_config_set(cfg_config, SVN_CONFIG_SECTION_HELPERS,
- SVN_CONFIG_OPTION_DIFF3_CMD, opt_state.merge_cmd);
+ {
+ svn_config_set(cfg_config, SVN_CONFIG_SECTION_HELPERS,
+ SVN_CONFIG_OPTION_DIFF3_CMD, opt_state.merge_cmd);
+ }
+ if (opt_state.invoke_diff3_cmd)
+ {
+ svn_config_set(cfg_config, SVN_CONFIG_SECTION_HELPERS,
+ SVN_CONFIG_OPTION_INVOKE_DIFF3_CMD, opt_state.invoke_diff3_cmd);
+ }
if (opt_state.diff.internal_diff)
svn_config_set(cfg_config, SVN_CONFIG_SECTION_HELPERS,
SVN_CONFIG_OPTION_DIFF_CMD, NULL);
@@ -2955,6 +2995,12 @@ sub_main(int argc, const char *argv[], a
_("--accept=%s incompatible with"
" --non-interactive"),
SVN_CL__ACCEPT_LAUNCH));
+ if (opt_state.accept_which == svn_cl__accept_invoke_diff3_config)
+ return EXIT_ERROR(
+ svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("--accept=%s incompatible with"
+ " --non-interactive"),
+ SVN_CL__ACCEPT_LAUNCH));
/* The default action when we're non-interactive is to postpone
* conflict resolution. */
Modified: subversion/branches/invoke-diff3-feature/subversion/svn/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff3-feature/subversion/svn/util.c?rev=1542514&r1=1542513&r2=1542514&view=diff
==============================================================================
--- subversion/branches/invoke-diff3-feature/subversion/svn/util.c (original)
+++ subversion/branches/invoke-diff3-feature/subversion/svn/util.c Sat Nov 16 14:36:46 2013
@@ -66,6 +66,7 @@
#include "private/svn_client_private.h"
#include "private/svn_cmdline_private.h"
#include "private/svn_string_private.h"
+#include "private/svn_io_private.h"
@@ -173,6 +174,104 @@ svn_cl__merge_file_externally(const char
return SVN_NO_ERROR;
}
+svn_error_t *
+svn_cl__invoke_diff3_cmd_externally(const char *base_label,
+ const char *their_label,
+ const char *my_label,
+ const char *base_file,
+ const char *their_file,
+ const char *my_file,
+ apr_hash_t *config,
+ svn_boolean_t *remains_in_conflict,
+ const char *opt_code,
+ apr_pool_t *pool)
+{
+ char *invoke_diff3_cmd;
+ const char ** cmd;
+ apr_pool_t *scratch_pool = svn_pool_create(pool);
+ char *cwd;
+ int exitcode;
+ apr_status_t status = apr_filepath_get(&cwd, APR_FILEPATH_NATIVE, pool);
+
+ if (status != 0)
+ return svn_error_wrap_apr(status, NULL);
+
+ if (0 == strcmp(opt_code,"3f")) /* command in config file */
+ {
+
+ if (apr_env_get(&invoke_diff3_cmd, "SVN_INVOKE_DIFF3_CMD", pool) != APR_SUCCESS)
+ {
+ struct svn_config_t *cfg;
+ invoke_diff3_cmd = NULL;
+ cfg = config ? svn_hash_gets(config, SVN_CONFIG_CATEGORY_CONFIG) : NULL;
+ /* apr_env_get wants char **, this wants const char ** */
+ svn_config_get(cfg, (const char **)&invoke_diff3_cmd,
+ SVN_CONFIG_SECTION_HELPERS,
+ SVN_CONFIG_OPTION_INVOKE_DIFF3_CMD, NULL);
+ }
+
+ if (invoke_diff3_cmd)
+ {
+ const char *c;
+ for (c = invoke_diff3_cmd; *c; c++)
+ if (!svn_ctype_isspace(*c))
+ break;
+
+ if (! *c)
+ return svn_error_create
+ (SVN_ERR_CL_NO_EXTERNAL_DIFF3_TOOL, NULL,
+ _("The SVN_INVOKE_DIFF3_TOOL environment variable is empty or "
+ "consists solely of whitespace. Expected a shell command.\n"));
+ }
+ else
+ return svn_error_create
+ (SVN_ERR_CL_NO_EXTERNAL_MERGE_TOOL, NULL,
+ _("The environment variable SVN_INVOKE_DIFF3_TOOL and the invoke-diff3-cmd run-time "
+ "configuration option were not set.\n"));
+ }
+ else
+ {
+ invoke_diff3_cmd = apr_pstrdup(pool, opt_code);
+ }
+
+
+ if (0 == strlen(invoke_diff3_cmd))
+ return svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL, NULL);
+
+ cmd = svn_io__create_custom_diff_cmd(my_label, their_label, base_label,
+ my_file, their_file, base_file,
+ invoke_diff3_cmd, scratch_pool);
+
+ SVN_ERR(svn_io_run_cmd(svn_dirent_internal_style(cwd, pool),
+ cmd[0], cmd, &exitcode, NULL, TRUE,
+ NULL, NULL, NULL, scratch_pool));
+
+ /* According to the diff3 docs, a '0' means the merge was clean, and
+ '1' means conflict markers were found. Anything else is real
+ error. */
+ if ((exitcode != 0) && (exitcode != 1))
+ {
+
+ int i;
+ const char *failed_command = "";
+
+ for (i = 0; cmd[i]; ++i)
+ failed_command = apr_pstrcat(pool, failed_command,
+ cmd[i], " ", (char*) NULL);
+ svn_pool_destroy(scratch_pool);
+ return svn_error_createf(SVN_ERR_EXTERNAL_PROGRAM, NULL,
+ _("'%s' was expanded to '%s' and returned %d"),
+ invoke_diff3_cmd,
+ failed_command,
+ exitcode);
+ }
+ else if (remains_in_conflict)
+ *remains_in_conflict = exitcode == 1;
+ svn_pool_destroy(scratch_pool);
+
+ return SVN_NO_ERROR;
+}
+
/* A svn_client_ctx_t's log_msg_baton3, for use with
svn_cl__make_log_msg_baton(). */
Modified: subversion/branches/invoke-diff3-feature/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff3-feature/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout?rev=1542514&r1=1542513&r2=1542514&view=diff
==============================================================================
--- subversion/branches/invoke-diff3-feature/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout (original)
+++ subversion/branches/invoke-diff3-feature/subversion/tests/cmdline/getopt_tests_data/svn_help_log_switch_stdout Sat Nov 16 14:36:46 2013
@@ -201,6 +201,15 @@ Valid options:
'empty', 'files', 'immediates', or 'infinity')
-q [--quiet] : print nothing, or only summary information
--diff3-cmd ARG : use ARG as merge command
+ --invoke-diff3-cmd ARG : use ARG as format string for external merge program
+ invocation. Substitutions:
+ %svn_mine 'mine' file
+ %svn_yours 'yours' file
+ %svn_base 'base' file
+ %svn_label_mine label of the 'mine file
+ %svn_label_yours label of the 'yours' file
+ %svn_label_base label of the 'mine file
+ See 'help diff' for example usage.
--relocate : relocate via URL-rewriting
--ignore-externals : ignore externals definitions
--ignore-ancestry : allow switching to a node with no common ancestor