Author: julianfoad
Date: Fri Nov 18 11:07:28 2011
New Revision: 1203597
URL: http://svn.apache.org/viewvc?rev=1203597&view=rev
Log:
On the 'showing-merge-info' branch: Split up the reintegrate merge so the
client can find out what the equivalent two-URL merge will be, optionally
tell the user about that, and then perform that merge. Also don't print any
informative messages during the merge if the 'quiet' option was supplied.
* subversion/include/private/svn_client_private.h
(svn_client_find_reintegrate_merge, svn_client_do_reintegrate_merge): New
functions.
* subversion/libsvn_client/merge.c
(find_reintegrate_merge, do_reintegrate_merge): New functions, broken out
(merge_reintegrate_locked): ... of here.
(svn_client_find_reintegrate_merge, svn_client_do_reintegrate_merge): New
functions.
* subversion/svn/merge-cmd.c
(get_target_and_lock_abspath, merge_reintegrate_locked, merge_reintegrate):
New functions.
(svn_cl__merge): Use the new functions for a reintegrate merge. Don't
print messages if 'opt_state->quiet' is true.
Modified:
subversion/branches/showing-merge-info/subversion/include/private/svn_client_private.h
subversion/branches/showing-merge-info/subversion/libsvn_client/merge.c
subversion/branches/showing-merge-info/subversion/svn/merge-cmd.c
Modified:
subversion/branches/showing-merge-info/subversion/include/private/svn_client_private.h
URL:
http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/include/private/svn_client_private.h?rev=1203597&r1=1203596&r2=1203597&view=diff
==============================================================================
---
subversion/branches/showing-merge-info/subversion/include/private/svn_client_private.h
(original)
+++
subversion/branches/showing-merge-info/subversion/include/private/svn_client_private.h
Fri Nov 18 11:07:28 2011
@@ -128,6 +128,38 @@ svn_client__get_location_segments(apr_ar
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
+/* */
+svn_error_t *
+svn_client_find_reintegrate_merge(svn_ra_session_t **source_ra_session_p,
+ svn_ra_session_t **target_ra_session_p,
+ const char **url1_p,
+ svn_revnum_t *rev1_p,
+ const char **url2_p,
+ svn_revnum_t *rev2_p,
+ svn_revnum_t *yc_ancestor_rev_p,
+ /* inputs */
+ const char *source,
+ const svn_opt_revision_t *peg_revision,
+ const char *target_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+/* */
+svn_error_t *
+svn_client_do_reintegrate_merge(svn_ra_session_t *source_ra_session,
+ svn_ra_session_t *target_ra_session,
+ const char *url1,
+ svn_revnum_t rev1,
+ const char *url2,
+ svn_revnum_t rev2,
+ svn_revnum_t yc_ancestor_rev,
+ const char *target_wcpath,
+ svn_boolean_t dry_run,
+ const apr_array_header_t *merge_options,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool);
+
#ifdef __cplusplus
}
Modified:
subversion/branches/showing-merge-info/subversion/libsvn_client/merge.c
URL:
http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_client/merge.c?rev=1203597&r1=1203596&r2=1203597&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_client/merge.c
(original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_client/merge.c Fri
Nov 18 11:07:28 2011
@@ -57,6 +57,7 @@
#include "private/svn_mergeinfo_private.h"
#include "private/svn_fspath.h"
#include "private/svn_ra_private.h"
+#include "private/svn_client_private.h"
#include "svn_private_config.h"
@@ -10407,14 +10408,22 @@ calculate_left_hand_side(const char **ur
return SVN_NO_ERROR;
}
+/* */
static svn_error_t *
-merge_reintegrate_locked(const char *source,
- const svn_opt_revision_t *peg_revision,
- const char *target_abspath,
- svn_boolean_t dry_run,
- const apr_array_header_t *merge_options,
- svn_client_ctx_t *ctx,
- apr_pool_t *scratch_pool)
+find_reintegrate_merge(svn_ra_session_t **source_ra_session_p,
+ svn_ra_session_t **target_ra_session_p,
+ const char **url1_p,
+ svn_revnum_t *rev1_p,
+ const char **url2_p,
+ svn_revnum_t *rev2_p,
+ svn_revnum_t *yc_ancestor_rev_p,
+ /* inputs */
+ const char *source,
+ const svn_opt_revision_t *peg_revision,
+ const char *target_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
url_uuid_t wc_repos_root, source_repos_root;
svn_opt_revision_t working_revision = { svn_opt_revision_working, { 0 } };
@@ -10427,8 +10436,6 @@ merge_reintegrate_locked(const char *sou
svn_revnum_t rev1, rev2;
svn_mergeinfo_t unmerged_to_source_mergeinfo_catalog;
svn_mergeinfo_t merged_to_source_mergeinfo_catalog;
- svn_boolean_t use_sleep = FALSE;
- svn_error_t *err;
apr_hash_t *subtrees_with_mergeinfo;
const char *target_url;
svn_revnum_t target_base_rev;
@@ -10453,12 +10460,12 @@ merge_reintegrate_locked(const char *sou
/* Determine the working copy target's repository root URL. */
SVN_ERR(svn_client_get_repos_root(&wc_repos_root.url, &wc_repos_root.uuid,
target_abspath,
- ctx, scratch_pool, scratch_pool));
+ ctx, result_pool, scratch_pool));
/* Determine the source's repository root URL. */
SVN_ERR(svn_client_get_repos_root(&source_repos_root.url,
&source_repos_root.uuid, url2,
- ctx, scratch_pool, scratch_pool));
+ ctx, result_pool, scratch_pool));
/* source_repos_root and wc_repos_root are required to be the same,
as mergeinfo doesn't come into play for cross-repository merging. */
@@ -10506,13 +10513,13 @@ merge_reintegrate_locked(const char *sou
SVN_ERR(svn_client__ra_session_from_path(&source_ra_session, &rev2, &url2,
url2, NULL, peg_revision,
peg_revision,
- ctx, scratch_pool));
+ ctx, result_pool));
SVN_ERR(svn_wc__node_get_url(&target_url, ctx->wc_ctx, target_abspath,
scratch_pool, scratch_pool));
SVN_ERR(svn_client__open_ra_session_internal(&target_ra_session, NULL,
target_url,
NULL, NULL, FALSE, FALSE,
- ctx, scratch_pool));
+ ctx, result_pool));
SVN_ERR(calculate_left_hand_side(&url1, &rev1,
&merged_to_source_mergeinfo_catalog,
@@ -10527,7 +10534,7 @@ merge_reintegrate_locked(const char *sou
source_ra_session,
target_ra_session,
ctx,
- scratch_pool, scratch_pool));
+ result_pool, scratch_pool));
/* Did calculate_left_hand_side() decide that there was no merge to
be performed here? */
@@ -10589,12 +10596,76 @@ merge_reintegrate_locked(const char *sou
/* Left side: trunk@youngest-trunk-rev-merged-to-branch-at-specified-peg-rev
* Right side: branch@specified-peg-revision */
- {
- printf(_("The reintegrate merge will be equivalent to:\n"
- " merge ^/%s@%ld ^/%s@%ld\n"),
- svn_uri_skip_ancestor(source_repos_root.url, url1, scratch_pool),
rev1,
- svn_uri_skip_ancestor(source_repos_root.url, url2, scratch_pool),
rev2);
- }
+ *source_ra_session_p = source_ra_session;
+ *target_ra_session_p = target_ra_session;
+ *url1_p = url1;
+ *rev1_p = rev1;
+ *url2_p = url2;
+ *rev2_p = rev2;
+ *yc_ancestor_rev_p = yc_ancestor_rev;
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client_find_reintegrate_merge(svn_ra_session_t **source_ra_session_p,
+ svn_ra_session_t **target_ra_session_p,
+ const char **url1_p,
+ svn_revnum_t *rev1_p,
+ const char **url2_p,
+ svn_revnum_t *rev2_p,
+ svn_revnum_t *yc_ancestor_rev_p,
+ /* inputs */
+ const char *source,
+ const svn_opt_revision_t *peg_revision,
+ const char *target_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ /* ### We don't need to write to the WC at this stage. We want to
+ * read a consistent state, and afterwards the caller will want
+ * svn_client_do_reintegrate_merge() to write into the same state,
+ * so maybe the caller should take out a write lock around both calls,
+ * and we should not take out a lock here. Maybe we should have a way
+ * to request a "read lock" that allows reading only. */
+ SVN_ERR(find_reintegrate_merge(
+ source_ra_session_p, target_ra_session_p,
+ url1_p, rev1_p, url2_p, rev2_p,
+ yc_ancestor_rev_p,
+ source, peg_revision, target_abspath,
+ ctx, result_pool, scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+/* */
+static svn_error_t *
+do_reintegrate_merge(svn_ra_session_t *source_ra_session,
+ svn_ra_session_t *target_ra_session,
+ const char *url1,
+ svn_revnum_t rev1,
+ const char *url2,
+ svn_revnum_t rev2,
+ svn_revnum_t yc_ancestor_rev,
+ const char *target_abspath,
+ svn_boolean_t dry_run,
+ const apr_array_header_t *merge_options,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ url_uuid_t source_repos_root, wc_repos_root;
+ svn_boolean_t use_sleep = FALSE;
+ svn_error_t *err;
+
+ /* Determine the working copy target's repository root URL. */
+ SVN_ERR(svn_client_get_repos_root(&wc_repos_root.url, &wc_repos_root.uuid,
+ target_abspath,
+ ctx, scratch_pool, scratch_pool));
+
+ /* Determine the source's repository root URL. */
+ SVN_ERR(svn_client_get_repos_root(&source_repos_root.url,
+ &source_repos_root.uuid, url2,
+ ctx, scratch_pool, scratch_pool));
/* Do the real merge! */
/* ### TODO(reint): Make sure that one isn't the same line ancestor
@@ -10623,6 +10694,59 @@ merge_reintegrate_locked(const char *sou
}
svn_error_t *
+svn_client_do_reintegrate_merge(svn_ra_session_t *source_ra_session,
+ svn_ra_session_t *target_ra_session,
+ const char *url1,
+ svn_revnum_t rev1,
+ const char *url2,
+ svn_revnum_t rev2,
+ svn_revnum_t yc_ancestor_rev,
+ const char *target_wc_abspath,
+ svn_boolean_t dry_run,
+ const apr_array_header_t *merge_options,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ SVN_ERR(do_reintegrate_merge(
+ source_ra_session, target_ra_session,
+ url1, rev1, url2, rev2, yc_ancestor_rev,
+ target_wc_abspath, dry_run, merge_options,
+ ctx, scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+/* */
+static svn_error_t *
+merge_reintegrate_locked(const char *source,
+ const svn_opt_revision_t *peg_revision,
+ const char *target_abspath,
+ svn_boolean_t dry_run,
+ const apr_array_header_t *merge_options,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ svn_ra_session_t *source_ra_session;
+ svn_ra_session_t *target_ra_session;
+ const char *url1, *url2;
+ svn_revnum_t rev1, rev2;
+ svn_revnum_t yc_ancestor_rev;
+
+ SVN_ERR(find_reintegrate_merge(
+ &source_ra_session, &target_ra_session,
+ &url1, &rev1, &url2, &rev2, &yc_ancestor_rev,
+ source, peg_revision, target_abspath,
+ ctx, scratch_pool, scratch_pool));
+
+ SVN_ERR(do_reintegrate_merge(
+ source_ra_session, target_ra_session,
+ url1, rev1, url2, rev2, yc_ancestor_rev,
+ target_abspath,
+ dry_run, merge_options, ctx, scratch_pool));
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
svn_client_merge_reintegrate(const char *source,
const svn_opt_revision_t *peg_revision,
const char *target_wcpath,
Modified: subversion/branches/showing-merge-info/subversion/svn/merge-cmd.c
URL:
http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/svn/merge-cmd.c?rev=1203597&r1=1203596&r2=1203597&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/svn/merge-cmd.c (original)
+++ subversion/branches/showing-merge-info/subversion/svn/merge-cmd.c Fri Nov
18 11:07:28 2011
@@ -34,6 +34,8 @@
#include "svn_types.h"
#include "cl.h"
+#include "private/svn_client_private.h"
+#include "private/svn_wc_private.h"
#include "svn_private_config.h"
@@ -70,6 +72,101 @@ get_repos_relpath(const char **repos_rel
return SVN_NO_ERROR;
}
+/* Set *TARGET_ABSPATH to the absolute path of, and *LOCK_ABSPATH to
+ the absolute path to lock for, TARGET_WCPATH. */
+static svn_error_t *
+get_target_and_lock_abspath(const char **target_abspath,
+ const char **lock_abspath,
+ const char *target_wcpath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ svn_node_kind_t kind;
+ SVN_ERR(svn_dirent_get_absolute(target_abspath, target_wcpath,
+ scratch_pool));
+ SVN_ERR(svn_wc_read_kind(&kind, ctx->wc_ctx, *target_abspath, FALSE,
+ scratch_pool));
+ if (kind == svn_node_dir)
+ *lock_abspath = *target_abspath;
+ else
+ *lock_abspath = svn_dirent_dirname(*target_abspath, scratch_pool);
+
+ return SVN_NO_ERROR;
+}
+
+/* */
+static svn_error_t *
+merge_reintegrate_locked(const char *source,
+ const svn_opt_revision_t *peg_revision,
+ const char *target_wc_abspath,
+ svn_boolean_t dry_run,
+ svn_boolean_t quiet,
+ const apr_array_header_t *merge_options,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *scratch_pool)
+{
+ svn_ra_session_t *source_ra_session;
+ svn_ra_session_t *target_ra_session;
+ const char *url1, *url2;
+ svn_revnum_t rev1, rev2;
+ svn_revnum_t yc_ancestor_rev;
+
+ SVN_ERR(svn_client_find_reintegrate_merge(
+ &source_ra_session, &target_ra_session,
+ &url1, &rev1, &url2, &rev2, &yc_ancestor_rev,
+ source, peg_revision, target_wc_abspath,
+ ctx, scratch_pool, scratch_pool));
+
+ {
+ const char *repos_root_url, *relpath1, *relpath2;
+
+ SVN_ERR(svn_client_get_repos_root(&repos_root_url, NULL, source,
+ ctx, scratch_pool, scratch_pool));
+ relpath1 = svn_uri_skip_ancestor(repos_root_url, url1, scratch_pool);
+ relpath2 = svn_uri_skip_ancestor(repos_root_url, url2, scratch_pool);
+
+ if (! quiet)
+ printf(_("The reintegrate merge will be equivalent to:\n"
+ " svn merge ^/%s@%ld ^/%s@%ld\n"),
+ relpath1, rev1, relpath2, rev2);
+ }
+
+ SVN_ERR(svn_client_do_reintegrate_merge(
+ source_ra_session, target_ra_session,
+ url1, rev1, url2, rev2, yc_ancestor_rev,
+ target_wc_abspath,
+ dry_run, merge_options, ctx, scratch_pool));
+ return SVN_NO_ERROR;
+}
+
+/* */
+static svn_error_t *
+merge_reintegrate(const char *source,
+ const svn_opt_revision_t *peg_revision,
+ const char *target_wcpath,
+ svn_boolean_t dry_run,
+ svn_boolean_t quiet,
+ const apr_array_header_t *merge_options,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool)
+{
+ const char *target_wc_abspath, *lock_abspath;
+
+ SVN_ERR(get_target_and_lock_abspath(&target_wc_abspath, &lock_abspath,
+ target_wcpath, ctx, pool));
+
+ if (!dry_run)
+ SVN_WC__CALL_WITH_WRITE_LOCK(
+ merge_reintegrate_locked(source, peg_revision, target_wc_abspath,
+ dry_run, quiet, merge_options, ctx, pool),
+ ctx->wc_ctx, lock_abspath, FALSE /* lock_anchor */, pool);
+ else
+ SVN_ERR(merge_reintegrate_locked(source, peg_revision, target_wc_abspath,
+ dry_run, quiet, merge_options, ctx,
pool));
+
+ return SVN_NO_ERROR;
+}
+
/* This implements the `svn_opt_subcommand_t' interface. */
svn_error_t *
svn_cl__merge(apr_getopt_t *os,
@@ -152,8 +249,9 @@ svn_cl__merge(apr_getopt_t *os,
SVN_ERR(svn_client_peg_create(&target_peg, "", NULL, pool));
SVN_ERR(svn_cl__find_merge_source_branch(&source_peg, target_peg, ctx,
pool));
/*SVN_ERR(svn_client__resolve_target_location_from_peg(&source,
source_peg, NULL, ctx, pool));*/
- printf("Assuming source branch is copy-source of target branch: '%s'\n",
- svn_cl__peg_for_display(source_peg, pool));
+ if (! opt_state->quiet)
+ printf(_("Assuming source branch is copy-source of target branch:
'%s'\n"),
+ svn_cl__peg_for_display(source_peg, pool));
peg_revision1 = source_peg->peg_revision;
sourcepath1 = source_peg->path_or_url;
}
@@ -329,19 +427,18 @@ svn_cl__merge(apr_getopt_t *os,
"with --reintegrate"));
}
- if (opt_state->dry_run)
+ if (opt_state->dry_run && ! opt_state->quiet)
printf(_("This is a dry-run merge: the working copy will not be
changed.\n"));
if (opt_state->reintegrate)
{
- printf(_("Reintegrate merge\n"));
- printf(_(" from '%s' into '%s'\n"),
- sourcepath1, targetpath);
- err = svn_client_merge_reintegrate(sourcepath1,
- &peg_revision1,
- targetpath,
- opt_state->dry_run,
- options, ctx, pool);
+ if (! opt_state->quiet)
+ printf(_("Reintegrate merge\n"
+ " from '%s' into '%s'\n"),
+ sourcepath1, targetpath);
+ err = merge_reintegrate(sourcepath1, &peg_revision1, targetpath,
+ opt_state->dry_run, opt_state->quiet,
+ options, ctx, pool);
/* Tell the user how to keep the source branch alive. */
if (! err)
@@ -368,14 +465,19 @@ svn_cl__merge(apr_getopt_t *os,
range->end = peg_revision1;
APR_ARRAY_PUSH(ranges_to_merge, svn_opt_revision_range_t *) = range;
- printf(_("Sync merge\n"));
+ if (! opt_state->quiet)
+ printf(_("Sync merge\n"
+ " from '%s' to '%s'\n"),
+ sourcepath1, targetpath);
}
else
{
- printf(_("Cherry-pick merge\n"));
+ if (! opt_state->quiet)
+ printf(_("Cherry-pick merge\n"
+ " from '%s' to '%s'\n"),
+ sourcepath1, targetpath);
}
- printf(_(" from '%s' to '%s'\n"),
- sourcepath1, targetpath);
+
err = svn_client_merge_peg4(sourcepath1,
ranges_to_merge,
&peg_revision1,
@@ -396,9 +498,10 @@ svn_cl__merge(apr_getopt_t *os,
return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
_("Merge sources must both be "
"either paths or URLs"));
- printf(_("Two-URL merge\n"));
- printf(_(" from diff between '%s' and '%s' into '%s'\n"),
- sourcepath1, sourcepath2, targetpath);
+ if (! opt_state->quiet)
+ printf(_("Two-URL merge\n"
+ " from diff between '%s' and '%s' into '%s'\n"),
+ sourcepath1, sourcepath2, targetpath);
err = svn_client_merge4(sourcepath1,
&first_range_start,
sourcepath2,