You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2015/11/03 18:02:44 UTC

svn commit: r1712352 - in /subversion/branches/move-tracking-2/subversion/svnmover: merge3.c svnmover.c svnmover.h

Author: julianfoad
Date: Tue Nov  3 17:02:43 2015
New Revision: 1712352

URL: http://svn.apache.org/viewvc?rev=1712352&view=rev
Log:
On the 'move-tracking-2' branch: Make 'svnmover' store conflicts in the WC,
and add subcommands 'conflicts' and 'resolved' to manipulate them.

* subversion/svnmover/merge3.c
  (conflict_kind_t,
   conflict_object_t,
   conflict_object_create,
   find_conflict,
   svnmover_conflict_resolved,
   svnmover_any_conflicts): New.
  (svnmover_branch_merge): Use svnmover_any_conflicts().

* subversion/svnmover/svnmover.c
  (action_code_t,
   action_defn_t): Add new subcommands.
  (do_switch): Store conflicts in the WC.
  (commit): New, factored out of do_commit() and final_commit(). Raise an
    error if there are unresolved conflicts.
  (do_commit): Factor out some code as commit().
  (final_commit): Delete.
  (execute): Store conflicts in the WC. Reimplement final_commit() inline.

* subversion/svnmover/svnmover.h
  (svnmover_wc_t): Add a 'conflicts' member.
  (svnmover_conflict_resolved,
   svnmover_any_conflicts): New.

Modified:
    subversion/branches/move-tracking-2/subversion/svnmover/merge3.c
    subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c
    subversion/branches/move-tracking-2/subversion/svnmover/svnmover.h

Modified: subversion/branches/move-tracking-2/subversion/svnmover/merge3.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnmover/merge3.c?rev=1712352&r1=1712351&r2=1712352&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnmover/merge3.c (original)
+++ subversion/branches/move-tracking-2/subversion/svnmover/merge3.c Tue Nov  3 17:02:43 2015
@@ -354,6 +354,122 @@ svnmover_display_conflicts(conflict_stor
   return SVN_NO_ERROR;
 }
 
+enum conflict_kind_t { conflict_kind_single_element,
+                       conflict_kind_clash,
+                       conflict_kind_cycle,
+                       conflict_kind_orphan };
+
+/*  */
+typedef struct conflict_object_t
+{
+  enum conflict_kind_t conflict_kind;
+  apr_hash_t *conflicts;
+  const void *key;
+} conflict_object_t;
+
+/*  */
+static conflict_object_t *
+conflict_object_create(enum conflict_kind_t conflict_kind,
+                       apr_hash_t *conflicts,
+                       const void *key,
+                       apr_pool_t *result_pool)
+{
+  conflict_object_t *c = apr_pcalloc(result_pool, sizeof(*c));
+
+  c->conflict_kind = conflict_kind;
+  c->conflicts = conflicts;
+  c->key = (conflict_kind == conflict_kind_clash)
+             ? apr_pstrdup(result_pool, key)
+             : apr_pmemdup(result_pool, key, sizeof(int));
+  return c;
+}
+
+static svn_error_t *
+find_conflict(conflict_object_t **conflict_p,
+              conflict_storage_t *conflicts,
+              const char *id_string,
+              apr_pool_t *result_pool,
+              apr_pool_t *scratch_pool)
+{
+  *conflict_p = NULL;
+
+  if (id_string[0] == 'e')
+    {
+      int which_eid = atoi(id_string + 1);
+
+      if (svn_int_hash_get(conflicts->single_element_conflicts, which_eid))
+        {
+          *conflict_p
+            = conflict_object_create(conflict_kind_single_element,
+                                     conflicts->single_element_conflicts,
+                                     &which_eid, result_pool);
+        }
+      if (svn_int_hash_get(conflicts->cycle_conflicts, which_eid))
+        {
+          *conflict_p
+            = conflict_object_create(conflict_kind_cycle,
+                                     conflicts->cycle_conflicts,
+                                     &which_eid, result_pool);
+        }
+      if (svn_int_hash_get(conflicts->orphan_conflicts, which_eid))
+        {
+          *conflict_p
+            = conflict_object_create(conflict_kind_orphan,
+                                     conflicts->orphan_conflicts,
+                                     &which_eid, result_pool);
+        }
+    }
+  else
+    {
+      if (svn_hash_gets(conflicts->name_clash_conflicts, id_string))
+        {
+          *conflict_p
+            = conflict_object_create(conflict_kind_clash,
+                                     conflicts->name_clash_conflicts,
+                                     id_string, result_pool);
+        }
+    }
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svnmover_conflict_resolved(conflict_storage_t *conflicts,
+                           const char *id_string,
+                           apr_pool_t *scratch_pool)
+{
+  conflict_object_t *conflict;
+
+  SVN_ERR(find_conflict(&conflict, conflicts, id_string,
+                        scratch_pool, scratch_pool));
+  if (! conflict)
+    {
+      return svn_error_createf(SVN_ERR_BRANCHING, NULL,
+                               _("Conflict '%s' not found"), id_string);
+    }
+
+  if (conflict->conflict_kind == conflict_kind_clash)
+    {
+      svn_hash_sets(conflict->conflicts, conflict->key, NULL);
+    }
+  else
+    {
+      apr_hash_set(conflict->conflicts, conflict->key, sizeof (int), NULL);
+    }
+  svnmover_notify("Marked conflict '%s' as resolved", id_string);
+  return SVN_NO_ERROR;
+}
+
+svn_boolean_t
+svnmover_any_conflicts(const conflict_storage_t *conflicts)
+{
+  return conflicts
+    && (apr_hash_count(conflicts->single_element_conflicts)
+        || apr_hash_count(conflicts->name_clash_conflicts)
+        || apr_hash_count(conflicts->cycle_conflicts)
+        || apr_hash_count(conflicts->orphan_conflicts));
+}
+
 /* Merge the payload for one element.
  *
  * If there is no conflict, set *CONFLICT_P to FALSE and *RESULT_P to the
@@ -982,10 +1098,7 @@ svnmover_branch_merge(svn_branch_txn_t *
 
   if (conflict_storage_p)
     {
-      if (apr_hash_count(conflicts->single_element_conflicts)
-          || apr_hash_count(conflicts->name_clash_conflicts)
-          || apr_hash_count(conflicts->cycle_conflicts)
-          || apr_hash_count(conflicts->orphan_conflicts))
+      if (svnmover_any_conflicts(conflicts))
         {
           *conflict_storage_p = conflicts;
         }

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=1712352&r1=1712351&r2=1712352&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c (original)
+++ subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c Tue Nov  3 17:02:43 2015
@@ -772,6 +772,8 @@ wc_commit(svn_revnum_t *new_rev_p,
 
 typedef enum action_code_t {
   ACTION_INFO_WC,
+  ACTION_LIST_CONFLICTS,
+  ACTION_RESOLVED_CONFLICT,
   ACTION_DIFF,
   ACTION_LOG,
   ACTION_LIST_BRANCHES,
@@ -812,6 +814,10 @@ static const action_defn_t action_defn[]
 {
   {ACTION_INFO_WC,          "info-wc", 0, "",
     "print information about the WC"},
+  {ACTION_LIST_CONFLICTS,   "conflicts", 0, "",
+    "list unresolved conflicts"},
+  {ACTION_RESOLVED_CONFLICT,"resolved", 1, "CONFLICT_ID",
+    "mark conflict as resolved"},
   {ACTION_LIST_BRANCHES,    "branches", 1, "PATH",
     "list all branches rooted at the same element as PATH"},
   {ACTION_LIST_BRANCHES_R,  "ls-br-r", 0, "",
@@ -1318,7 +1324,6 @@ do_switch(svnmover_wc_t *wc,
   if (has_local_changes)
     {
       svn_branch_el_rev_id_t *yca, *src, *tgt;
-      conflict_storage_t *conflicts;
 
       /* Merge changes from the old into the new WC */
       yca = svn_branch_el_rev_id_create(previous_base_br,
@@ -1331,12 +1336,12 @@ 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(svnmover_branch_merge(wc->edit_txn, &conflicts,
+      SVN_ERR(svnmover_branch_merge(wc->edit_txn, &wc->conflicts,
                                     src, tgt, yca, scratch_pool, scratch_pool));
 
-      if (conflicts)
+      if (svnmover_any_conflicts(wc->conflicts))
         {
-          SVN_ERR(svnmover_display_conflicts(conflicts, scratch_pool));
+          SVN_ERR(svnmover_display_conflicts(wc->conflicts, scratch_pool));
           return svn_error_createf(
                    SVN_ERR_BRANCHING, NULL,
                    _("Switch failed because of conflicts"));
@@ -2347,6 +2352,28 @@ display_diff_of_commit(const commit_call
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+commit(svn_revnum_t *new_rev_p,
+       svnmover_wc_t *wc,
+       apr_hash_t *revprops,
+       apr_pool_t *scratch_pool)
+{
+  if (svnmover_any_conflicts(wc->conflicts))
+    {
+      return svn_error_createf(SVN_ERR_BRANCHING, NULL,
+                               _("Cannot commit because there are "
+                                 "unresolved conflicts"));
+    }
+
+  /* Complete the old edit drive (into the 'WC') */
+  SVN_ERR(svn_branch_txn_sequence_point(wc->edit_txn, scratch_pool));
+
+  /* Commit */
+  SVN_ERR(wc_commit(new_rev_p, wc, revprops, scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
 /* Commit and update WC.
  *
  * Set *NEW_REV_P to the committed revision number, and update the WC to
@@ -2365,11 +2392,7 @@ do_commit(svn_revnum_t *new_rev_p,
 {
   svn_revnum_t new_rev;
 
-  /* Complete the old edit drive (into the 'WC') */
-  SVN_ERR(svn_branch_txn_sequence_point(wc->edit_txn, scratch_pool));
-
-  /* Commit */
-  SVN_ERR(wc_commit(&new_rev, wc, revprops, scratch_pool));
+  SVN_ERR(commit(&new_rev, wc, revprops, scratch_pool));
 
   /* Check out a new WC.
      (Instead, we could perhaps just get a new WC editor.) */
@@ -2690,6 +2713,26 @@ execute(svnmover_wc_t *wc,
           }
           break;
 
+        case ACTION_LIST_CONFLICTS:
+          {
+            if (svnmover_any_conflicts(wc->conflicts))
+              {
+                SVN_ERR(svnmover_display_conflicts(wc->conflicts, iterpool));
+              }
+          }
+          break;
+
+        case ACTION_RESOLVED_CONFLICT:
+          {
+            if (svnmover_any_conflicts(wc->conflicts))
+              {
+                SVN_ERR(svnmover_conflict_resolved(wc->conflicts,
+                                                   action->relpath[0],
+                                                   iterpool));
+              }
+          }
+          break;
+
         case ACTION_DIFF:
           VERIFY_EID_EXISTS("diff", 0);
           VERIFY_EID_EXISTS("diff", 1);
@@ -2860,8 +2903,6 @@ execute(svnmover_wc_t *wc,
 
         case ACTION_MERGE:
           {
-            conflict_storage_t *conflicts;
-
             VERIFY_EID_EXISTS("merge", 0);
             VERIFY_EID_EXISTS("merge", 1);
             VERIFY_EID_EXISTS("merge", 2);
@@ -2874,15 +2915,15 @@ execute(svnmover_wc_t *wc,
                   arg[0]->el_rev->eid, arg[1]->el_rev->eid, arg[2]->el_rev->eid);
               }
             SVN_ERR(svnmover_branch_merge(wc->edit_txn,
-                                          &conflicts,
+                                          &wc->conflicts,
                                           arg[0]->el_rev /*from*/,
                                           arg[1]->el_rev /*to*/,
                                           arg[2]->el_rev /*yca*/,
                                           iterpool, iterpool));
 
-            if (conflicts)
+            if (svnmover_any_conflicts(wc->conflicts))
               {
-                SVN_ERR(svnmover_display_conflicts(conflicts, iterpool));
+                SVN_ERR(svnmover_display_conflicts(wc->conflicts, iterpool));
                 return svn_error_createf(
                          SVN_ERR_BRANCHING, NULL,
                          _("Merge failed because of conflicts"));
@@ -3098,25 +3139,6 @@ execute(svnmover_wc_t *wc,
   return SVN_NO_ERROR;
 }
 
-/*  */
-static svn_error_t *
-final_commit(svnmover_wc_t *wc,
-             apr_hash_t *revprops,
-             apr_pool_t *scratch_pool)
-{
-  svn_error_t *err;
-
-  /* Complete the old edit drive (into the 'WC') */
-  SVN_ERR(svn_branch_txn_sequence_point(wc->edit_txn, scratch_pool));
-
-  /* Commit, if there are any changes */
-  err = wc_commit(NULL, wc, revprops, scratch_pool);
-
-  svn_pool_destroy(wc->pool);
-
-  return svn_error_trace(err);
-}
-
 /* Perform the typical suite of manipulations for user-provided URLs
    on URL, returning the result (allocated from POOL): IRI-to-URI
    conversion, auto-escaping, and canonicalization. */
@@ -3888,7 +3910,10 @@ sub_main(int *exit_code, int argc, const
     }
   while (interactive_actions && action_args);
 
-  SVN_ERR(final_commit(wc, revprops, pool));
+  /* Final commit */
+  err = commit(NULL, wc, revprops, pool);
+  svn_pool_destroy(wc->pool);
+  SVN_ERR(err);
 
   return SVN_NO_ERROR;
 }

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=1712352&r1=1712351&r2=1712352&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnmover/svnmover.h (original)
+++ subversion/branches/move-tracking-2/subversion/svnmover/svnmover.h Tue Nov  3 17:02:43 2015
@@ -56,6 +56,9 @@ typedef struct svnmover_wc_version_t
   svn_branch_state_t *branch;
 } svnmover_wc_version_t;
 
+/*  */
+typedef struct conflict_storage_t conflict_storage_t;
+
 typedef struct svnmover_wc_t
 {
   apr_pool_t *pool;
@@ -65,6 +68,7 @@ typedef struct svnmover_wc_t
 
   svn_ra_session_t *ra_session;
   svn_branch_txn_t *edit_txn;
+  conflict_storage_t *conflicts;
 
   /* Base and working versions. */
   svnmover_wc_version_t *base, *working;
@@ -77,8 +81,7 @@ typedef struct svnmover_wc_t
 
 } svnmover_wc_t;
 
-/*  */
-typedef struct conflict_storage_t
+struct conflict_storage_t
 {
   /* Single-element conflicts */
   /* (eid -> element_merge3_conflict_t) */
@@ -95,7 +98,7 @@ typedef struct conflict_storage_t
   /* Orphan conflicts */
   /* (eid -> orphan_conflict_t) */
   apr_hash_t *orphan_conflicts;
-} conflict_storage_t;
+};
 
 /* Merge SRC into TGT, using the common ancestor YCA.
  *
@@ -125,6 +128,15 @@ svn_error_t *
 svnmover_display_conflicts(conflict_storage_t *conflict_storage,
                            apr_pool_t *scratch_pool);
 
+svn_error_t *
+svnmover_conflict_resolved(conflict_storage_t *conflicts,
+                           const char *id_string,
+                           apr_pool_t *scratch_pool);
+
+/*  */
+svn_boolean_t
+svnmover_any_conflicts(const conflict_storage_t *conflicts);
+
 
 #ifdef __cplusplus
 }