You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by pr...@apache.org on 2013/02/13 11:21:36 UTC

svn commit: r1445542 [8/16] - in /subversion/branches/verify-keep-going: ./ build/generator/ build/generator/swig/ build/generator/templates/ build/win32/ contrib/server-side/fsfsfixer/fixer/ contrib/server-side/svncutter/ notes/ notes/api-errata/1.7/ ...

Modified: subversion/branches/verify-keep-going/subversion/libsvn_wc/info.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_wc/info.c?rev=1445542&r1=1445541&r2=1445542&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_wc/info.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_wc/info.c Wed Feb 13 10:21:33 2013
@@ -536,10 +536,13 @@ svn_wc__get_info(svn_wc_context_t *wc_ct
 
       if (!repos_root_url)
         {
-          SVN_ERR(svn_wc__internal_get_repos_info(&repos_root_url,
+          SVN_ERR(svn_wc__internal_get_repos_info(NULL, NULL,
+                                                  &repos_root_url,
                                                   &repos_uuid,
                                                   wc_ctx->db,
-                                                  local_abspath,
+                                                  svn_dirent_dirname(
+                                                            local_abspath,
+                                                            iterpool),
                                                   scratch_pool,
                                                   iterpool));
         }

Modified: subversion/branches/verify-keep-going/subversion/libsvn_wc/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_wc/merge.c?rev=1445542&r1=1445541&r2=1445542&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_wc/merge.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_wc/merge.c Wed Feb 13 10:21:33 2013
@@ -1396,11 +1396,27 @@ svn_wc_merge5(enum svn_wc_merge_outcome_
                                scratch_pool));
 
       if (conflict_skel && conflict_func)
-        SVN_ERR(svn_wc__conflict_invoke_resolver(wc_ctx->db, target_abspath,
-                                                 conflict_skel, merge_options,
-                                                 conflict_func, conflict_baton,
-                                                 cancel_func, cancel_baton,
-                                                 scratch_pool));
+        {
+          svn_boolean_t text_conflicted, prop_conflicted;
+
+          SVN_ERR(svn_wc__conflict_invoke_resolver(
+                    wc_ctx->db, target_abspath,
+                    conflict_skel, merge_options,
+                    conflict_func, conflict_baton,
+                    cancel_func, cancel_baton,
+                    scratch_pool));
+
+          /* Reset *MERGE_CONTENT_OUTCOME etc. if a conflict was resolved. */
+          SVN_ERR(svn_wc__internal_conflicted_p(
+                    &text_conflicted, &prop_conflicted, NULL,
+                    wc_ctx->db, target_abspath, scratch_pool));
+          if (*merge_props_outcome == svn_wc_notify_state_conflicted
+              && ! prop_conflicted)
+            *merge_props_outcome = svn_wc_notify_state_merged;
+          if (*merge_content_outcome == svn_wc_merge_conflict
+              && ! text_conflicted)
+            *merge_content_outcome = svn_wc_merge_merged;
+        }
     }
   
   return SVN_NO_ERROR;

Modified: subversion/branches/verify-keep-going/subversion/libsvn_wc/node.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_wc/node.c?rev=1445542&r1=1445541&r2=1445542&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_wc/node.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_wc/node.c Wed Feb 13 10:21:33 2013
@@ -139,44 +139,37 @@ svn_wc__node_get_children(const apr_arra
 
 
 svn_error_t *
-svn_wc__internal_get_repos_info(const char **repos_root_url,
+svn_wc__internal_get_repos_info(svn_revnum_t *revision,
+                                const char **repos_relpath,
+                                const char **repos_root_url,
                                 const char **repos_uuid,
                                 svn_wc__db_t *db,
                                 const char *local_abspath,
                                 apr_pool_t *result_pool,
                                 apr_pool_t *scratch_pool)
 {
-  svn_error_t *err;
   svn_wc__db_status_t status;
+  svn_boolean_t have_work;
 
-  err = svn_wc__db_read_info(&status, NULL, NULL, NULL,
-                             repos_root_url, repos_uuid,
-                             NULL, NULL, NULL, NULL, NULL, NULL,
-                             NULL, NULL, NULL, NULL, NULL, NULL,
-                             NULL, NULL, NULL, NULL, NULL, NULL,
-                             NULL, NULL, NULL,
-                             db, local_abspath,
-                             result_pool, scratch_pool);
-  if (err)
-    {
-      if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND
-          && err->apr_err != SVN_ERR_WC_NOT_WORKING_COPY)
-        return svn_error_trace(err);
+  SVN_ERR(svn_wc__db_read_info(&status, NULL, revision, repos_relpath,
+                               repos_root_url, repos_uuid,
+                               NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, &have_work,
+                               db, local_abspath,
+                               result_pool, scratch_pool));
 
-      /* This node is not versioned. Return NULL repos info.  */
-      svn_error_clear(err);
+  if ((repos_relpath ? *repos_relpath != NULL : TRUE)
+      && (repos_root_url ? *repos_root_url  != NULL: TRUE)
+      && (repos_uuid ? *repos_uuid != NULL : TRUE))
+    return SVN_NO_ERROR; /* We got the requested information */
 
-      if (repos_root_url)
-        *repos_root_url = NULL;
-      if (repos_uuid)
-        *repos_uuid = NULL;
-      return SVN_NO_ERROR;
+  if (!have_work) /* not-present, (server-)excluded? */
+    {
+      return SVN_NO_ERROR; /* Can't fetch more */
     }
 
-  if (((repos_root_url && *repos_root_url) || !repos_root_url)
-      && ((repos_uuid && *repos_uuid) || !repos_uuid))
-    return SVN_NO_ERROR;
-
   if (status == svn_wc__db_status_deleted)
     {
       const char *base_del_abspath, *wrk_del_abspath;
@@ -187,113 +180,82 @@ svn_wc__internal_get_repos_info(const ch
                                        scratch_pool, scratch_pool));
 
       if (base_del_abspath)
-        SVN_ERR(svn_wc__db_scan_base_repos(NULL,repos_root_url,
-                                           repos_uuid, db, base_del_abspath,
+        {
+          SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, NULL, repos_relpath,
+                                           repos_root_url, repos_uuid, NULL,
+                                           NULL, NULL, NULL, NULL, NULL, NULL,
+                                           NULL, NULL, NULL,
+                                           db, base_del_abspath,
                                            result_pool, scratch_pool));
+
+          /* If we have a repos_relpath, it is of the op-root */
+          if (repos_relpath)
+            *repos_relpath = svn_relpath_join(*repos_relpath,
+                                svn_dirent_skip_ancestor(base_del_abspath,
+                                                         local_abspath),
+                                              result_pool);
+          /* We keep revision as SVN_INVALID_REVNUM */
+        }
       else if (wrk_del_abspath)
-        SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL,
-                                         repos_root_url, repos_uuid,
-                                         NULL, NULL, NULL, NULL, NULL, NULL,
-                                         db, svn_dirent_dirname(
+        {
+          const char *op_root_abspath = NULL;
+
+          SVN_ERR(svn_wc__db_scan_addition(NULL, repos_relpath
+                                                    ? &op_root_abspath : NULL,
+                                           repos_relpath, repos_root_url,
+                                           repos_uuid, NULL, NULL, NULL, NULL,
+                                           NULL, NULL,
+                                           db, svn_dirent_dirname(
                                                    wrk_del_abspath,
                                                    scratch_pool),
-                                         result_pool, scratch_pool));
+                                           result_pool, scratch_pool));
+
+          /* If we have a repos_relpath, it is of the op-root */
+          if (repos_relpath)
+            *repos_relpath = svn_relpath_join(
+                                    *repos_relpath,
+                                    svn_dirent_skip_ancestor(op_root_abspath,
+                                                             local_abspath),
+                                    result_pool);
+        }
     }
-  else if (status == svn_wc__db_status_added)
+  else /* added, or WORKING incomplete */
     {
+      const char *op_root_abspath = NULL;
+
       /* We have an addition. scan_addition() will find the intended
          repository location by scanning up the tree.  */
-      SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL,
-                                       repos_root_url, repos_uuid,
-                                       NULL, NULL, NULL, NULL, NULL, NULL,
+      SVN_ERR(svn_wc__db_scan_addition(NULL, repos_relpath
+                                                    ? &op_root_abspath : NULL,
+                                       repos_relpath, repos_root_url,
+                                       repos_uuid, NULL, NULL, NULL, NULL,
+                                       NULL, NULL,
                                        db, local_abspath,
                                        result_pool, scratch_pool));
     }
-  else
-    SVN_ERR(svn_wc__db_scan_base_repos(NULL, repos_root_url, repos_uuid,
-                                       db, local_abspath,
-                                       result_pool, scratch_pool));
 
   SVN_ERR_ASSERT(repos_root_url == NULL || *repos_root_url != NULL);
   SVN_ERR_ASSERT(repos_uuid == NULL || *repos_uuid != NULL);
   return SVN_NO_ERROR;
 }
 
-/* ### This is essentially a copy-paste of svn_wc__internal_get_url().
- * ### If we decide to keep this one, then it should be rewritten to avoid
- * ### code duplication.*/
 svn_error_t *
-svn_wc__internal_get_repos_relpath(const char **repos_relpath,
-                                   svn_wc__db_t *db,
-                                   const char *local_abspath,
-                                   apr_pool_t *result_pool,
-                                   apr_pool_t *scratch_pool)
-{
-  svn_wc__db_status_t status;
-  svn_boolean_t have_base;
-
-  SVN_ERR(svn_wc__db_read_info(&status, NULL, NULL, repos_relpath,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL,
-                               &have_base, NULL, NULL,
-                               db, local_abspath,
-                               result_pool, scratch_pool));
-  if (*repos_relpath == NULL)
-    {
-      if (status == svn_wc__db_status_added)
-        {
-          SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, repos_relpath,
-                                           NULL, NULL, NULL, NULL,
-                                           NULL, NULL, NULL, NULL,
-                                           db, local_abspath,
-                                           result_pool, scratch_pool));
-        }
-      else if (have_base)
-        {
-          SVN_ERR(svn_wc__db_scan_base_repos(repos_relpath, NULL,
-                                             NULL,
-                                             db, local_abspath,
-                                             result_pool, scratch_pool));
-        }
-      else if (status == svn_wc__db_status_excluded
-               || (!have_base && (status == svn_wc__db_status_deleted)))
-        {
-          const char *parent_abspath, *name, *parent_relpath;
-
-          svn_dirent_split(&parent_abspath, &name, local_abspath,
-                           scratch_pool);
-          SVN_ERR(svn_wc__internal_get_repos_relpath(&parent_relpath, db,
-                                                     parent_abspath,
-                                                     scratch_pool,
-                                                     scratch_pool));
-
-          if (parent_relpath)
-            *repos_relpath = svn_relpath_join(parent_relpath, name,
-                                              result_pool);
-        }
-      else
-        {
-          /* Status: obstructed, obstructed_add */
-          *repos_relpath = NULL;
-          return SVN_NO_ERROR;
-        }
-    }
-
-  return SVN_NO_ERROR;
-}
-
-svn_error_t *
-svn_wc__node_get_repos_info(const char **repos_root_url,
+svn_wc__node_get_repos_info(svn_revnum_t *revision,
+                            const char **repos_relpath,
+                            const char **repos_root_url,
                             const char **repos_uuid,
                             svn_wc_context_t *wc_ctx,
                             const char *local_abspath,
                             apr_pool_t *result_pool,
                             apr_pool_t *scratch_pool)
 {
-  return svn_error_trace(svn_wc__internal_get_repos_info(
-            repos_root_url, repos_uuid, wc_ctx->db, local_abspath,
-            result_pool, scratch_pool));
+  return svn_error_trace(
+            svn_wc__internal_get_repos_info(revision,
+                                            repos_relpath,
+                                            repos_root_url,
+                                            repos_uuid,
+                                            wc_ctx->db, local_abspath,
+                                            result_pool, scratch_pool));
 }
 
 /* Convert DB_KIND into the appropriate NODE_KIND value.
@@ -412,20 +374,6 @@ svn_wc__node_get_url(const char **url,
                                              result_pool, scratch_pool));
 }
 
-svn_error_t *
-svn_wc__node_get_repos_relpath(const char **repos_relpath,
-                               svn_wc_context_t *wc_ctx,
-                               const char *local_abspath,
-                               apr_pool_t *result_pool,
-                               apr_pool_t *scratch_pool)
-{
-  return svn_error_trace(svn_wc__internal_get_repos_relpath(repos_relpath,
-                                                            wc_ctx->db,
-                                                            local_abspath,
-                                                            result_pool,
-                                                            scratch_pool));
-}
-
 /* A recursive node-walker, helper for svn_wc__internal_walk_children().
  *
  * Call WALK_CALLBACK with WALK_BATON on all children (recursively) of
@@ -713,16 +661,19 @@ svn_wc__node_get_base(svn_revnum_t *revi
                       const char **repos_relpath,
                       const char **repos_root_url,
                       const char **repos_uuid,
+                      const char **lock_token,
                       svn_wc_context_t *wc_ctx,
                       const char *local_abspath,
                       apr_pool_t *result_pool,
                       apr_pool_t *scratch_pool)
 {
   svn_error_t *err;
+  svn_wc__db_lock_t *lock;
 
   err = svn_wc__db_base_get_info(NULL, NULL, revision, repos_relpath,
                                  repos_root_url, repos_uuid, NULL,
-                                 NULL, NULL, NULL, NULL, NULL, NULL,
+                                 NULL, NULL, NULL, NULL, NULL,
+                                 lock_token ? &lock : NULL,
                                  NULL, NULL, NULL,
                                  wc_ctx->db, local_abspath,
                                  result_pool, scratch_pool);
@@ -737,10 +688,15 @@ svn_wc__node_get_base(svn_revnum_t *revi
         *repos_root_url = NULL;
       if (repos_uuid)
         *repos_uuid = NULL;
+      if (lock_token)
+        *lock_token = NULL;
       return SVN_NO_ERROR;
     }
   SVN_ERR(err);
 
+  if (lock_token)
+    *lock_token = lock ? lock->token : NULL;
+
   SVN_ERR_ASSERT(!revision || SVN_IS_VALID_REVNUM(*revision));
   SVN_ERR_ASSERT(!repos_relpath || *repos_relpath);
   SVN_ERR_ASSERT(!repos_root_url || *repos_root_url);
@@ -797,45 +753,6 @@ svn_wc__node_get_pre_ng_status_data(svn_
 }
 
 svn_error_t *
-svn_wc__node_get_lock_info(const char **lock_token,
-                           const char **lock_owner,
-                           const char **lock_comment,
-                           apr_time_t *lock_date,
-                           svn_wc_context_t *wc_ctx,
-                           const char *local_abspath,
-                           apr_pool_t *result_pool,
-                           apr_pool_t *scratch_pool)
-{
-  svn_wc__db_lock_t *lock;
-  svn_error_t *err;
-
-  err = svn_wc__db_base_get_info(NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                                 NULL, NULL, NULL, NULL, NULL, &lock, NULL,
-                                 NULL, NULL,
-                                 wc_ctx->db, local_abspath,
-                                 result_pool, scratch_pool);
-
-  if (err)
-    {
-      if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
-        return svn_error_trace(err);
-
-      svn_error_clear(err);
-      lock = NULL;
-    }
-  if (lock_token)
-    *lock_token = lock ? lock->token : NULL;
-  if (lock_owner)
-    *lock_owner = lock ? lock->owner : NULL;
-  if (lock_comment)
-    *lock_comment = lock ? lock->comment : NULL;
-  if (lock_date)
-    *lock_date = lock ? lock->date : 0;
-
-  return SVN_NO_ERROR;
-}
-
-svn_error_t *
 svn_wc__internal_node_get_schedule(svn_wc_schedule_t *schedule,
                                    svn_boolean_t *copied,
                                    svn_wc__db_t *db,
@@ -1272,6 +1189,8 @@ svn_error_t *
 svn_wc__check_for_obstructions(svn_wc_notify_state_t *obstruction_state,
                                svn_node_kind_t *kind,
                                svn_boolean_t *deleted,
+                               svn_boolean_t *excluded,
+                               svn_depth_t *parent_depth,
                                svn_wc_context_t *wc_ctx,
                                const char *local_abspath,
                                svn_boolean_t no_wcroot_check,
@@ -1287,6 +1206,10 @@ svn_wc__check_for_obstructions(svn_wc_no
     *kind = svn_node_none;
   if (deleted)
     *deleted = FALSE;
+  if (excluded)
+    *excluded = FALSE;
+  if (parent_depth)
+    *parent_depth = svn_depth_unknown;
 
   SVN_ERR(svn_io_check_path(local_abspath, &disk_kind, scratch_pool));
 
@@ -1309,9 +1232,10 @@ svn_wc__check_for_obstructions(svn_wc_no
         }
 
       err = svn_wc__db_read_info(&status, &db_kind, NULL, NULL, NULL, NULL,
+                                 NULL, NULL, NULL, parent_depth, NULL, NULL,
                                  NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                  NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                                 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                 NULL,
                                  wc_ctx->db, svn_dirent_dirname(local_abspath,
                                                                 scratch_pool),
                                  scratch_pool, scratch_pool);
@@ -1372,6 +1296,9 @@ svn_wc__check_for_obstructions(svn_wc_no
 
       case svn_wc__db_status_excluded:
       case svn_wc__db_status_server_excluded:
+        if (excluded)
+          *excluded = TRUE;
+        /* fall through */
       case svn_wc__db_status_incomplete:
         *obstruction_state = svn_wc_notify_state_missing;
         break;

Modified: subversion/branches/verify-keep-going/subversion/libsvn_wc/props.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_wc/props.c?rev=1445542&r1=1445541&r2=1445542&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_wc/props.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_wc/props.c Wed Feb 13 10:21:33 2013
@@ -349,12 +349,24 @@ svn_wc_merge_props3(svn_wc_notify_state_
     SVN_ERR(svn_wc__wq_run(db, local_abspath, cancel_func, cancel_baton,
                            scratch_pool));
 
+  /* If there is a conflict, try to resolve it. */
   if (conflict_skel && conflict_func)
-    SVN_ERR(svn_wc__conflict_invoke_resolver(db, local_abspath, conflict_skel,
-                                             NULL /* merge_options */,
-                                             conflict_func, conflict_baton,
-                                             cancel_func, cancel_baton,
-                                             scratch_pool));
+    {
+      svn_boolean_t prop_conflicted;
+
+      SVN_ERR(svn_wc__conflict_invoke_resolver(db, local_abspath, conflict_skel,
+                                               NULL /* merge_options */,
+                                               conflict_func, conflict_baton,
+                                               cancel_func, cancel_baton,
+                                               scratch_pool));
+
+      /* Reset *STATE if all prop conflicts were resolved. */
+      SVN_ERR(svn_wc__internal_conflicted_p(
+                NULL, &prop_conflicted, NULL,
+                wc_ctx->db, local_abspath, scratch_pool));
+      if (! prop_conflicted)
+        *state = svn_wc_notify_state_merged;
+    }
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/verify-keep-going/subversion/libsvn_wc/revert.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_wc/revert.c?rev=1445542&r1=1445541&r2=1445542&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_wc/revert.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_wc/revert.c Wed Feb 13 10:21:33 2013
@@ -369,7 +369,7 @@ revert_restore(svn_wc__db_t *db,
       special = FALSE;
 #endif
     }
-  else
+  else if (!err)
     {
       if (finfo.filetype == APR_REG || finfo.filetype == APR_LNK)
         on_disk = svn_node_file;
@@ -382,6 +382,8 @@ revert_restore(svn_wc__db_t *db,
       special = (finfo.filetype == APR_LNK);
 #endif
     }
+  else
+    return svn_error_trace(err);
 
   if (copied_here)
     {

Modified: subversion/branches/verify-keep-going/subversion/libsvn_wc/tree_conflicts.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_wc/tree_conflicts.c?rev=1445542&r1=1445541&r2=1445542&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_wc/tree_conflicts.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_wc/tree_conflicts.c Wed Feb 13 10:21:33 2013
@@ -406,6 +406,12 @@ svn_wc__add_tree_conflict(svn_wc_context
   svn_skel_t *conflict_skel;
   svn_error_t *err;
 
+  SVN_ERR_ASSERT(conflict != NULL);
+  SVN_ERR_ASSERT(conflict->operation == svn_wc_operation_merge
+                 || (conflict->reason != svn_wc_conflict_reason_moved_away
+                     && conflict->reason != svn_wc_conflict_reason_moved_here)
+                );
+
   /* Re-adding an existing tree conflict victim is an error. */
   err = svn_wc__internal_conflicted_p(NULL, NULL, &existing_conflict,
                                       wc_ctx->db, conflict->local_abspath,
@@ -418,7 +424,7 @@ svn_wc__add_tree_conflict(svn_wc_context
       svn_error_clear(err);
     }
   else if (existing_conflict)
-    return svn_error_createf(SVN_ERR_WC_CORRUPT, NULL,
+    return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
                              _("Attempt to add tree conflict that already "
                                "exists at '%s'"),
                              svn_dirent_local_style(conflict->local_abspath,
@@ -432,6 +438,7 @@ svn_wc__add_tree_conflict(svn_wc_context
                                                   conflict->local_abspath,
                                                   conflict->reason,
                                                   conflict->action,
+                                                  NULL,
                                                   scratch_pool, scratch_pool));
 
   switch(conflict->operation)

Modified: subversion/branches/verify-keep-going/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_wc/update_editor.c?rev=1445542&r1=1445541&r2=1445542&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_wc/update_editor.c Wed Feb 13 10:21:33 2013
@@ -284,6 +284,8 @@ remember_skipped_tree(struct edit_baton 
   return SVN_NO_ERROR;
 }
 
+/* Per directory baton. Lives in its own subpool of the parent directory
+   or of the edit baton if there is no parent directory */
 struct dir_baton
 {
   /* Basename of this directory. */
@@ -381,26 +383,10 @@ struct dir_baton
 
   /* The pool in which this baton itself is allocated. */
   apr_pool_t *pool;
-};
-
-
-/* The bump information is tracked separately from the directory batons.
-   This is a small structure kept in the edit pool, while the heavier
-   directory baton is managed by the editor driver.
-
-   In a postfix delta case, the directory batons are going to disappear.
-   The files will refer to these structures, rather than the full
-   directory baton.  */
-struct bump_dir_info
-{
-  /* ptr to the bump information for the parent directory */
-  struct bump_dir_info *parent;
 
-  /* how many entries are referring to this bump information? */
+  /* how many nodes are referring to baton? */
   int ref_count;
 
-  /* Pool that should be cleared after the dir is bumped */
-  apr_pool_t *pool;
 };
 
 
@@ -514,7 +500,6 @@ make_dir_baton(struct dir_baton **d_p,
 {
   apr_pool_t *dir_pool;
   struct dir_baton *d;
-  struct bump_dir_info *bdi;
 
   if (pb != NULL)
     dir_pool = svn_pool_create(pb->pool);
@@ -599,23 +584,13 @@ make_dir_baton(struct dir_baton **d_p,
         }
     }
 
-  /* the bump information lives in the edit pool */
-  bdi = apr_pcalloc(dir_pool, sizeof(*bdi));
-  bdi->parent = pb ? pb->bump_info : NULL;
-  bdi->ref_count = 1;
-  bdi->pool = dir_pool;
-
-  /* the parent's bump info has one more referer */
-  if (pb)
-    ++bdi->parent->ref_count;
-
   d->edit_baton   = eb;
   d->parent_baton = pb;
   d->pool         = dir_pool;
   d->propchanges  = apr_array_make(dir_pool, 1, sizeof(svn_prop_t));
   d->obstruction_found = FALSE;
   d->add_existed  = FALSE;
-  d->bump_info    = bdi;
+  d->ref_count = 1;
   d->old_revision = SVN_INVALID_REVNUM;
   d->adding_dir   = adding;
   d->changed_rev  = SVN_INVALID_REVNUM;
@@ -626,6 +601,9 @@ make_dir_baton(struct dir_baton **d_p,
     {
       d->skip_this = pb->skip_this;
       d->shadowed = pb->shadowed || pb->edit_obstructed;
+
+      /* the parent's bump info has one more referer */
+      pb->ref_count++;
     }
 
   /* The caller of this function needs to fill these in. */
@@ -663,34 +641,32 @@ do_notification(const struct edit_baton 
   (*eb->notify_func)(eb->notify_baton, notify, scratch_pool);
 }
 
-/* Decrement the bump_dir_info's reference count. If it hits zero,
+/* Decrement the directory's reference count. If it hits zero,
    then this directory is "done". This means it is safe to clear its pool.
 
-   In addition, when the directory is "done", we loop onto the parent's
-   bump information to possibly mark it as done, too.
+   In addition, when the directory is "done", we recurse to possible cleanup
+   the parent directory.
 */
 static svn_error_t *
-maybe_release_dir_info(struct bump_dir_info *bdi)
+maybe_release_dir_info(struct dir_baton *db)
 {
-  /* Keep moving up the tree of directories until we run out of parents,
-     or a directory is not yet "done".  */
-  while (bdi != NULL)
-    {
-      apr_pool_t *destroy_pool;
+  db->ref_count--;
 
-      if (--bdi->ref_count > 0)
-        break;  /* directory isn't done yet */
+  if (!db->ref_count)
+    {
+      struct dir_baton *pb = db->parent_baton;
 
-      destroy_pool = bdi->pool;
-      bdi = bdi->parent;
+      svn_pool_destroy(db->pool);
 
-      svn_pool_destroy(destroy_pool);
+      if (pb)
+        SVN_ERR(maybe_release_dir_info(pb));
     }
-  /* we exited the for loop because there are no more parents */
 
   return SVN_NO_ERROR;
 }
 
+/* Per file baton. Lives in its own subpool below the pool of the parent
+   directory */
 struct file_baton
 {
   /* Pool specific to this file_baton. */
@@ -842,8 +818,8 @@ make_file_baton(struct file_baton **f_p,
   f->dir_baton         = pb;
   f->changed_rev       = SVN_INVALID_REVNUM;
 
-  /* the directory's bump info has one more referer now */
-  ++f->bump_info->ref_count;
+  /* the directory has one more referer now */
+  pb->ref_count++;
 
   *f_p = f;
   return SVN_NO_ERROR;
@@ -859,7 +835,7 @@ make_file_baton(struct file_baton **f_p,
  */
 static svn_error_t *
 complete_conflict(svn_skel_t *conflict,
-                  const struct dir_baton *pb,
+                  const struct edit_baton *eb,
                   const char *local_abspath,
                   const char *old_repos_relpath,
                   svn_revnum_t old_revision,
@@ -869,7 +845,6 @@ complete_conflict(svn_skel_t *conflict,
                   apr_pool_t *result_pool,
                   apr_pool_t *scratch_pool)
 {
-  const struct edit_baton *eb = pb->edit_baton;
   svn_wc_conflict_version_t *original_version;
   svn_wc_conflict_version_t *target_version;
   svn_boolean_t is_complete;
@@ -934,7 +909,7 @@ mark_directory_edited(struct dir_baton *
     {
       /* We have a (delayed) tree conflict to install */
 
-      SVN_ERR(complete_conflict(db->edit_conflict, db->parent_baton,
+      SVN_ERR(complete_conflict(db->edit_conflict, db->edit_baton,
                                 db->local_abspath,
                                 db->old_repos_relpath, db->old_revision,
                                 db->new_relpath,
@@ -969,7 +944,7 @@ mark_file_edited(struct file_baton *fb, 
     {
       /* We have a (delayed) tree conflict to install */
 
-      SVN_ERR(complete_conflict(fb->edit_conflict, fb->dir_baton,
+      SVN_ERR(complete_conflict(fb->edit_conflict, fb->edit_baton,
                                 fb->local_abspath, fb->old_repos_relpath,
                                 fb->old_revision, fb->new_relpath,
                                 svn_node_file, svn_node_file,
@@ -1145,6 +1120,15 @@ path_join_under_root(const char **result
                                  pool));
     }
 
+  /* This catches issue #3288 */
+  if (strcmp(add_path, svn_dirent_basename(*result_path, NULL)) != 0)
+    {
+      return svn_error_createf(
+          SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,
+          _("'%s' is not valid as filename in a working copy path"),
+          svn_dirent_local_style(add_path, pool));
+    }
+
   return SVN_NO_ERROR;
 }
 
@@ -1163,6 +1147,17 @@ set_target_revision(void *edit_baton,
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+check_tree_conflict(svn_skel_t **pconflict,
+                    struct edit_baton *eb,
+                    const char *local_abspath,
+                    svn_wc__db_status_t working_status,
+                    svn_boolean_t exists_in_repos,
+                    svn_node_kind_t expected_kind,
+                    svn_wc_conflict_action_t action,
+                    apr_pool_t *result_pool,
+                    apr_pool_t *scratch_pool);
+
 /* An svn_delta_editor_t function. */
 static svn_error_t *
 open_root(void *edit_baton,
@@ -1221,8 +1216,50 @@ open_root(void *edit_baton,
                                db->pool, pool));
 
   if (have_work)
-    db->shadowed = TRUE; /* Needed for the close_directory() on the root, to
-                            make sure it doesn't use the ACTUAL tree */
+    {
+      const char *move_src_root_abspath;
+
+      SVN_ERR(svn_wc__db_base_moved_to(NULL, NULL, &move_src_root_abspath,
+                                       NULL, eb->db, db->local_abspath,
+                                       pool, pool));
+      if (move_src_root_abspath)
+        {
+          /* This is an update anchored inside a move. We need to
+             raise a move-edit tree-conflict on the move root to
+             update the move destination. */
+          svn_skel_t *tree_conflict = svn_wc__conflict_skel_create(pool);
+
+          SVN_ERR(svn_wc__conflict_skel_add_tree_conflict(
+                    tree_conflict, eb->db, move_src_root_abspath,
+                    svn_wc_conflict_reason_moved_away,
+                    svn_wc_conflict_action_edit,
+                    move_src_root_abspath, pool, pool));
+
+          if (strcmp(db->local_abspath, move_src_root_abspath))
+            {
+              /* This is some parent of the edit root, we won't be
+                 handling it again so raise the conflict now. */
+              SVN_ERR(complete_conflict(tree_conflict, eb,
+                                        move_src_root_abspath,
+                                        db->old_repos_relpath,
+                                        db->old_revision, db->new_relpath,
+                                        svn_node_dir, svn_node_dir,
+                                        pool, pool));
+              SVN_ERR(svn_wc__db_op_mark_conflict(eb->db,
+                                                  move_src_root_abspath,
+                                                  tree_conflict,
+                                                  NULL, pool));
+              do_notification(eb, move_src_root_abspath, svn_node_dir,
+                              svn_wc_notify_tree_conflict, pool);
+            }
+          else
+            db->edit_conflict = tree_conflict;
+        }
+
+
+      db->shadowed = TRUE; /* Needed for the close_directory() on the root, to
+                              make sure it doesn't use the ACTUAL tree */
+    }
 
   if (*eb->target_basename == '\0')
     {
@@ -1394,6 +1431,7 @@ check_tree_conflict(svn_skel_t **pconfli
   svn_wc_conflict_reason_t reason = SVN_WC_CONFLICT_REASON_NONE;
   svn_boolean_t modified = FALSE;
   svn_boolean_t all_mods_are_deletes = FALSE;
+  const char *move_src_op_root_abspath = NULL;
 
   *pconflict = NULL;
 
@@ -1431,21 +1469,26 @@ check_tree_conflict(svn_skel_t **pconfli
           }
         else
           {
-            /* The node is locally replaced. */
-            reason = svn_wc_conflict_reason_replaced;
+            /* The node is locally replaced but could also be moved-away. */
+            SVN_ERR(svn_wc__db_base_moved_to(NULL, NULL, NULL,
+                                             &move_src_op_root_abspath,
+                                             eb->db, local_abspath,
+                                             scratch_pool, scratch_pool));
+            if (move_src_op_root_abspath)
+              reason = svn_wc_conflict_reason_moved_away;
+            else
+              reason = svn_wc_conflict_reason_replaced;
           }
         break;
 
 
       case svn_wc__db_status_deleted:
         {
-          const char *moved_to_abspath;
-
-          SVN_ERR(svn_wc__db_scan_deletion(NULL, &moved_to_abspath,
-                                           NULL, NULL, eb->db,
-                                           local_abspath,
+          SVN_ERR(svn_wc__db_base_moved_to(NULL, NULL, NULL,
+                                           &move_src_op_root_abspath,
+                                           eb->db, local_abspath,
                                            scratch_pool, scratch_pool));
-          if (moved_to_abspath)
+          if (move_src_op_root_abspath)
             reason = svn_wc_conflict_reason_moved_away;
           else
             reason = svn_wc_conflict_reason_deleted;
@@ -1560,6 +1603,7 @@ check_tree_conflict(svn_skel_t **pconfli
                                                   eb->db, local_abspath,
                                                   reason,
                                                   action,
+                                                  move_src_op_root_abspath,
                                                   result_pool, scratch_pool));
 
   return SVN_NO_ERROR;
@@ -1795,7 +1839,7 @@ delete_entry(const char *path,
       apr_hash_set(pb->deletion_conflicts, apr_pstrdup(pb->pool, base),
                    APR_HASH_KEY_STRING, tree_conflict);
 
-      SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, NULL,
+      SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, NULL, NULL,
                                                   eb->db, local_abspath,
                                                   tree_conflict,
                                                   scratch_pool, scratch_pool));
@@ -1828,7 +1872,7 @@ delete_entry(const char *path,
         SVN_ERR_MALFUNCTION();  /* other reasons are not expected here */
     }
 
-  SVN_ERR(complete_conflict(tree_conflict, pb, local_abspath, repos_relpath,
+  SVN_ERR(complete_conflict(tree_conflict, eb, local_abspath, repos_relpath,
                             old_revision, NULL,
                             (kind == svn_kind_dir)
                                 ? svn_node_dir
@@ -2051,7 +2095,7 @@ add_directory(const char *path,
           /* ### Should store the conflict in DB to allow reinstalling
              ### with theoretically more data in close_directory() */
 
-          SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, NULL,
+          SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, NULL, NULL,
                                                       eb->db,
                                                       db->local_abspath,
                                                       tree_conflict,
@@ -2063,6 +2107,7 @@ add_directory(const char *path,
                                         tree_conflict,
                                         eb->db, db->local_abspath,
                                         reason, svn_wc_conflict_action_replace,
+                                        NULL,
                                         db->pool, db->pool));
 
           /* And now stop checking for conflicts here and just perform
@@ -2187,14 +2232,14 @@ add_directory(const char *path,
                                         tree_conflict,
                                         eb->db, db->local_abspath,
                                         svn_wc_conflict_reason_unversioned,
-                                        svn_wc_conflict_action_add,
+                                        svn_wc_conflict_action_add, NULL,
                                         db->pool, pool));
           db->edit_conflict = tree_conflict;
         }
     }
 
   if (tree_conflict)
-    SVN_ERR(complete_conflict(tree_conflict, pb, db->local_abspath,
+    SVN_ERR(complete_conflict(tree_conflict, eb, db->local_abspath,
                               db->old_repos_relpath, db->old_revision,
                               db->new_relpath,
                               svn__node_kind_from_kind(wc_kind),
@@ -2356,7 +2401,7 @@ open_directory(const char *path,
       db->edit_conflict = tree_conflict;
       /* Other modifications wouldn't be a tree conflict */
 
-      SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, NULL,
+      SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, NULL, NULL,
                                                   eb->db, db->local_abspath,
                                                   tree_conflict,
                                                   db->pool, db->pool));
@@ -2452,7 +2497,7 @@ close_directory(void *dir_baton,
   if (db->skip_this)
     {
       /* Allow the parent to complete its update. */
-      SVN_ERR(maybe_release_dir_info(db->bump_info));
+      SVN_ERR(maybe_release_dir_info(db));
 
       return SVN_NO_ERROR;
     }
@@ -2770,7 +2815,7 @@ close_directory(void *dir_baton,
           svn_skel_t *work_item;
 
           SVN_ERR(complete_conflict(conflict_skel,
-                                    db->parent_baton,
+                                    db->edit_baton,
                                     db->local_abspath,
                                     db->old_repos_relpath,
                                     db->old_revision,
@@ -2868,7 +2913,7 @@ close_directory(void *dir_baton,
 
   /* We're done with this directory, so remove one reference from the
      bump information. */
-  SVN_ERR(maybe_release_dir_info(db->bump_info));
+  SVN_ERR(maybe_release_dir_info(db));
 
   return SVN_NO_ERROR;
 }
@@ -3136,7 +3181,7 @@ add_file(const char *path,
           /* ### Should store the conflict in DB to allow reinstalling
              ### with theoretically more data in close_directory() */
 
-          SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, NULL,
+          SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, NULL, NULL,
                                                       eb->db,
                                                       fb->local_abspath,
                                                       tree_conflict,
@@ -3148,6 +3193,7 @@ add_file(const char *path,
                                         tree_conflict,
                                         eb->db, fb->local_abspath,
                                         reason, svn_wc_conflict_action_replace,
+                                        NULL,
                                         fb->pool, fb->pool));
 
           /* And now stop checking for conflicts here and just perform
@@ -3270,6 +3316,7 @@ add_file(const char *path,
                                         eb->db, fb->local_abspath,
                                         svn_wc_conflict_reason_unversioned,
                                         svn_wc_conflict_action_add,
+                                        NULL,
                                         fb->pool, scratch_pool));
         }
     }
@@ -3288,7 +3335,7 @@ add_file(const char *path,
   if (tree_conflict != NULL)
     {
       SVN_ERR(complete_conflict(tree_conflict,
-                                fb->dir_baton,
+                                fb->edit_baton,
                                 fb->local_abspath,
                                 fb->old_repos_relpath,
                                 fb->old_revision,
@@ -3419,7 +3466,7 @@ open_file(const char *path,
       fb->edit_conflict = tree_conflict;
       /* Other modifications wouldn't be a tree conflict */
 
-      SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, NULL,
+      SVN_ERR(svn_wc__conflict_read_tree_conflict(&reason, NULL, NULL,
                                                   eb->db, fb->local_abspath,
                                                   tree_conflict,
                                                   scratch_pool, scratch_pool));
@@ -3655,9 +3702,10 @@ change_file_prop(void *file_baton,
                                      eb->db, fb->local_abspath,
                                      svn_wc_conflict_reason_edited,
                                      svn_wc_conflict_action_replace,
+                                     NULL,
                                      fb->pool, scratch_pool));
 
-          SVN_ERR(complete_conflict(fb->edit_conflict, fb->dir_baton,
+          SVN_ERR(complete_conflict(fb->edit_conflict, fb->edit_baton,
                                     fb->local_abspath, fb->old_repos_relpath,
                                     fb->old_revision, fb->new_relpath,
                                     svn_node_file, svn_node_file,
@@ -4040,6 +4088,7 @@ close_file(void *file_baton,
            apr_pool_t *pool)
 {
   struct file_baton *fb = file_baton;
+  struct dir_baton *pdb = fb->dir_baton;
   struct edit_baton *eb = fb->edit_baton;
   svn_wc_notify_state_t content_state, prop_state;
   svn_wc_notify_lock_state_t lock_state;
@@ -4062,8 +4111,8 @@ close_file(void *file_baton,
 
   if (fb->skip_this)
     {
-      SVN_ERR(maybe_release_dir_info(fb->bump_info));
       svn_pool_destroy(fb->pool);
+      SVN_ERR(maybe_release_dir_info(pdb));
       return SVN_NO_ERROR;
     }
 
@@ -4245,8 +4294,8 @@ close_file(void *file_baton,
                                             scratch_pool));
               fb->skip_this = TRUE;
 
-              SVN_ERR(maybe_release_dir_info(fb->bump_info));
               svn_pool_destroy(fb->pool);
+              SVN_ERR(maybe_release_dir_info(pdb));
               return SVN_NO_ERROR;
             }
           else
@@ -4367,7 +4416,7 @@ close_file(void *file_baton,
   if (conflict_skel)
     {
       SVN_ERR(complete_conflict(conflict_skel,
-                                fb->dir_baton,
+                                fb->edit_baton,
                                 fb->local_abspath,
                                 fb->old_repos_relpath,
                                 fb->old_revision,
@@ -4488,11 +4537,11 @@ close_file(void *file_baton,
       eb->notify_func(eb->notify_baton, notify, scratch_pool);
     }
 
-  /* We have one less referrer to the directory's bump information. */
-  SVN_ERR(maybe_release_dir_info(fb->bump_info));
-
   svn_pool_destroy(fb->pool); /* Destroy scratch_pool */
 
+  /* We have one less referrer to the directory */
+  SVN_ERR(maybe_release_dir_info(pdb));
+
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/verify-keep-going/subversion/libsvn_wc/upgrade.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_wc/upgrade.c?rev=1445542&r1=1445541&r2=1445542&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_wc/upgrade.c (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_wc/upgrade.c Wed Feb 13 10:21:33 2013
@@ -1457,6 +1457,7 @@ svn_wc__upgrade_conflict_skel_from_raw(s
                                                       db, wri_abspath,
                                                       tc->reason,
                                                       tc->action,
+                                                      NULL,
                                                       scratch_pool,
                                                       scratch_pool));
 
@@ -1497,6 +1498,51 @@ svn_wc__upgrade_conflict_skel_from_raw(s
   return SVN_NO_ERROR;
 }
 
+/* Helper function to upgrade a single conflict from bump_to_30 */
+static svn_error_t *
+bump_30_upgrade_one_conflict(svn_wc__db_t *wc_db,
+                             const char *wcroot_abspath,
+                             svn_sqlite__stmt_t *stmt,
+                             svn_sqlite__db_t *sdb,
+                             apr_pool_t *scratch_pool)
+{
+  svn_sqlite__stmt_t *stmt_store;
+  svn_stringbuf_t *skel_data;
+  svn_skel_t *conflict_data;
+  apr_int64_t wc_id = svn_sqlite__column_int64(stmt, 0);
+  const char *local_relpath = svn_sqlite__column_text(stmt, 1, NULL);
+  const char *conflict_old = svn_sqlite__column_text(stmt, 2, NULL);
+  const char *conflict_wrk = svn_sqlite__column_text(stmt, 3, NULL);
+  const char *conflict_new = svn_sqlite__column_text(stmt, 4, NULL);
+  const char *prop_reject = svn_sqlite__column_text(stmt, 5, NULL);
+  apr_size_t tree_conflict_size;
+  const char *tree_conflict_data = svn_sqlite__column_blob(stmt, 6,
+                                           &tree_conflict_size, NULL);
+
+  SVN_ERR(svn_wc__upgrade_conflict_skel_from_raw(&conflict_data,
+                                                 wc_db, wcroot_abspath,
+                                                 local_relpath,
+                                                 conflict_old,
+                                                 conflict_wrk,
+                                                 conflict_new,
+                                                 prop_reject,
+                                                 tree_conflict_data,
+                                                 tree_conflict_size,
+                                                 scratch_pool, scratch_pool));
+
+  SVN_ERR_ASSERT(conflict_data != NULL);
+
+  skel_data = svn_skel__unparse(conflict_data, scratch_pool);
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt_store, sdb,
+                                    STMT_UPGRADE_30_SET_CONFLICT));
+  SVN_ERR(svn_sqlite__bindf(stmt_store, "isb", wc_id, local_relpath,
+                            skel_data->data, skel_data->len));
+  SVN_ERR(svn_sqlite__step_done(stmt_store));
+
+  return SVN_NO_ERROR;
+}
+
 static svn_error_t *
 bump_to_30(void *baton, svn_sqlite__db_t *sdb, apr_pool_t *scratch_pool)
 {
@@ -1505,9 +1551,8 @@ bump_to_30(void *baton, svn_sqlite__db_t
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
   svn_sqlite__stmt_t *stmt;
   svn_wc__db_t *db; /* Read only temp db */
-  const char *wri_abspath = bb->wcroot_abspath;
 
-  SVN_ERR(svn_wc__db_open(&db, NULL, FALSE, FALSE,
+  SVN_ERR(svn_wc__db_open(&db, NULL, TRUE /* open_without_upgrade */, FALSE,
                           scratch_pool, scratch_pool));
 
   SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
@@ -1516,41 +1561,19 @@ bump_to_30(void *baton, svn_sqlite__db_t
 
   while (have_row)
     {
-      svn_sqlite__stmt_t *stmt_store;
-      svn_stringbuf_t *skel_data;
-      svn_skel_t *conflict_data;
-      apr_int64_t wc_id = svn_sqlite__column_int64(stmt, 0);
-      const char *local_relpath = svn_sqlite__column_text(stmt, 1, NULL);
-      const char *conflict_old = svn_sqlite__column_text(stmt, 2, NULL);
-      const char *conflict_wrk = svn_sqlite__column_text(stmt, 3, NULL);
-      const char *conflict_new = svn_sqlite__column_text(stmt, 4, NULL);
-      const char *prop_reject = svn_sqlite__column_text(stmt, 5, NULL);
-      apr_size_t tree_conflict_size;
-      const char *tree_conflict_data = svn_sqlite__column_blob(stmt, 6,
-                                               &tree_conflict_size, NULL);
-
+      svn_error_t *err;
       svn_pool_clear(iterpool);
 
-      SVN_ERR(svn_wc__upgrade_conflict_skel_from_raw(&conflict_data,
-                                                     db, wri_abspath,
-                                                     local_relpath,
-                                                     conflict_old,
-                                                     conflict_wrk,
-                                                     conflict_new,
-                                                     prop_reject,
-                                                     tree_conflict_data,
-                                                     tree_conflict_size,
-                                                     iterpool, iterpool));
-
-      SVN_ERR_ASSERT(conflict_data != NULL);
-
-      skel_data = svn_skel__unparse(conflict_data, iterpool);
-
-      SVN_ERR(svn_sqlite__get_statement(&stmt_store, sdb,
-                                        STMT_UPGRADE_30_SET_CONFLICT));
-      SVN_ERR(svn_sqlite__bindf(stmt_store, "isb", wc_id, local_relpath,
-                                skel_data->data, skel_data->len));
-      SVN_ERR(svn_sqlite__step_done(stmt_store));
+      err = bump_30_upgrade_one_conflict(db, bb->wcroot_abspath, stmt, sdb,
+                                         iterpool);
+
+      if (err)
+        {
+          return svn_error_trace(
+                    svn_error_compose_create(
+                            err,
+                            svn_sqlite__reset(stmt)));
+        }
 
       SVN_ERR(svn_sqlite__step(&have_row, stmt));
     }
@@ -2133,17 +2156,21 @@ svn_wc_upgrade(svn_wc_context_t *wc_ctx,
   SVN_ERR(svn_wc__db_open(&db, NULL /* ### config */, TRUE, FALSE,
                           scratch_pool, scratch_pool));
 
+
   err = svn_wc__db_bump_format(&result_format, local_abspath, db,
                                scratch_pool);
   if (err)
     {
-      if (err->apr_err == SVN_ERR_WC_UPGRADE_REQUIRED) /* pre-1.7 WC */
+      if (err->apr_err != SVN_ERR_WC_UPGRADE_REQUIRED)
         {
-          svn_error_clear(err);
-          SVN_ERR(svn_wc__db_close(db));
+          return svn_error_trace(
+                    svn_error_compose_create(
+                            err,
+                            svn_wc__db_close(db)));
         }
-      else
-        return svn_error_trace(err);
+
+      svn_error_clear(err);
+      /* Pre 1.7: Fall through */
     }
   else
     {
@@ -2166,10 +2193,6 @@ svn_wc_upgrade(svn_wc_context_t *wc_ctx,
      'cleanup' with a new client will complete any outstanding
      upgrade. */
 
-  SVN_ERR(svn_wc__db_open(&db,
-                          NULL /* ### config */, TRUE, FALSE,
-                          scratch_pool, scratch_pool));
-
   SVN_ERR(svn_wc__read_entries_old(&entries, local_abspath,
                                    scratch_pool, scratch_pool));
 

Modified: subversion/branches/verify-keep-going/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_wc/wc-queries.sql?rev=1445542&r1=1445541&r2=1445542&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_wc/wc-queries.sql Wed Feb 13 10:21:33 2013
@@ -29,7 +29,8 @@
 -- STMT_SELECT_NODE_INFO
 SELECT op_depth, repos_id, repos_path, presence, kind, revision, checksum,
   translated_size, changed_revision, changed_date, changed_author, depth,
-  symlink_target, last_mod_time, properties, moved_here, inherited_props
+  symlink_target, last_mod_time, properties, moved_here, inherited_props,
+  moved_to
 FROM nodes
 WHERE wc_id = ?1 AND local_relpath = ?2
 ORDER BY op_depth DESC
@@ -96,12 +97,19 @@ FROM nodes
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?3
 
 -- STMT_SELECT_LOWEST_WORKING_NODE
-SELECT op_depth, presence, kind
+SELECT op_depth, presence, kind, moved_to
 FROM nodes
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > ?3
 ORDER BY op_depth
 LIMIT 1
 
+-- STMT_SELECT_HIGHEST_WORKING_NODE
+SELECT op_depth
+FROM nodes
+WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth < ?3
+ORDER BY op_depth DESC
+LIMIT 1
+
 -- STMT_SELECT_ACTUAL_NODE
 SELECT changelist, properties, conflict_data
 FROM actual_node
@@ -271,13 +279,18 @@ SELECT local_relpath, kind FROM nodes
 WHERE wc_id = ?1 AND parent_relpath = ?2 AND op_depth = ?3
   AND (?3 != 0 OR file_external is NULL)
 
+/* Used by non-recursive revert to detect higher level children, and
+   actual-only rows that would be left orphans, if the revert
+   proceeded. */
 -- STMT_SELECT_GE_OP_DEPTH_CHILDREN
 SELECT 1 FROM nodes
 WHERE wc_id = ?1 AND parent_relpath = ?2
   AND (op_depth > ?3 OR (op_depth = ?3 AND presence != MAP_BASE_DELETED))
 UNION ALL
-SELECT 1 FROM ACTUAL_NODE
+SELECT 1 FROM ACTUAL_NODE a
 WHERE wc_id = ?1 AND parent_relpath = ?2
+  AND NOT EXISTS (SELECT 1 FROM nodes n
+                   WHERE wc_id = ?1 AND n.local_relpath = a.local_relpath)
 
 /* Delete the nodes shadowed by local_relpath. Not valid for the wc-root */
 -- STMT_DELETE_SHADOWED_RECURSIVE
@@ -287,6 +300,11 @@ WHERE wc_id = ?1
   AND (op_depth < ?3
        OR (op_depth = ?3 AND presence = MAP_BASE_DELETED))
 
+-- STMT_CLEAR_MOVED_TO_FROM_DEST
+UPDATE NODES SET moved_to = NULL
+WHERE wc_id = ?1
+  AND moved_to = ?2
+
 /* Get not-present descendants of a copied node. Not valid for the wc-root */
 -- STMT_SELECT_NOT_PRESENT_DESCENDANTS
 SELECT local_relpath FROM nodes
@@ -294,13 +312,21 @@ WHERE wc_id = ?1 AND op_depth = ?3
   AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
   AND presence = MAP_NOT_PRESENT
 
--- STMT_COMMIT_DESCENDANT_TO_BASE
-UPDATE NODES SET op_depth = 0, repos_id = ?4, repos_path = ?5, revision = ?6,
-  moved_here = NULL, moved_to = NULL, dav_cache = NULL,
-  presence = CASE presence WHEN MAP_NORMAL THEN MAP_NORMAL
-                           WHEN MAP_EXCLUDED THEN MAP_EXCLUDED
-                           ELSE MAP_NOT_PRESENT END
-WHERE wc_id = ?1 AND local_relpath = ?2 and op_depth = ?3
+-- STMT_COMMIT_DESCENDANTS_TO_BASE
+UPDATE NODES SET op_depth = 0,
+                 repos_id = ?4,
+                 repos_path = ?5 || SUBSTR(local_relpath, LENGTH(?2)+1),
+                 revision = ?6,
+                 dav_cache = NULL,
+                 moved_here = NULL,
+                 presence = CASE presence
+                              WHEN MAP_NORMAL THEN MAP_NORMAL
+                              WHEN MAP_EXCLUDED THEN MAP_EXCLUDED
+                              ELSE MAP_NOT_PRESENT
+                            END
+WHERE wc_id = ?1
+  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
+  AND op_depth = ?3
 
 -- STMT_SELECT_NODE_CHILDREN
 /* Return all paths that are children of the directory (?1, ?2) in any
@@ -1315,6 +1341,30 @@ ORDER BY local_relpath
 -- STMT_FINALIZE_DELETE
 DROP TABLE IF EXISTS delete_list
 
+-- STMT_CREATE_UPDATE_MOVE_LIST
+DROP TABLE IF EXISTS update_move_list;
+CREATE TEMPORARY TABLE update_move_list (
+/* ### we should put the wc_id in here in case a move update spans multiple
+   ### working copies. queries, etc will need to be adjusted.  */
+  local_relpath TEXT PRIMARY KEY NOT NULL UNIQUE,
+  action INTEGER NOT NULL,
+  kind  INTEGER NOT NULL,
+  content_state INTEGER NOT NULL,
+  prop_state  INTEGER NOT NULL
+  )
+
+-- STMT_INSERT_UPDATE_MOVE_LIST
+INSERT INTO update_move_list(local_relpath, action, kind, content_state,
+  prop_state)
+VALUES (?1, ?2, ?3, ?4, ?5)
+
+-- STMT_SELECT_UPDATE_MOVE_LIST
+SELECT local_relpath, action, kind, content_state, prop_state
+FROM update_move_list
+ORDER BY local_relpath
+
+-- STMT_FINALIZE_UPDATE_MOVE
+DROP TABLE IF EXISTS update_move_list
 
 /* ------------------------------------------------------------------------- */
 
@@ -1484,10 +1534,65 @@ WHERE wc_id = ?1
   AND op_depth > ?3
   AND moved_to IS NOT NULL
 
+-- STMT_SELECT_MOVED_OUTSIDE
+SELECT local_relpath FROM nodes
+WHERE wc_id = ?1
+  AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
+  AND op_depth >= ?3
+  AND moved_to IS NOT NULL
+  AND NOT IS_STRICT_DESCENDANT_OF(moved_to, ?2)
+
+-- STMT_SELECT_OP_DEPTH_MOVED_PAIR
+SELECT n.local_relpath, n.moved_to,
+       (SELECT o.repos_path FROM nodes AS o
+        WHERE o.wc_id = n.wc_id
+          AND o.local_relpath = n.local_relpath
+          AND o.op_depth < ?3 ORDER BY o.op_depth DESC LIMIT 1)
+FROM nodes AS n
+WHERE n.wc_id = ?1
+  AND IS_STRICT_DESCENDANT_OF(n.local_relpath, ?2)
+  AND n.op_depth = ?3
+  AND n.moved_to IS NOT NULL
+
+-- STMT_SELECT_MOVED_DESCENDANTS
+SELECT n.local_relpath, h.moved_to
+FROM nodes n, nodes h
+WHERE n.wc_id = ?1
+  AND h.wc_id = ?1
+  AND IS_STRICT_DESCENDANT_OF(n.local_relpath, ?2)
+  AND h.local_relpath = n.local_relpath
+  AND n.op_depth = ?3
+  AND h.op_depth = (SELECT MIN(o.op_depth)
+                    FROM nodes o
+                    WHERE o.wc_id = ?1
+                      AND o.local_relpath = n.local_relpath
+                      AND o.op_depth > ?3)
+  AND h.moved_to IS NOT NULL
+
+-- STMT_COMMIT_UPDATE_ORIGIN
+/* Note that the only reason this SUBSTR() trick is valid is that you
+   can move neither the working copy nor the repository root.
+
+   SUBSTR(local_relpath, LENGTH(?2)+1) includes the '/' of the path */
+UPDATE nodes SET repos_id = ?4,
+                 repos_path = ?5 || SUBSTR(local_relpath, LENGTH(?2)+1),
+                 revision = ?6
+WHERE wc_id = ?1
+  AND (local_relpath = ?2
+       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
+  AND op_depth = ?3
+
 -- STMT_HAS_LAYER_BETWEEN
 SELECT 1 FROM NODES
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > ?3 AND op_depth < ?4
 
+-- STMT_SELECT_REPOS_PATH_REVISION
+SELECT local_relpath, repos_path, revision FROM nodes
+WHERE wc_id = ?1
+  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
+  AND op_depth = 0
+ORDER BY local_relpath
+
 /* ------------------------------------------------------------------------- */
 
 /* Queries for verification. */

Modified: subversion/branches/verify-keep-going/subversion/libsvn_wc/wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/libsvn_wc/wc.h?rev=1445542&r1=1445541&r2=1445542&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/libsvn_wc/wc.h (original)
+++ subversion/branches/verify-keep-going/subversion/libsvn_wc/wc.h Wed Feb 13 10:21:33 2013
@@ -615,21 +615,15 @@ svn_wc__internal_get_origin(svn_boolean_
 
 /* Internal version of svn_wc__node_get_repos_info() */
 svn_error_t *
-svn_wc__internal_get_repos_info(const char **repos_root_url,
+svn_wc__internal_get_repos_info(svn_revnum_t *revision,
+                                const char **repos_relpath,
+                                const char **repos_root_url,
                                 const char **repos_uuid,
                                 svn_wc__db_t *db,
                                 const char *local_abspath,
                                 apr_pool_t *result_pool,
                                 apr_pool_t *scratch_pool);
 
-/* Internal version of svn_wc__node_get_repos_relpath() */
-svn_error_t *
-svn_wc__internal_get_repos_relpath(const char **repos_relpath,
-                                   svn_wc__db_t *db,
-                                   const char *local_abspath,
-                                   apr_pool_t *result_pool,
-                                   apr_pool_t *scratch_pool);
-
 /* Upgrade the wc sqlite database given in SDB for the wc located at
    WCROOT_ABSPATH. It's current/starting format is given by START_FORMAT.
    After the upgrade is complete (to as far as the automatic upgrade will