Modified: subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c?rev=1710565&r1=1710564&r2=1710565&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c 
(original)
+++ subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c Mon Oct 
26 11:06:50 2015
@@ -1218,783 +1218,6 @@ list_all_branches(svn_branch_txn_t *txn,
   return SVN_NO_ERROR;
 }
 
-/* Options to control how strict the merge is about detecting conflicts.
- *
- * The options affect cases that, depending on the user's preference, could
- * either be considered a conflict or be merged to a deterministic result.
- *
- * The set of options is flexible and may be extended in future.
- */
-typedef struct merge_conflict_policy_t
-{
-  /* Whether to merge delete-vs-delete */
-  svn_boolean_t merge_double_delete;
-  /* Whether to merge add-vs-add (with same parent/name/payload) */
-  svn_boolean_t merge_double_add;
-  /* Whether to merge reparent-vs-reparent (with same parent) */
-  svn_boolean_t merge_double_reparent;
-  /* Whether to merge rename-vs-rename (with same name) */
-  svn_boolean_t merge_double_rename;
-  /* Whether to merge modify-vs-modify (with same payload) */
-  svn_boolean_t merge_double_modify;
-  /* Possible additional controls: */
-  /* merge (parent, name, props, text) independently or as a group */
-  /* merge (parent, name) independently or as a group */
-  /* merge (props, text) independently or as a group */
-} merge_conflict_policy_t;
-
-/* An element-merge conflict description.
- */
-typedef struct element_merge3_conflict_t
-{
-  svn_element_content_t *yca;
-  svn_element_content_t *side1;
-  svn_element_content_t *side2;
-} element_merge3_conflict_t;
-
-static element_merge3_conflict_t *
-element_merge3_conflict_create(svn_element_content_t *yca,
-                               svn_element_content_t *side1,
-                               svn_element_content_t *side2,
-                               apr_pool_t *result_pool)
-{
-  element_merge3_conflict_t *c = apr_pcalloc(result_pool, sizeof(*c));
-
-  c->yca = yca;
-  c->side1 = side1;
-  c->side2 = side2;
-  return c;
-}
-
-/* A name-clash conflict description.
- */
-typedef struct name_clash_conflict_t
-{
-  int parent_eid;
-  const char *name;
-  /* All EIDs that conflict with each other: hash of (eid -> irrelevant). */
-  apr_hash_t *elements;
-} name_clash_conflict_t;
-
-static name_clash_conflict_t *
-name_clash_conflict_create(int parent_eid,
-                           const char *name,
-                           apr_pool_t *result_pool)
-{
-  name_clash_conflict_t *c = apr_pcalloc(result_pool, sizeof(*c));
-
-  c->parent_eid = parent_eid;
-  c->name = apr_pstrdup(result_pool, name);
-  c->elements = apr_hash_make(result_pool);
-  return c;
-}
-
-/* An orphan conflict description.
- */
-typedef struct orphan_conflict_t
-{
-  svn_element_content_t *element;
-} orphan_conflict_t;
-
-static orphan_conflict_t *
-orphan_conflict_create(svn_element_content_t *element,
-                       apr_pool_t *result_pool)
-{
-  orphan_conflict_t *c = apr_pcalloc(result_pool, sizeof(*c));
-
-  c->element = element;
-  return c;
-}
-
-typedef struct conflict_storage_t
-{
-  /* Single-element conflicts */
-  /* (eid -> element_merge3_conflict_t) */
-  apr_hash_t *single_element_conflicts;
-
-  /* Name-clash conflicts */
-  /* ("%{parent_eid}d/%{name}s" -> name_clash_conflict_t) */
-  apr_hash_t *name_clash_conflicts;
-
-  /* Orphan conflicts */
-  /* (eid -> orphan_conflict_t) */
-  apr_hash_t *orphan_conflicts;
-} conflict_storage_t;
-
-/*  */
-static conflict_storage_t *
-conflict_storage_create(apr_pool_t *result_pool)
-{
-  conflict_storage_t *c = apr_pcalloc(result_pool, sizeof(*c));
-
-  return c;
-}
-
-/*  */
-static const char *
-brief_eid_and_name_or_nil(svn_element_content_t *e,
-                          apr_pool_t *result_pool)
-{
-  return e ? apr_psprintf(result_pool, "%d/%s", e->parent_eid, e->name)
-           : "<nil>";
-
-  return SVN_NO_ERROR;
-}
-
-/*  */
-static svn_error_t *
-display_conflicts(conflict_storage_t *conflict_storage,
-                  const char *prefix,
-                  apr_pool_t *scratch_pool)
-{
-  apr_hash_index_t *hi;
-
-  for (hi = apr_hash_first(scratch_pool,
-                           conflict_storage->single_element_conflicts);
-       hi; hi = apr_hash_next(hi))
-    {
-      int eid = svn_int_hash_this_key(hi);
-      element_merge3_conflict_t *c = apr_hash_this_val(hi);
-
-      printf("%ssingle-element conflict: e%d: yca=%s, side1=%s, side2=%s\n",
-             prefix, eid,
-             brief_eid_and_name_or_nil(c->yca, scratch_pool),
-             brief_eid_and_name_or_nil(c->side1, scratch_pool),
-             brief_eid_and_name_or_nil(c->side2, scratch_pool));
-    }
-  for (hi = apr_hash_first(scratch_pool,
-                           conflict_storage->name_clash_conflicts);
-       hi; hi = apr_hash_next(hi))
-    {
-      /*const char *key = apr_hash_this_key(hi);*/
-      name_clash_conflict_t *c = apr_hash_this_val(hi);
-      apr_hash_index_t *hi2;
-
-      printf("%sname-clash conflict: peid %d, name '%s', %d elements\n",
-             prefix, c->parent_eid, c->name, apr_hash_count(c->elements));
-      for (hi2 = apr_hash_first(scratch_pool, c->elements);
-           hi2; hi2 = apr_hash_next(hi2))
-        {
-          int eid = svn_int_hash_this_key(hi2);
-
-          printf("%s  element %d\n", prefix, eid);
-        }
-    }
-  for (hi = apr_hash_first(scratch_pool,
-                           conflict_storage->orphan_conflicts);
-       hi; hi = apr_hash_next(hi))
-    {
-      int eid = svn_int_hash_this_key(hi);
-      orphan_conflict_t *c = apr_hash_this_val(hi);
-
-      printf("%sorphan conflict: element %d/%s: peid %d does not exist\n",
-             prefix, eid, c->element->name, c->element->parent_eid);
-    }
-  return SVN_NO_ERROR;
-}
-
-/* Merge the payload for one element.
- *
- * If there is no conflict, set *CONFLICT_P to FALSE and *RESULT_P to the
- * merged element; otherwise set *CONFLICT_P to TRUE and *RESULT_P to NULL.
- * Note that *RESULT_P can be null, indicating a deletion.
- *
- * This handles any case where at least one of (SIDE1, SIDE2, YCA) exists.
- *
- * Allocate the result in RESULT_POOL and/or as pointers to the inputs.
- */
-static void
-payload_merge(svn_element_payload_t **result_p,
-              svn_boolean_t *conflict_p,
-              int eid,
-              svn_element_payload_t *side1,
-              svn_element_payload_t *side2,
-              svn_element_payload_t *yca,
-              const merge_conflict_policy_t *policy,
-              apr_pool_t *result_pool,
-              apr_pool_t *scratch_pool)
-{
-  svn_boolean_t conflict = FALSE;
-  svn_element_payload_t *result = NULL;
-
-  if (yca && side1 && side2)
-    {
-      if (svn_element_payload_equal(side1, yca, scratch_pool))
-        {
-          result = side2;
-        }
-      else if (svn_element_payload_equal(side2, yca, scratch_pool))
-        {
-          result = side1;
-        }
-      else if (policy->merge_double_modify
-               && svn_element_payload_equal(side1, side2, scratch_pool))
-        {
-          SVN_DBG(("e%d double modify: ... -> { ... | ... }",
-                   eid));
-          result = side1;
-        }
-      else
-        {
-          /* ### Need not conflict if can merge props and text separately. */
-
-          SVN_DBG(("e%d conflict: payload: ... -> { ... | ... }",
-                   eid));
-          conflict = TRUE;
-        }
-    }
-
-  *result_p = result;
-  *conflict_p = conflict;
-}
-
-/* Merge the content for one element.
- *
- * If there is no conflict, set *CONFLICT_P to FALSE and *RESULT_P to the
- * merged element; otherwise set *CONFLICT_P to TRUE and *RESULT_P to NULL.
- * Note that *RESULT_P can be null, indicating a deletion.
- *
- * This handles any case where at least one of (SIDE1, SIDE2, YCA) exists.
- *
- * Allocate the result in RESULT_POOL and/or as pointers to the inputs.
- */
-static void
-element_merge(svn_element_content_t **result_p,
-              element_merge3_conflict_t **conflict_p,
-              int eid,
-              svn_element_content_t *side1,
-              svn_element_content_t *side2,
-              svn_element_content_t *yca,
-              const merge_conflict_policy_t *policy,
-              apr_pool_t *result_pool,
-              apr_pool_t *scratch_pool)
-{
-  svn_boolean_t same1 = svn_element_content_equal(yca, side1, scratch_pool);
-  svn_boolean_t same2 = svn_element_content_equal(yca, side2, scratch_pool);
-  svn_boolean_t conflict = FALSE;
-  svn_element_content_t *result = NULL;
-
-  if (same1)
-    {
-      result = side2;
-    }
-  else if (same2)
-    {
-      result = side1;
-    }
-  else if (yca && side1 && side2)
-    {
-      /* All three sides are different, and all exist */
-      result = apr_pmemdup(result_pool, yca, sizeof(*result));
-
-      /* merge the parent-eid */
-      if (side1->parent_eid == yca->parent_eid)
-        {
-          result->parent_eid = side2->parent_eid;
-        }
-      else if (side2->parent_eid == yca->parent_eid)
-        {
-          result->parent_eid = side1->parent_eid;
-        }
-      else if (policy->merge_double_reparent
-               && side1->parent_eid == side2->parent_eid)
-        {
-          SVN_DBG(("e%d double reparent: e%d -> { e%d | e%d }",
-                   eid, yca->parent_eid, side1->parent_eid, 
side2->parent_eid));
-          result->parent_eid = side1->parent_eid;
-        }
-      else
-        {
-          SVN_DBG(("e%d conflict: parent: e%d -> { e%d | e%d }",
-                   eid, yca->parent_eid, side1->parent_eid, 
side2->parent_eid));
-          conflict = TRUE;
-        }
-
-      /* merge the name */
-      if (strcmp(side1->name, yca->name) == 0)
-        {
-          result->name = side2->name;
-        }
-      else if (strcmp(side2->name, yca->name) == 0)
-        {
-          result->name = side1->name;
-        }
-      else if (policy->merge_double_rename
-               && strcmp(side1->name, side2->name) == 0)
-        {
-          SVN_DBG(("e%d double rename: %s -> { %s | %s }",
-                   eid, yca->name, side1->name, side2->name));
-          result->name = side1->name;
-        }
-      else
-        {
-          SVN_DBG(("e%d conflict: name: %s -> { %s | %s }",
-                   eid, yca->name, side1->name, side2->name));
-          conflict = TRUE;
-        }
-
-      /* merge the payload */
-      {
-        svn_boolean_t payload_conflict;
-
-        payload_merge(&result->payload, &payload_conflict,
-                      eid, side1->payload, side2->payload, yca->payload,
-                      policy, result_pool, scratch_pool);
-        if (payload_conflict)
-          conflict = TRUE;
-      }
-    }
-  else if (! side1 && ! side2)
-    {
-      /* Double delete (as we assume at least one of YCA/SIDE1/SIDE2 exists) */
-      if (policy->merge_double_delete)
-        {
-          SVN_DBG(("e%d double delete",
-                   eid));
-          result = side1;
-        }
-      else
-        {
-          SVN_DBG(("e%d conflict: delete vs. delete",
-                   eid));
-          conflict = TRUE;
-        }
-    }
-  else if (side1 && side2)
-    {
-      /* Double add (as we already handled the case where YCA also exists) */
-      /* May be allowed for equal content of a normal element (not subbranch) 
*/
-      if (policy->merge_double_add
-          && !side1->payload->is_subbranch_root
-          && !side2->payload->is_subbranch_root
-          && svn_element_content_equal(side1, side2, scratch_pool))
-        {
-          SVN_DBG(("e%d double add",
-                   eid));
-          result = side1;
-        }
-      else
-        {
-          SVN_DBG(("e%d conflict: add vs. add (%s)",
-                   eid,
-                   svn_element_content_equal(side1, side2, scratch_pool)
-                     ? "same content" : "different content"));
-          conflict = TRUE;
-        }
-    }
-  else
-    {
-      /* The remaining cases must be delete vs. modify */
-      SVN_DBG(("e%d conflict: delete vs. modify: %d -> { %d | %d }",
-               eid, !!yca, !!side1, !!side2));
-      conflict = TRUE;
-    }
-
-  *result_p = result;
-  *conflict_p
-    = conflict ? element_merge3_conflict_create(yca, side1, side2,
-                                                result_pool) : NULL;
-}
-
-static svn_error_t *
-branch_merge_subtree_r(svn_branch_txn_t *edit_txn,
-                       conflict_storage_t **conflict_storage_p,
-                       const svn_branch_el_rev_id_t *src,
-                       const svn_branch_el_rev_id_t *tgt,
-                       const svn_branch_el_rev_id_t *yca,
-                       apr_pool_t *result_pool,
-                       apr_pool_t *scratch_pool);
-
-/* Merge the subbranch of {SRC, TGT, YCA} found at EID.
- */
-static svn_error_t *
-merge_subbranch(svn_branch_txn_t *edit_txn,
-                const svn_branch_el_rev_id_t *src,
-                const svn_branch_el_rev_id_t *tgt,
-                const svn_branch_el_rev_id_t *yca,
-                int eid,
-                apr_pool_t *scratch_pool)
-{
-  svn_branch_state_t *src_subbranch
-    = svn_branch_get_subbranch_at_eid(src->branch, eid, scratch_pool);
-  svn_branch_state_t *tgt_subbranch
-    = svn_branch_get_subbranch_at_eid(tgt->branch, eid, scratch_pool);
-  svn_branch_state_t *yca_subbranch
-    = svn_branch_get_subbranch_at_eid(yca->branch, eid, scratch_pool);
-  svn_branch_el_rev_id_t *subbr_src = NULL;
-  svn_branch_el_rev_id_t *subbr_tgt = NULL;
-  svn_branch_el_rev_id_t *subbr_yca = NULL;
-
-  if (src_subbranch)
-    subbr_src = svn_branch_el_rev_id_create(
-                  src_subbranch, svn_branch_root_eid(src_subbranch),
-                  src->rev, scratch_pool);
-  if (tgt_subbranch)
-    subbr_tgt = svn_branch_el_rev_id_create(
-                  tgt_subbranch, svn_branch_root_eid(tgt_subbranch),
-                  tgt->rev, scratch_pool);
-  if (yca_subbranch)
-    subbr_yca = svn_branch_el_rev_id_create(
-                  yca_subbranch, svn_branch_root_eid(yca_subbranch),
-                  yca->rev, scratch_pool);
-
-  if (subbr_src && subbr_tgt && subbr_yca)  /* ?edit vs. ?edit */
-    {
-      conflict_storage_t *conflict_storage;
-
-      /* subbranch possibly changed in source => merge */
-      SVN_ERR(branch_merge_subtree_r(edit_txn,
-                                     &conflict_storage,
-                                     subbr_src, subbr_tgt, subbr_yca,
-                                     scratch_pool, scratch_pool));
-      /* ### store this branch's conflict_storage somewhere ... */
-    }
-  else if (subbr_src && subbr_yca)  /* ?edit vs. delete */
-    {
-      /* ### possible conflict (edit vs. delete) */
-    }
-  else if (subbr_tgt && subbr_yca)  /* delete vs. ?edit */
-    {
-      /* ### possible conflict (delete vs. edit) */
-    }
-  else if (subbr_src && subbr_tgt)  /* double add */
-    {
-      /* ### conflict */
-    }
-  else if (subbr_src)  /* added on source branch */
-    {
-      const char *new_branch_id
-        = svn_branch_id_nest(svn_branch_get_id(tgt->branch, scratch_pool),
-                             eid, scratch_pool);
-      svn_branch_rev_bid_eid_t *from
-        = svn_branch_rev_bid_eid_create(src_subbranch->txn->rev,
-                                        svn_branch_get_id(src_subbranch,
-                                                          scratch_pool),
-                                        svn_branch_root_eid(src_subbranch),
-                                        scratch_pool);
-
-      SVN_ERR(svn_branch_txn_branch(edit_txn, NULL /*new_branch_id_p*/, from,
-                                    new_branch_id, scratch_pool, 
scratch_pool));
-    }
-  else if (subbr_tgt)  /* added on target branch */
-    {
-      /* nothing to do */
-    }
-  else if (subbr_yca)  /* double delete */
-    {
-      /* ### conflict? policy option? */
-    }
-
-  return SVN_NO_ERROR;
-}
-
-/*  */
-static int
-sort_compare_items_by_peid_and_name(const svn_sort__item_t *a,
-                                    const svn_sort__item_t *b)
-{
-  svn_element_content_t *element_a = a->value;
-  svn_element_content_t *element_b = b->value;
-
-  if (element_a->parent_eid != element_b->parent_eid)
-    return element_a->parent_eid - element_b->parent_eid;
-  return strcmp(element_a->name, element_b->name);
-}
-
-/* Return all (key -> name_clash_conflict_t) name clash conflicts in BRANCH.
- */
-static svn_error_t *
-detect_clashes(apr_hash_t **clashes_p,
-               svn_branch_state_t *branch,
-               apr_pool_t *result_pool,
-               apr_pool_t *scratch_pool)
-{
-  apr_hash_t *clashes = apr_hash_make(result_pool);
-  SVN_ITER_T(svn_element_content_t) *pi;
-  int prev_eid = -1;
-  svn_element_content_t *prev_element = NULL;
-
-  for (SVN_HASH_ITER_SORTED(pi, svn_branch_get_elements(branch),
-                            sort_compare_items_by_peid_and_name, scratch_pool))
-    {
-      int eid = *(const int *)(pi->key);
-      svn_element_content_t *element = pi->val;
-
-      if (prev_element
-          && element->parent_eid == prev_element->parent_eid
-          && strcmp(element->name, prev_element->name) == 0)
-        {
-          const char *key = apr_psprintf(result_pool, "%d/%s",
-                                         element->parent_eid, element->name);
-          name_clash_conflict_t *c;
-
-          c = svn_hash_gets(clashes, key);
-          if (!c)
-            {
-              c = name_clash_conflict_create(
-                    element->parent_eid, element->name,
-                    result_pool);
-              svn_hash_sets(clashes, key, c);
-            }
-          svn_int_hash_set(c->elements, eid, &c);
-          svn_int_hash_set(c->elements, prev_eid, &c);
-        }
-      prev_eid = eid;
-      prev_element = element;
-    }
-
-  *clashes_p = clashes;
-  return SVN_NO_ERROR;
-}
-
-/* Return all (eid -> orphan_conflict_t) orphan conflicts in BRANCH.
- */
-static svn_error_t *
-detect_orphans(apr_hash_t **orphans_p,
-               svn_branch_state_t *branch,
-               apr_pool_t *result_pool,
-               apr_pool_t *scratch_pool)
-{
-  apr_hash_t *orphans = apr_hash_make(result_pool);
-  SVN_ITER_T(svn_element_content_t) *pi;
-  const svn_element_tree_t *elements = svn_branch_get_element_tree(branch);
-
-  for (SVN_HASH_ITER(pi, scratch_pool, elements->e_map))
-    {
-      int eid = *(const int *)(pi->key);
-      svn_element_content_t *element = pi->val;
-
-      if (eid != elements->root_eid
-          && ! svn_element_tree_get(elements, element->parent_eid))
-        {
-          orphan_conflict_t *c;
-
-          c = orphan_conflict_create(element, result_pool);
-          svn_int_hash_set(orphans, eid, c);
-
-          notify("  orphan: %d/%s: peid %d does not exist",
-                 eid, element->name, element->parent_eid);
-        }
-    }
-
-  *orphans_p = orphans;
-  return SVN_NO_ERROR;
-}
-
-/* Merge ...
- *
- * Merge any sub-branches in the same way, recursively.
- */
-static svn_error_t *
-branch_merge_subtree_r(svn_branch_txn_t *edit_txn,
-                       conflict_storage_t **conflict_storage_p,
-                       const svn_branch_el_rev_id_t *src,
-                       const svn_branch_el_rev_id_t *tgt,
-                       const svn_branch_el_rev_id_t *yca,
-                       apr_pool_t *result_pool,
-                       apr_pool_t *scratch_pool)
-{
-  svn_branch_subtree_t *s_src, *s_tgt, *s_yca;
-  apr_hash_t *diff_yca_src, *diff_yca_tgt;
-  apr_hash_t *e_conflicts = apr_hash_make(scratch_pool);
-  conflict_storage_t *conflict_storage = conflict_storage_create(result_pool);
-  SVN_ITER_T(svn_element_content_t *) *pi;
-  apr_hash_t *all_elements;
-  const merge_conflict_policy_t policy = { TRUE, TRUE, TRUE, TRUE, TRUE };
-  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
-
-  SVN_ERR_ASSERT(src->eid == tgt->eid);
-  SVN_ERR_ASSERT(src->eid == yca->eid);
-
-  SVN_DBG(("merge src: r%2ld %s e%3d",
-           src->rev,
-           svn_branch_get_id(src->branch, scratch_pool), src->eid));
-  SVN_DBG(("merge tgt: r%2ld %s e%3d",
-           tgt->rev,
-           svn_branch_get_id(tgt->branch, scratch_pool), tgt->eid));
-  SVN_DBG(("merge yca: r%2ld %s e%3d",
-           yca->rev,
-           svn_branch_get_id(yca->branch, scratch_pool), yca->eid));
-
-  notify_v("merging into branch %s",
-           svn_branch_get_id(tgt->branch, scratch_pool));
-  /*
-      for (eid, diff1) in element_differences(YCA, FROM):
-        diff2 = element_diff(eid, YCA, TO)
-        if diff1 and diff2:
-          result := element_merge(diff1, diff2)
-        elif diff1:
-          result := diff1.right
-        # else no change
-   */
-  s_src = svn_branch_get_subtree(src->branch, src->eid, scratch_pool);
-  s_tgt = svn_branch_get_subtree(tgt->branch, tgt->eid, scratch_pool);
-  s_yca = svn_branch_get_subtree(yca->branch, yca->eid, scratch_pool);
-  SVN_ERR(element_differences(&diff_yca_src,
-                              s_yca->tree, s_src->tree,
-                              scratch_pool, scratch_pool));
-  /* ### We only need to query for YCA:TO differences in elements that are
-         different in YCA:FROM, but right now we ask for all differences. */
-  SVN_ERR(element_differences(&diff_yca_tgt,
-                              s_yca->tree, s_tgt->tree,
-                              scratch_pool, scratch_pool));
-
-  all_elements = apr_hash_overlay(scratch_pool,
-                                  svn_branch_get_elements(src->branch),
-                                  svn_branch_get_elements(tgt->branch));
-  all_elements = apr_hash_overlay(scratch_pool,
-                                  svn_branch_get_elements(yca->branch),
-                                  all_elements);
-  for (SVN_HASH_ITER_SORTED(pi, all_elements,
-                            sort_compare_items_by_eid, scratch_pool))
-    {
-      int eid = *(const int *)(pi->key);
-      svn_element_content_t **e_yca_src
-        = svn_int_hash_get(diff_yca_src, eid);
-      svn_element_content_t **e_yca_tgt
-        = svn_int_hash_get(diff_yca_tgt, eid);
-      svn_element_content_t *e_yca;
-      svn_element_content_t *e_src;
-      svn_element_content_t *e_tgt;
-      svn_element_content_t *result;
-      element_merge3_conflict_t *conflict;
-
-      svn_pool_clear(iterpool);
-
-      /* If an element hasn't changed in the source branch, there is
-         no need to do anything with it in the target branch. We could
-         use element_merge() for any case where at least one of (SRC,
-         TGT, YCA) exists, but we choose to skip it when SRC == YCA. */
-      if (! e_yca_src)
-        {
-          /* Still need to merge any subbranch linked to this element.
-             There were no changes to the link element but that doesn't
-             mean there were no changes to the linked branch. */
-          SVN_ERR(merge_subbranch(edit_txn, src, tgt, yca, eid, iterpool));
-
-          continue;
-        }
-
-      e_yca = e_yca_src[0];
-      e_src = e_yca_src[1];
-      e_tgt = e_yca_tgt ? e_yca_tgt[1] : e_yca_src[0];
-
-      element_merge(&result, &conflict,
-                    eid, e_src, e_tgt, e_yca,
-                    &policy,
-                    scratch_pool, scratch_pool);
-
-      if (conflict)
-        {
-          notify_v("!    e%d <conflict>", eid);
-          svn_int_hash_set(e_conflicts, eid, conflict);
-        }
-      else if (e_tgt && result)
-        {
-          notify_v("M/V  e%d %s%s",
-                   eid, result->name,
-                   subbranch_str(tgt->branch, eid, iterpool));
-
-          SVN_ERR(svn_branch_state_alter_one(tgt->branch, eid,
-                                             result->parent_eid, result->name,
-                                             result->payload, iterpool));
-
-          SVN_ERR(merge_subbranch(edit_txn, src, tgt, yca, eid, iterpool));
-        }
-      else if (e_tgt)
-        {
-          notify_v("D    e%d %s%s",
-                   eid, e_yca->name,
-                   subbranch_str(yca->branch, eid, iterpool));
-          SVN_ERR(svn_branch_state_delete_one(tgt->branch, eid, iterpool));
-
-          /* ### If this is a subbranch-root element being deleted, shouldn't
-             we see if there were any changes to be merged in the subbranch,
-             and raise a delete-vs-edit conflict if so? */
-        }
-      else if (result)
-        {
-          notify_v("A    e%d %s%s",
-                   eid, result->name,
-                   subbranch_str(src->branch, eid, iterpool));
-
-          /* In BRANCH, create an instance of the element EID with new content.
-           *
-           * Translated to old language, this means create a new node-copy
-           * copied (branched) from the source-right version of the merge
-           * (which is not specified here, but will need to be),
-           * which may be in this branch or in another branch.
-           */
-          SVN_ERR(svn_branch_state_alter_one(tgt->branch, eid,
-                                             result->parent_eid, result->name,
-                                             result->payload, iterpool));
-
-          SVN_ERR(merge_subbranch(edit_txn, src, tgt, yca, eid, iterpool));
-        }
-    }
-  svn_pool_destroy(iterpool);
-
-  /* Detect clashes.
-     ### TODO: Detect clashes, cycles and orphans; and report full conflict
-               info (including the relevant incoming changes) for each
-               kind of conflict. If there are no conflicts, flatten the
-               merge result into a tree. */
-  conflict_storage->single_element_conflicts = e_conflicts;
-  SVN_ERR(detect_clashes(&conflict_storage->name_clash_conflicts,
-                         tgt->branch,
-                         result_pool, scratch_pool));
-  SVN_ERR(detect_orphans(&conflict_storage->orphan_conflicts,
-                         tgt->branch,
-                         result_pool, scratch_pool));
-
-  notify_v("merging into branch %s -- finished",
-           svn_branch_get_id(tgt->branch, scratch_pool));
-
-  *conflict_storage_p = conflict_storage;
-  return SVN_NO_ERROR;
-}
-
-/* Merge SRC into TGT, using the common ancestor YCA.
- *
- * Merge the two sets of changes: YCA -> SRC and YCA -> TGT, applying
- * the result to the transaction at TGT.
- *
- * If conflicts arise, just fail.
- *
- * SRC, TGT and YCA must be existing and corresponding (same EID) elements.
- *
- * None of SRC, TGT and YCA is a subbranch root element.
- *
- * Nested subbranches will also be merged.
- */
-static svn_error_t *
-svn_branch_merge(svn_branch_txn_t *edit_txn,
-                 conflict_storage_t **conflict_storage_p,
-                 svn_branch_el_rev_id_t *src,
-                 svn_branch_el_rev_id_t *tgt,
-                 svn_branch_el_rev_id_t *yca,
-                 apr_pool_t *scratch_pool)
-{
-  /*SVN_ERR(verify_exists_in_branch(from, scratch_pool));*/
-  /*SVN_ERR(verify_exists_in_branch(to, scratch_pool));*/
-  /*SVN_ERR(verify_exists_in_branch(yca, scratch_pool));*/
-  if (src->eid != tgt->eid || src->eid != yca->eid)
-    return svn_error_createf(SVN_ERR_BRANCHING, NULL,
-                             _("Merge branches must all be same element "
-                               "(from: e%d, to: e%d, yca: e%d)"),
-                             src->eid, tgt->eid, yca->eid);
-  /*SVN_ERR(verify_not_subbranch_root(from, scratch_pool));*/
-  /*SVN_ERR(verify_not_subbranch_root(to, scratch_pool));*/
-  /*SVN_ERR(verify_not_subbranch_root(yca, scratch_pool));*/
-
-  SVN_ERR(branch_merge_subtree_r(edit_txn,
-                                 conflict_storage_p,
-                                 src, tgt, yca,
-                                 scratch_pool, scratch_pool));
-
-  return SVN_NO_ERROR;
-}
-
 /* Switch the WC to revision BASE_REVISION (SVN_INVALID_REVNUM means HEAD)
  * and branch BRANCH_ID.
  *
@@ -2048,14 +1271,15 @@ do_switch(svnmover_wc_t *wc,
       tgt = svn_branch_el_rev_id_create(wc->working->branch,
                                         
svn_branch_root_eid(wc->working->branch),
                                         SVN_INVALID_REVNUM, scratch_pool);
-      SVN_ERR(svn_branch_merge(wc->edit_txn, &conflicts,
-                               src, tgt, yca, scratch_pool));
+      SVN_ERR(svnmover_branch_merge(wc->edit_txn, &conflicts,
+                                    src, tgt, yca, scratch_pool));
 
       if (apr_hash_count(conflicts->single_element_conflicts)
           || apr_hash_count(conflicts->name_clash_conflicts)
           || apr_hash_count(conflicts->orphan_conflicts))
         {
-          SVN_ERR(display_conflicts(conflicts, "switch: ", scratch_pool));
+          SVN_ERR(svnmover_display_conflicts(conflicts, "switch: ",
+                                             scratch_pool));
           return svn_error_createf(
                    SVN_ERR_BRANCHING, NULL,
                    _("Switch failed because of conflicts: "
@@ -3578,18 +2802,19 @@ execute(svnmover_wc_t *wc,
             VERIFY_EID_EXISTS("merge", 0);
             VERIFY_EID_EXISTS("merge", 1);
             VERIFY_EID_EXISTS("merge", 2);
-            SVN_ERR(svn_branch_merge(wc->edit_txn,
-                                     &conflicts,
-                                     arg[0]->el_rev /*from*/,
-                                     arg[1]->el_rev /*to*/,
-                                     arg[2]->el_rev /*yca*/,
-                                     iterpool));
+            SVN_ERR(svnmover_branch_merge(wc->edit_txn,
+                                          &conflicts,
+                                          arg[0]->el_rev /*from*/,
+                                          arg[1]->el_rev /*to*/,
+                                          arg[2]->el_rev /*yca*/,
+                                          iterpool));
 
             if (apr_hash_count(conflicts->single_element_conflicts)
                 || apr_hash_count(conflicts->name_clash_conflicts)
                 || apr_hash_count(conflicts->orphan_conflicts))
               {
-                SVN_ERR(display_conflicts(conflicts, "merge: ", iterpool));
+                SVN_ERR(svnmover_display_conflicts(conflicts, "merge: ",
+                                                   iterpool));
                 return svn_error_createf(
                          SVN_ERR_BRANCHING, NULL,
                          _("Merge failed because of conflicts: "

Modified: subversion/branches/move-tracking-2/subversion/svnmover/svnmover.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnmover/svnmover.h?rev=1710565&r1=1710564&r2=1710565&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnmover/svnmover.h 
(original)
+++ subversion/branches/move-tracking-2/subversion/svnmover/svnmover.h Mon Oct 
26 11:06:50 2015
@@ -65,6 +65,49 @@ typedef struct svnmover_wc_t
 
 } svnmover_wc_t;
 
+/*  */
+typedef struct conflict_storage_t
+{
+  /* Single-element conflicts */
+  /* (eid -> element_merge3_conflict_t) */
+  apr_hash_t *single_element_conflicts;
+
+  /* Name-clash conflicts */
+  /* ("%{parent_eid}d/%{name}s" -> name_clash_conflict_t) */
+  apr_hash_t *name_clash_conflicts;
+
+  /* Orphan conflicts */
+  /* (eid -> orphan_conflict_t) */
+  apr_hash_t *orphan_conflicts;
+} conflict_storage_t;
+
+/* Merge SRC into TGT, using the common ancestor YCA.
+ *
+ * Merge the two sets of changes: YCA -> SRC and YCA -> TGT, applying
+ * the result to the transaction at TGT.
+ *
+ * If conflicts arise, just fail.
+ *
+ * SRC, TGT and YCA must be existing and corresponding (same EID) elements.
+ *
+ * None of SRC, TGT and YCA is a subbranch root element.
+ *
+ * Nested subbranches will also be merged.
+ */
+svn_error_t *
+svnmover_branch_merge(svn_branch_txn_t *edit_txn,
+                      conflict_storage_t **conflict_storage_p,
+                      svn_branch_el_rev_id_t *src,
+                      svn_branch_el_rev_id_t *tgt,
+                      svn_branch_el_rev_id_t *yca,
+                      apr_pool_t *scratch_pool);
+
+/*  */
+svn_error_t *
+svnmover_display_conflicts(conflict_storage_t *conflict_storage,
+                           const char *prefix,
+                           apr_pool_t *scratch_pool);
+
 
 #ifdef __cplusplus
 }


Reply via email to