The patch below allows the merge tool to abort the "svn merge" operation
by returning an exit code of 2. This is needed for automated merges, in
cases where the merge tool needs to signal to the calling merge script
that the scope of the automated merge needs to be reduced.
Index: subversion/svn/util.c
===================================================================
--- subversion/svn/util.c (revision 34905)
+++ subversion/svn/util.c (working copy)
@@ -241,12 +241,21 @@
const char *arguments[] = { merge_tool, base_path, their_path,
my_path, merged_path, NULL};
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);
- return svn_io_run_cmd(svn_path_internal_style(cwd, pool), merge_tool,
- arguments, NULL, NULL, TRUE, NULL, NULL, NULL,
+ svn_error_t *err = svn_io_run_cmd(svn_path_internal_style(cwd,
pool), merge_tool,
+ arguments, &exitcode, NULL, TRUE, NULL, NULL,
NULL,
pool);
+ if (err)
+ return err;
+ if (exitcode == 2)
+ return svn_error_create(SVN_ERR_CL_EXTERNAL_MERGE_TOOL_ABORTED, NULL,
+ _("The external merge tool aborted the
merge"));
+ return svn_error_createf
+ (SVN_ERR_EXTERNAL_PROGRAM, NULL,
+ _("The external merge tool returned error exitcode %d"), exitcode);
}
}
Index: subversion/include/svn_error_codes.h
===================================================================
--- subversion/include/svn_error_codes.h (revision 34905)
+++ subversion/include/svn_error_codes.h (working copy)
@@ -1275,6 +1275,11 @@
SVN_ERR_CL_CATEGORY_START + 10,
"No external merge tool available")
+ /** @since New in 1.6. */
+ SVN_ERRDEF(SVN_ERR_CL_EXTERNAL_MERGE_TOOL_ABORTED,
+ SVN_ERR_CL_CATEGORY_START + 11,
+ "The external merge tool aborted the merge")
+
/* malfunctions such as assertion failures */
SVN_ERRDEF(SVN_ERR_ASSERTION_FAIL,
For context, the following is the message I sent to
users_at_subversion.tigris.org on Nov. 21:
With Subversion 1.5.4, I'm trying to write a script for automated merges
between branches and am finding the merge-tool-cmd interface a bit lacking.
This script is intended to run out of cron. What I want the script to
do is:
* Merge from a specified source branch to a specified destination
branch, using the merge tracking info. If no conflicts, go ahead an
commit.
* If the conflict is in a certain defined set of files (such as contain
build numbers, etc.), automatically pick the "mine" file.
* If there is a conflict outside of that set of files, remember the
changeset that caused the conflict and abort the merge attempt. If
there are any eligible changesets before the changeset that caused the
conflict, repeat the merge attempt for eligible changesets up to but not
including the changeset that caused the conflict. Keep repeating until
a successful merge (which would be committed) or the script finds the
first eligible changeset causes a conflict.
* If there was a changeset that caused a conflict, email the author of
that changeset asking them to merge their change (possibly with
--record-only). After the author does this, the script would continue
on from there the next time it is run.
I appear to have run into three issues:
1) The merge-tool-cmd script does not appear to be provided with the
repository path of the file being merged.
2) The merge-tool-cmd script does not appear to be provided with the
name of the source revision it is trying to merge in. It might be able
to figure this out by scanning the file in the fourth argument for a
line with ">>>>>>> .merge-right.r", but I'm not sure such a line is
guaranteed to exist in all cases.
3) When the merge-tool-cmd script returns an exit code of 1 or 2, this
does not appear to stop the merge.
I think I'm going to be reduced to copying the merge-cmd.c code and
directly hacking on that, but I though I'd check first.
For background, I'll describe the branching model this is intended to
support. I think a good name for this model is "cascading release
branches."
Each release has its own release branch. There is no trunk. On a
regular basis, automated merges are run from earlier release branches to
later release branches. Developers check their changes into the branch
of the release for which each change is intended.
When a release nears completion, we use commit scripts and the flags
feature of Bugzilla to restrict the bugs for which commits are allowed
into that release's branch. At some point, automated merges going into
that branch are changed to instead go into the branch for a later release.
When development starts on a new version of the product, we create a
release branch for that version, branching off of its previous release
branch.
This branching model has the advantage that developers usually only have
to check into one branch. Less developer time is wasted merging changes
around. Furthermore, with the --use-merge-history switch, it is easier
to research in which release a particular change first appeared.
------------------------------------------------------
http://subversion.tigris.org/ds/viewMessage.do?dsForumId=462&dsMessageId=991136
Received on 2008-12-24 10:47:38 CET