Author: stsp
Date: Thu Nov 24 10:17:39 2011
New Revision: 1205776

URL: http://svn.apache.org/viewvc?rev=1205776&view=rev
Log:
On the moves-scan-log branch, fix detection of applicable moves during update.

* subversion/libsvn_wc/update_editor.c
  (find_applicable_move): Return proper move chains containing all applicable
   moves, instead of returning just the last applicable move.
   A move which happened in the base revision of a node does apply if updating
   into the past, so don't ignore such moves.

Modified:
    subversion/branches/moves-scan-log/subversion/libsvn_wc/update_editor.c

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=1205776&r1=1205775&r2=1205776&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:17:39 2011
@@ -1875,17 +1875,34 @@ find_applicable_move(svn_wc_repos_move_i
               if (strcmp(this_move->moved_from_repos_relpath,
                          repos_relpath) == 0)
                 {
-                  /* Move forward to the last applicable move in the chain,
-                   * collapsing the move chain (e.g. a->b->c->d) into the
-                   * move which is applied by the update (e.g. b->d). */
+                  svn_wc_repos_move_info_t *m;
+
+                  /* Create a shallow copy of the move chain which contains
+                   * only elements of the chain which are applicable to
+                   * the node being updated.
+                   * A shallow copy is sufficient because data is allocated
+                   * in the global editor pool. */
+                  m = svn_wc_create_repos_move_info(
+                        this_move->moved_from_repos_relpath,
+                        this_move->moved_to_repos_relpath,
+                        this_move->revision,
+                        this_move->copyfrom_rev,
+                        NULL, NULL, result_pool);
+                  *move = m;
+                  /* Add any further applicable moves to the chain. */
                   while (this_move->next)
                     {
                       if (this_move->next->revision > *eb->target_revision)
                         break;
                       this_move = this_move->next;
+                      m = svn_wc_create_repos_move_info(
+                            this_move->moved_from_repos_relpath,
+                            this_move->moved_to_repos_relpath,
+                            this_move->revision,
+                            this_move->copyfrom_rev,
+                            m, NULL, result_pool);
                     }
 
-                  *move = this_move;
                   break;
                 }
             }
@@ -1904,8 +1921,8 @@ find_applicable_move(svn_wc_repos_move_i
           apr_array_header_t *moves = elt.value;
 
          /* When updating into the past, a move applies if it
-          * happened before the base rev of the node. */
-          if (*rev >= base_revision)
+          * happened before or at the base rev of the node. */
+          if (*rev > base_revision)
             continue;
 
           /* Generally, we have a chain of reversed moves which happened
@@ -1923,16 +1940,42 @@ find_applicable_move(svn_wc_repos_move_i
               if (strcmp(this_move->moved_to_repos_relpath,
                          repos_relpath) == 0)
                 {
-                  /* Move backwards to the last applicable move in the chain,
-                   * collapsing the move chain (e.g. d->c->b->a) into the
-                   * move which is applied by the update (e.g. d->b). */
+                  svn_wc_repos_move_info_t *m;
+
+                  /* Create a shallow copy of the move chain which contains
+                   * only elements of the chain which are applicable to
+                   * the node being updated.
+                   * A shallow copy is sufficient because data is allocated
+                   * in the global editor pool.
+                   *
+                   * The returned chain is reversed to the chain obtained
+                   * from the log because we're updating into the past,
+                   * i.e. the 'next' and 'prev' pointers are reversed.
+                   * For the same reason we must use the revision the move
+                   * happened in as the copyfrom revision, turning the
+                   * delete-half of a move into a fake copy from future
+                   * history. */
+                  m = svn_wc_create_repos_move_info(
+                        this_move->moved_to_repos_relpath,
+                        this_move->moved_from_repos_relpath,
+                        this_move->revision,
+                        this_move->revision,
+                        NULL, NULL, result_pool);
+                  *move = m;
+                  /* Add any further applicable moves to the chain. */
                   while (this_move->prev)
                     {
                       if (this_move->prev->revision < *eb->target_revision)
                         break;
                       this_move = this_move->prev;
+                      m = svn_wc_create_repos_move_info(
+                            this_move->moved_to_repos_relpath,
+                            this_move->moved_from_repos_relpath,
+                            this_move->revision,
+                            this_move->revision,
+                            m, NULL, result_pool);
                     }
-                  *move = this_move;
+
                   break;
                 }
             }


Reply via email to