Author: philip
Date: Fri May  4 13:59:17 2012
New Revision: 1333967

URL: http://svn.apache.org/viewvc?rev=1333967&view=rev
Log:
Don't follow "broken" moves.

* subversion/libsvn_wc/wc_db.c
  (follow_moved_to): Check moved-here on destination.

* subversion/libsvn_wc/wc-queries.sql
  (STMT_SELECT_MOVED_HERE): New.
  (STMT_SELECT_OP_DEPTH_MOVED_TO, STMT_SELECT_MOVED_TO): Remove unnecessary
   qualification for consistency with other queries.

* subversion/tests/libsvn_wc/op-depth-test.c
  (mixed_rev_move): Tweak expectations.

Modified:
    subversion/trunk/subversion/libsvn_wc/wc-queries.sql
    subversion/trunk/subversion/libsvn_wc/wc_db.c
    subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c

Modified: subversion/trunk/subversion/libsvn_wc/wc-queries.sql
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-queries.sql?rev=1333967&r1=1333966&r2=1333967&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Fri May  4 13:59:17 
2012
@@ -301,14 +301,20 @@ WHERE nodes_work.wc_id = ?1 AND nodes_wo
 -- STMT_SELECT_OP_DEPTH_MOVED_TO
 SELECT op_depth, moved_to
 FROM nodes
-WHERE nodes.wc_id = ?1 AND nodes.local_relpath = ?2
+WHERE wc_id = ?1 AND local_relpath = ?2
  AND op_depth = (SELECT MIN(op_depth) FROM nodes
                   WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > ?3)
 
 -- STMT_SELECT_MOVED_TO
 SELECT moved_to
 FROM nodes
-WHERE nodes.wc_id = ?1 AND nodes.local_relpath = ?2 AND op_depth = ?3
+WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?3
+
+-- STMT_SELECT_MOVED_HERE
+SELECT moved_here, presence
+FROM nodes
+WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth >= ?3
+ORDER BY op_depth
                   
 -- STMT_DELETE_LOCK
 DELETE FROM lock

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1333967&r1=1333966&r2=1333967&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Fri May  4 13:59:17 2012
@@ -10203,19 +10203,33 @@ follow_moved_to(apr_array_header_t **mov
     {
       working_op_depth = svn_sqlite__column_int(stmt, 0);
       node_moved_to = svn_sqlite__column_text(stmt, 1, result_pool);
-      /* ### verify moved_here? */
+    }
+  SVN_ERR(svn_sqlite__reset(stmt));
 
-      if (node_moved_to)
-        {
-          struct svn_wc__db_moved_to_t *moved_to;
+  if (node_moved_to)
+    {
+      svn_boolean_t have_row2;
 
-          moved_to = apr_palloc(result_pool, sizeof(*moved_to));
-          moved_to->op_depth = working_op_depth;
-          moved_to->local_relpath = node_moved_to;
-          APR_ARRAY_PUSH(*moved_tos, struct svn_wc__db_moved_to_t *) = 
moved_to;
-        }
+      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                        STMT_SELECT_MOVED_HERE));
+      SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, node_moved_to,
+                                relpath_depth(node_moved_to)));
+      SVN_ERR(svn_sqlite__step(&have_row2, stmt));
+      if (!have_row2 || !svn_sqlite__column_int(stmt, 0))
+        node_moved_to = NULL;
+      SVN_ERR(svn_sqlite__reset(stmt));
+      /* verify repos_path points back? */
+    }
+
+  if (node_moved_to)
+    {
+      struct svn_wc__db_moved_to_t *moved_to;
+
+      moved_to = apr_palloc(result_pool, sizeof(*moved_to));
+      moved_to->op_depth = working_op_depth;
+      moved_to->local_relpath = node_moved_to;
+      APR_ARRAY_PUSH(*moved_tos, struct svn_wc__db_moved_to_t *) = moved_to;
     }
-  SVN_ERR(svn_sqlite__reset(stmt));
 
   /* A working row with moved_to, or no working row, and we are done. */
   if (node_moved_to || !have_row)
@@ -10225,7 +10239,7 @@ follow_moved_to(apr_array_header_t **mov
   node_relpath = local_relpath;
   for (i = relpath_depth(local_relpath); i > working_op_depth; --i)
     {
-      const char *node_moved_to_relpath;
+      const char *node_moved_to_relpath, *moved_to_relpath;
 
       node_relpath = svn_relpath_dirname(node_relpath, scratch_pool);
 
@@ -10236,17 +10250,45 @@ follow_moved_to(apr_array_header_t **mov
       SVN_ERR(svn_sqlite__step(&have_row, stmt));
       SVN_ERR_ASSERT(have_row);
       node_moved_to_relpath = svn_sqlite__column_text(stmt, 0, scratch_pool);
-      /* ### verify moved_here? */
       SVN_ERR(svn_sqlite__reset(stmt));
       if (node_moved_to_relpath)
         {
-          struct svn_wc__db_moved_to_t *moved_to;
-          const char *moved_to_relpath
+          moved_to_relpath
             = svn_relpath_join(node_moved_to_relpath,
                                svn_relpath_skip_ancestor(node_relpath,
                                                          local_relpath),
                                result_pool);
 
+          SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                            STMT_SELECT_MOVED_HERE));
+          SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id,
+                                    moved_to_relpath,
+                                    relpath_depth(node_moved_to_relpath)));
+          SVN_ERR(svn_sqlite__step(&have_row, stmt));
+          if (!have_row)
+            node_moved_to_relpath = NULL;
+          else if (!svn_sqlite__column_int(stmt, 0))
+            {
+              svn_wc__db_status_t presence
+                = svn_sqlite__column_token(stmt, 1, presence_map);
+              if (presence != svn_wc__db_status_not_present)
+                node_moved_to_relpath = NULL;
+              else
+                {
+                  SVN_ERR(svn_sqlite__step(&have_row, stmt));
+                  if (!have_row && !svn_sqlite__column_int(stmt, 0))
+                    node_moved_to_relpath = NULL;
+                }
+            }
+          SVN_ERR(svn_sqlite__reset(stmt));
+          if (!node_moved_to_relpath)
+            break;
+          /* verify repos_path points back? */
+        }
+      if (node_moved_to_relpath)
+        {
+          struct svn_wc__db_moved_to_t *moved_to;
+
           moved_to = apr_palloc(result_pool, sizeof(*moved_to));
           moved_to->op_depth = working_op_depth;
           moved_to->local_relpath = moved_to_relpath;

Modified: subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c?rev=1333967&r1=1333966&r2=1333967&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c Fri May  4 
13:59:17 2012
@@ -4951,15 +4951,17 @@ mixed_rev_move(const svn_test_opts_t *op
     SVN_ERR(check_db_rows(&b, "", nodes));
   }
 
-  /* ### These values are unchanged, is that right? */
   SVN_ERR(svn_wc__db_follow_moved_to(&moved_tos, b.wc_ctx->db,
                                      wc_path(&b, "A/B/C"), pool, pool));
-  SVN_ERR(check_moved_to(moved_tos, 0, 1, "X/B/C"));
-  SVN_TEST_ASSERT(moved_tos->nelts == 1);
+  SVN_TEST_ASSERT(moved_tos->nelts == 0);
 
   SVN_ERR(svn_wc__db_follow_moved_to(&moved_tos, b.wc_ctx->db,
                                      wc_path(&b, "A/B"), pool, pool));
-  SVN_ERR(check_moved_to(moved_tos, 0, 1, "X/B"));
+  SVN_TEST_ASSERT(moved_tos->nelts == 0);
+
+  SVN_ERR(svn_wc__db_follow_moved_to(&moved_tos, b.wc_ctx->db,
+                                     wc_path(&b, "A"), pool, pool));
+  SVN_ERR(check_moved_to(moved_tos, 0, 1, "X"));
   SVN_TEST_ASSERT(moved_tos->nelts == 1);
 
   return SVN_NO_ERROR;


Reply via email to