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;
}
}