Author: stsp
Date: Thu Nov 24 10:51:24 2011
New Revision: 1205784

URL: http://svn.apache.org/viewvc?rev=1205784&view=rev
Log:
On the moves-scan-log branch, fix support for multiple move suggestions.

* subversion/include/svn_wc.h
  (svn_wc_conflict_description2_t): Rename suggested_move to suggested_moves
   and make this an array. This will be useful in case the log scanning
   heuristic returns multiple move suggestions (which it does not as of yet).

* subversion/svn/conflict-callbacks.c
  (pick_move, svn_cl__conflict_handler): Handle move suggestions array.
   If only one suggestion is present in the array, use it right away
   without prompting the user (is this always OK? TBD).

* subversion/libsvn_wc/update_editor.c
  (find_applicable_move): Rename to ...
  (find_applicable_moves): ... this, and return an array of applicable move
   chains instead of just one move chain.
  (delete_entry): Handle move suggestions array.

Modified:
    subversion/branches/moves-scan-log/subversion/include/svn_wc.h
    subversion/branches/moves-scan-log/subversion/libsvn_wc/update_editor.c
    subversion/branches/moves-scan-log/subversion/svn/conflict-callbacks.c

Modified: subversion/branches/moves-scan-log/subversion/include/svn_wc.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/include/svn_wc.h?rev=1205784&r1=1205783&r2=1205784&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/include/svn_wc.h (original)
+++ subversion/branches/moves-scan-log/subversion/include/svn_wc.h Thu Nov 24 
10:51:24 2011
@@ -1847,11 +1847,12 @@ typedef struct svn_wc_conflict_descripti
 
   /** A chain of one or more suggested moves in case the server sends moves
    * as copy+delete and the revision log was scanned for server-side moves
-   * at the user's request.
+   * at the user's request. Elements of this array are pointers to
+   * svn_wc_repos_move_info_t structures.
    * @see svn_wc_conflict_choice_t
    * @see svn_wc_repos_move_info_t
    * @since New in 1.8. */
-  svn_wc_repos_move_info_t *suggested_move;
+  apr_array_header_t *suggested_moves;
 
   /* Remember to adjust svn_wc__conflict_description2_dup()
    * if you add new fields to this struct. */

Modified: 
subversion/branches/moves-scan-log/subversion/libsvn_wc/update_editor.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_wc/update_editor.c?rev=1205784&r1=1205783&r2=1205784&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/libsvn_wc/update_editor.c 
(original)
+++ subversion/branches/moves-scan-log/subversion/libsvn_wc/update_editor.c Thu 
Nov 24 10:51:24 2011
@@ -1807,11 +1807,11 @@ compare_revision_items_ascending(const s
 }
 
 static svn_error_t *
-find_applicable_move(svn_wc_repos_move_info_t **move,
-                     struct edit_baton *eb,
-                     const char *local_abspath,
-                     apr_pool_t *result_pool,
-                     apr_pool_t *scratch_pool)
+find_applicable_moves(apr_array_header_t **moves,
+                      struct edit_baton *eb,
+                      const char *local_abspath,
+                      apr_pool_t *result_pool,
+                      apr_pool_t *scratch_pool)
 {
   const char *repos_relpath;
   svn_revnum_t base_revision;
@@ -1819,7 +1819,7 @@ find_applicable_move(svn_wc_repos_move_i
   svn_boolean_t update_into_past;
   int i;
 
-  *move = NULL;
+  *moves = apr_array_make(result_pool, 0, sizeof(svn_wc_repos_move_info_t *));
 
   if (! eb->repos_moves || apr_hash_count(eb->repos_moves) == 0)
     return SVN_NO_ERROR;
@@ -1853,7 +1853,7 @@ find_applicable_move(svn_wc_repos_move_i
           svn_sort__item_t elt = APR_ARRAY_IDX(sorted, i,
                                                svn_sort__item_t);
           const svn_revnum_t *rev = elt.key;
-          apr_array_header_t *moves = elt.value;
+          apr_array_header_t *moves_in_rev = elt.value;
 
          /* When updating into the future, a move applies if it
           * happened after the base rev of the node. */
@@ -1866,11 +1866,11 @@ find_applicable_move(svn_wc_repos_move_i
            *   rB: mv b->c
            *   rC: mv c->d
            * and so on. Find the first applicable move in the chain. */
-          for (j = 0; j < moves->nelts; j++)
+          for (j = 0; j < moves_in_rev->nelts; j++)
             {
               svn_wc_repos_move_info_t *this_move;
 
-              this_move = APR_ARRAY_IDX(moves, j,
+              this_move = APR_ARRAY_IDX(moves_in_rev, j,
                                         svn_wc_repos_move_info_t *);
               if (strcmp(this_move->moved_from_repos_relpath,
                          repos_relpath) == 0)
@@ -1888,7 +1888,7 @@ find_applicable_move(svn_wc_repos_move_i
                         this_move->revision,
                         this_move->copyfrom_rev,
                         NULL, NULL, result_pool);
-                  *move = m;
+                  APR_ARRAY_PUSH(*moves, svn_wc_repos_move_info_t *) = m;
                   /* Add any further applicable moves to the chain. */
                   while (this_move->next)
                     {
@@ -1918,7 +1918,7 @@ find_applicable_move(svn_wc_repos_move_i
           svn_sort__item_t elt = APR_ARRAY_IDX(sorted, i,
                                                svn_sort__item_t);
           const svn_revnum_t *rev = elt.key;
-          apr_array_header_t *moves = elt.value;
+          apr_array_header_t *moves_in_rev = elt.value;
 
          /* When updating into the past, a move applies if it
           * happened before or at the base rev of the node. */
@@ -1931,11 +1931,11 @@ find_applicable_move(svn_wc_repos_move_i
            *   rB: mv c->b (actually b->c)
            *   rA: mv b->a (actually a->b)
            * and so on. Find the first applicable move in the chain. */
-          for (j = 0; j < moves->nelts; j++)
+          for (j = 0; j < moves_in_rev->nelts; j++)
             {
               svn_wc_repos_move_info_t *this_move;
 
-              this_move = APR_ARRAY_IDX(moves, j,
+              this_move = APR_ARRAY_IDX(moves_in_rev, j,
                                         svn_wc_repos_move_info_t *);
               if (strcmp(this_move->moved_to_repos_relpath,
                          repos_relpath) == 0)
@@ -1961,7 +1961,7 @@ find_applicable_move(svn_wc_repos_move_i
                         this_move->revision,
                         this_move->revision,
                         NULL, NULL, result_pool);
-                  *move = m;
+                  APR_ARRAY_PUSH(*moves, svn_wc_repos_move_info_t *) = m;
                   /* Add any further applicable moves to the chain. */
                   while (this_move->prev)
                     {
@@ -2137,17 +2137,15 @@ delete_entry(const char *path,
                                             " returned no results"));
           if (result->choice == svn_wc_conflict_choose_scan_log_for_moves)
             {
-              svn_wc_repos_move_info_t *move;
-
               /* Scan revision log for server-side moves */
               SVN_ERR(get_repos_moves(eb, scratch_pool));
               
               /* Find a server-side move which applies to the deleted node. */
               if (apr_hash_count(eb->repos_moves) > 0)
                 {
-                  SVN_ERR(find_applicable_move(&move, eb, local_abspath,
-                                              scratch_pool, scratch_pool));
-                  tree_conflict->suggested_move = move;
+                  SVN_ERR(find_applicable_moves(
+                            &tree_conflict->suggested_moves, eb,
+                            local_abspath, scratch_pool, scratch_pool));
                 }
               continue;
             }

Modified: subversion/branches/moves-scan-log/subversion/svn/conflict-callbacks.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/svn/conflict-callbacks.c?rev=1205784&r1=1205783&r2=1205784&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/svn/conflict-callbacks.c 
(original)
+++ subversion/branches/moves-scan-log/subversion/svn/conflict-callbacks.c Thu 
Nov 24 10:51:24 2011
@@ -258,18 +258,31 @@ launch_resolver(svn_boolean_t *performed
 
 static svn_error_t *
 pick_move(svn_wc_repos_move_info_t **move,
-          const svn_wc_conflict_description2_t *desc,
+          apr_array_header_t *suggested_moves,
           svn_cmdline_prompt_baton_t *pb,
           apr_pool_t *scratch_pool)
 {
   const char *prompt;
-  svn_wc_repos_move_info_t *this_move = desc->suggested_move;
+  svn_wc_repos_move_info_t *this_move;
   int i = 0;
   int m;
   apr_pool_t *iterpool;
 
-  prompt = _("Moves found in revision log:\n");
-  do
+  if (suggested_moves->nelts == 1)
+    {
+      this_move = APR_ARRAY_IDX(suggested_moves, 0,
+                                svn_wc_repos_move_info_t *);
+      SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
+                _("  [r%ld] %s@%ld -> %s\n"),
+                this_move->revision, this_move->moved_from_repos_relpath,
+                this_move->copyfrom_rev, this_move->moved_to_repos_relpath));
+      
+      *move = this_move;
+      return SVN_NO_ERROR;
+    }
+
+  prompt = _("Multiple moves found in revision log:\n");
+  for (i = 0; i < suggested_moves->nelts; i++)
     {
       prompt = apr_pstrcat(scratch_pool, prompt,
                   apr_psprintf(scratch_pool,
@@ -279,10 +292,8 @@ pick_move(svn_wc_repos_move_info_t **mov
                                 this_move->copyfrom_rev,
                                 this_move->moved_to_repos_relpath),
                   (char *)NULL);
-      i++;
       this_move = this_move->next;
     }
-  while (this_move);
 
   prompt = apr_pstrcat(scratch_pool, prompt,
                        _("Enter number to choose incoming move or hit enter "
@@ -318,20 +329,14 @@ pick_move(svn_wc_repos_move_info_t **mov
             return svn_error_trace(err);
         }
 
-      if (m < 0 || m >= i)
+      if (m < 0 || m >= suggested_moves->nelts)
         {
           SVN_ERR(svn_cmdline_fprintf(stderr, iterpool,
                                       "Invalid choice (%i)\n", m));
           continue;
         }
 
-      *move = desc->suggested_move;
-      i = 0;
-      while (m < i && (*move)->next)
-        {
-          *move = (*move)->next;
-          m++;
-        }
+      *move = APR_ARRAY_IDX(suggested_moves, m, svn_wc_repos_move_info_t *);
     }
   svn_pool_destroy(iterpool);
 
@@ -844,7 +849,7 @@ svn_cl__conflict_handler(svn_wc_conflict
       const char *answer;
       const char *prompt;
 
-      if (!desc->suggested_move)
+      if (!desc->suggested_moves)
         SVN_ERR(svn_cmdline_fprintf(
                      stderr, subpool,
                      _("Tree conflict discovered when trying to delete\n'%s'\n"
@@ -859,16 +864,25 @@ svn_cl__conflict_handler(svn_wc_conflict
         {
           svn_pool_clear(subpool);
 
-          if (desc->suggested_move)
+          if (desc->suggested_moves)
             {
-              svn_wc_repos_move_info_t *move;
-
-              SVN_ERR(pick_move(&move, desc, b->pb, subpool));
-              if (move)
+              if (desc->suggested_moves->nelts == 0)
                 {
-                  (*result)->choice = svn_wc_conflict_choose_incoming_move;
-                  (*result)->incoming_move = move;
-                  break;
+                  SVN_ERR(svn_cmdline_fprintf(stderr, subpool,
+                          _("No moves found in revision log.\n")));
+                }
+              else
+                {
+                  svn_wc_repos_move_info_t *move;
+
+                  SVN_ERR(pick_move(&move, desc->suggested_moves, b->pb,
+                                    subpool));
+                  if (move)
+                    {
+                      (*result)->choice = svn_wc_conflict_choose_incoming_move;
+                      (*result)->incoming_move = move;
+                      break;
+                    }
                 }
             }
 
@@ -903,8 +917,26 @@ svn_cl__conflict_handler(svn_wc_conflict
 
           if (strcmp(answer, "s") == 0)
             {
-              if (desc->suggested_move)
-                continue;
+              if (desc->suggested_moves)
+                {
+                  svn_wc_repos_move_info_t *move;
+
+                  if (desc->suggested_moves->nelts == 0)
+                    {
+                      SVN_ERR(svn_cmdline_fprintf(stderr, subpool,
+                              _("No moves found in revision log.\n")));
+                      continue;
+                    }
+
+                  SVN_ERR(pick_move(&move, desc->suggested_moves, b->pb,
+                                    subpool));
+                  if (move)
+                    {
+                      (*result)->choice = svn_wc_conflict_choose_incoming_move;
+                      (*result)->incoming_move = move;
+                      break;
+                    }
+                }
               else
                 {
                   (*result)->choice = 
svn_wc_conflict_choose_scan_log_for_moves;


Reply via email to