You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2011/10/19 12:33:21 UTC

svn commit: r1186075 [2/2] - in /subversion/branches/showing-merge-info: ./ subversion/bindings/javahl/native/ subversion/bindings/javahl/src/org/tigris/subversion/javahl/ subversion/bindings/swig/ subversion/include/ subversion/include/private/ subver...

Modified: subversion/branches/showing-merge-info/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_wc/update_editor.c?rev=1186075&r1=1186074&r2=1186075&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_wc/update_editor.c Wed Oct 19 10:33:19 2011
@@ -35,6 +35,7 @@
 #include "svn_types.h"
 #include "svn_pools.h"
 #include "svn_delta.h"
+#include "svn_hash.h"
 #include "svn_string.h"
 #include "svn_dirent_uri.h"
 #include "svn_path.h"
@@ -283,6 +284,13 @@ struct dir_baton
   /* Absolute path of this directory */
   const char *local_abspath;
 
+  /* Absolute path to the new location of the directory if it was moved away,
+   * and the op-root of the move operation.
+   * This is set on the root of a move operation and all children.
+   * If the directory was not moved away, this is NULL. */
+  const char *moved_to_abspath;
+  const char *moved_to_op_root_abspath;
+
   /* The repository relative path this directory will correspond to. */
   const char *new_relpath;
 
@@ -617,6 +625,8 @@ make_dir_baton(struct dir_baton **d_p,
   d->adding_dir   = adding;
   d->changed_rev  = SVN_INVALID_REVNUM;
   d->not_present_files = apr_hash_make(dir_pool);
+  d->moved_to_abspath = NULL;
+  d->moved_to_op_root_abspath = NULL;
 
   /* Copy some flags from the parent baton */
   if (pb)
@@ -1083,6 +1093,7 @@ open_root(void *edit_baton,
   struct dir_baton *db;
   svn_boolean_t already_conflicted;
   svn_error_t *err;
+  svn_wc__db_status_t status;
 
   /* Note that something interesting is actually happening in this
      edit run. */
@@ -1118,7 +1129,6 @@ open_root(void *edit_baton,
   if (*eb->target_basename == '\0')
     {
       /* For an update with a NULL target, this is equivalent to open_dir(): */
-      svn_wc__db_status_t status;
 
       /* Read the depth from the entry. */
       SVN_ERR(svn_wc__db_base_get_info(&status, NULL, NULL, NULL, NULL, NULL,
@@ -1136,6 +1146,25 @@ open_root(void *edit_baton,
                                                         pool));
     }
 
+  /* Check if this directory was moved away. */
+  err = svn_wc__db_read_info(&status, NULL, NULL, NULL, NULL, NULL, NULL,
+                             NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                             NULL, NULL, NULL, NULL, NULL, NULL,
+                             NULL, NULL, NULL, NULL,
+                             NULL, NULL, NULL,
+                             eb->db, db->local_abspath, pool, pool);
+  if (err)
+    {
+      if (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+        svn_error_clear(err);
+      else
+        return svn_error_trace(err);
+    }
+  else if (status == svn_wc__db_status_deleted)
+    SVN_ERR(svn_wc__db_scan_deletion(NULL, &db->moved_to_abspath, NULL,
+                                     &db->moved_to_op_root_abspath,
+                                     eb->db, db->local_abspath, db->pool, pool));
+
   return SVN_NO_ERROR;
 }
 
@@ -1148,6 +1177,7 @@ typedef struct modcheck_baton_t {
   svn_wc__db_t *db;         /* wc_db to access nodes */
   svn_boolean_t found_mod;  /* whether a modification has been found */
   svn_boolean_t found_not_delete;  /* Found a not-delete modification */
+  svn_boolean_t is_copy; /* check for post-copy modifications only */
 } modcheck_baton_t;
 
 /* An implementation of svn_wc_status_func4_t. */
@@ -1178,8 +1208,17 @@ modcheck_callback(void *baton,
           break;
         /* Fall through in the found modification case */
 
-      default:
       case svn_wc_status_added:
+        if (!mb->is_copy)
+          {
+            mb->found_mod = TRUE;
+            mb->found_not_delete = TRUE;
+            /* Exit from the status walker: We know what we want to know */
+            return svn_error_create(SVN_ERR_CEASE_INVOCATION, NULL, NULL);
+          }
+        break;
+
+      default:
       case svn_wc_status_replaced:
       case svn_wc_status_modified:
         mb->found_mod = TRUE;
@@ -1196,20 +1235,24 @@ modcheck_callback(void *baton,
  * tree rooted at LOCAL_ABSPATH, using DB. If *MODIFIED
  * is set to true and all the local modifications were deletes then set
  * *ALL_EDITS_ARE_DELETES to true, set it to false otherwise.  LOCAL_ABSPATH
- * may be a file or a directory. */
+ * may be a file or a directory. If IS_COPY is TRUE, LOCAL_ABSPATH is a
+ * copied (or moved) node, and nodes at or within LOCAL_ABSPATH are only
+ * considered modified if they were modified post-copy. */
 static svn_error_t *
 node_has_local_mods(svn_boolean_t *modified,
                     svn_boolean_t *all_edits_are_deletes,
+                    svn_boolean_t is_copy,
                     svn_wc__db_t *db,
                     const char *local_abspath,
                     svn_cancel_func_t cancel_func,
                     void *cancel_baton,
                     apr_pool_t *scratch_pool)
 {
-  modcheck_baton_t modcheck_baton = { NULL, FALSE, FALSE };
+  modcheck_baton_t modcheck_baton = { NULL, FALSE, FALSE, FALSE };
   svn_error_t *err;
 
   modcheck_baton.db = db;
+  modcheck_baton.is_copy = is_copy;
 
   /* Walk the WC tree for status with depth infinity, looking for any local
    * modifications. If it's a "sparse" directory, that's OK: there can be
@@ -1332,6 +1375,7 @@ create_tree_conflict(svn_wc_conflict_des
       SVN_ERR_ASSERT(reason == svn_wc_conflict_reason_edited
                      || reason == svn_wc_conflict_reason_deleted
                      || reason == svn_wc_conflict_reason_moved_away
+                     || reason == svn_wc_conflict_reason_moved_away_and_edited
                      || reason == svn_wc_conflict_reason_replaced
                      || reason == svn_wc_conflict_reason_obstructed);
 
@@ -1527,6 +1571,26 @@ check_tree_conflict(svn_wc_conflict_desc
       case svn_wc__db_status_deleted:
         if (!moved_to_abspath)
           reason = svn_wc_conflict_reason_deleted;
+        else if (action == svn_wc_conflict_action_delete)
+          {
+            svn_boolean_t all_edits_are_deletes = FALSE;
+
+            /* The update wants to delete a node which was locally moved
+             * away. We allow this only if the node wasn't modified post-move.
+             * If the only post-move changes within a subtree are deletions,
+             * allow the update to delete the entire subtree. */
+            if (working_kind == svn_kind_dir)
+              SVN_ERR(node_has_local_mods(&modified, &all_edits_are_deletes,
+                                          TRUE, eb->db, moved_to_abspath,
+                                          eb->cancel_func, eb->cancel_baton,
+                                          scratch_pool));
+            else
+              SVN_ERR(svn_wc__internal_file_modified_p(&modified, eb->db,
+                                                       moved_to_abspath,
+                                                       FALSE, scratch_pool));
+            if (modified && !all_edits_are_deletes)
+              reason = svn_wc_conflict_reason_moved_away_and_edited;
+          }
         break;
 
       case svn_wc__db_status_incomplete:
@@ -1551,7 +1615,7 @@ check_tree_conflict(svn_wc_conflict_desc
          * not visit the subdirectories of a directory that it wants to delete.
          * Therefore, we need to start a separate crawl here. */
 
-        SVN_ERR(node_has_local_mods(&modified, &all_mods_are_deletes,
+        SVN_ERR(node_has_local_mods(&modified, &all_mods_are_deletes, FALSE,
                                     eb->db, local_abspath,
                                     eb->cancel_func, eb->cancel_baton,
                                     scratch_pool));
@@ -1592,6 +1656,7 @@ check_tree_conflict(svn_wc_conflict_desc
   if (reason == svn_wc_conflict_reason_edited
       || reason == svn_wc_conflict_reason_deleted
       || reason == svn_wc_conflict_reason_moved_away
+      || reason == svn_wc_conflict_reason_moved_away_and_edited
       || reason == svn_wc_conflict_reason_replaced)
     /* When the node existed before (it was locally deleted, replaced or
      * edited), then 'update' cannot add it "again". So it can only send
@@ -1706,6 +1771,7 @@ delete_entry(const char *path,
   const char *base = svn_relpath_basename(path, NULL);
   const char *local_abspath;
   const char *repos_relpath;
+  const char *moved_to_abspath = NULL;
   svn_kind_t kind, base_kind;
   svn_boolean_t conflicted;
   svn_boolean_t have_base;
@@ -1805,6 +1871,13 @@ delete_entry(const char *path,
       return SVN_NO_ERROR;
     }
 
+  /* Has the to-be-deleted node been moved away? */
+  if (status == svn_wc__db_status_deleted)
+    SVN_ERR(svn_wc__db_scan_deletion(NULL, &moved_to_abspath, NULL,
+                                     NULL, eb->db, local_abspath,
+                                     pool, pool));
+
+
   /* Is this path the victim of a newly-discovered tree conflict?  If so,
    * remember it and notify the client. Then (if it was existing and
    * modified), re-schedule the node to be added back again, as a (modified)
@@ -1817,7 +1890,8 @@ delete_entry(const char *path,
       SVN_ERR(check_tree_conflict(&tree_conflict, eb, local_abspath,
                                   status, kind, TRUE,
                                   svn_wc_conflict_action_delete, svn_node_none,
-                                  repos_relpath, NULL, pb->pool, scratch_pool));
+                                  repos_relpath, moved_to_abspath,
+                                  pb->pool, scratch_pool));
     }
 
   if (tree_conflict != NULL)
@@ -1856,6 +1930,8 @@ delete_entry(const char *path,
         }
       else if (tree_conflict->reason == svn_wc_conflict_reason_deleted
                || tree_conflict->reason == svn_wc_conflict_reason_moved_away
+               || tree_conflict->reason ==
+                     svn_wc_conflict_reason_moved_away_and_edited
                || tree_conflict->reason == svn_wc_conflict_reason_replaced)
         {
           /* The item does not exist locally because it was already shadowed.
@@ -1867,6 +1943,23 @@ delete_entry(const char *path,
       else
         SVN_ERR_MALFUNCTION();  /* other reasons are not expected here */
     }
+  else if (moved_to_abspath)
+    {
+      /* No tree conflict was flagged, and the node was moved-away.
+       * Automatically merge the incoming deletion with the local move
+       * by deleting the node from the moved-away subtree. */
+      /* ### This should probably use a work queue. */
+      SVN_ERR(svn_wc__db_op_delete(eb->db, moved_to_abspath, NULL,
+                                   NULL, NULL, /* notify below */
+                                   eb->cancel_func, eb->cancel_baton,
+                                   scratch_pool));
+      if (kind == svn_kind_dir)
+        SVN_ERR(svn_io_remove_dir2(moved_to_abspath, TRUE,
+                                   eb->cancel_func, eb->cancel_baton,
+                                   scratch_pool));
+      else
+        SVN_ERR(svn_io_remove_file2(moved_to_abspath, TRUE, scratch_pool));
+    }
 
   /* Issue a wq operation to delete the BASE_NODE data and to delete actual
      nodes based on that from disk, but leave any WORKING_NODEs on disk.
@@ -1917,7 +2010,8 @@ delete_entry(const char *path,
       else
         node_kind = svn_node_file;
 
-      do_notification(eb, local_abspath, node_kind, action, scratch_pool);
+      do_notification(eb, moved_to_abspath ? moved_to_abspath : local_abspath,
+                      node_kind, action, scratch_pool);
     }
 
   svn_pool_destroy(scratch_pool);
@@ -2216,8 +2310,8 @@ add_directory(const char *path,
                                                        pool));
 
   /* Make sure there is a real directory at LOCAL_ABSPATH, unless we are just
-     updating the DB */
-  if (!db->shadowed)
+     updating the DB or the parent was moved away. */
+  if (!db->shadowed && !pb->moved_to_abspath)
     SVN_ERR(svn_wc__ensure_directory(db->local_abspath, pool));
 
   if (!db->shadowed && status == svn_wc__db_status_added)
@@ -2245,6 +2339,16 @@ add_directory(const char *path,
       do_notification(eb, db->local_abspath, svn_node_dir,
                       svn_wc_notify_tree_conflict, pool);
     }
+  else if (wc_kind == svn_kind_unknown &&
+           versioned_locally_and_present == FALSE &&
+           pb->moved_to_abspath)
+    {
+      /* The parent directory of the directory we're adding was moved.
+       * Add the new directory at the new location. */
+      db->moved_to_abspath = svn_dirent_join(pb->moved_to_abspath,
+                                             db->name, db->pool);
+      db->moved_to_op_root_abspath = pb->moved_to_op_root_abspath;
+    }
 
 
 
@@ -2266,7 +2370,9 @@ add_directory(const char *path,
 
       db->already_notified = TRUE;
 
-      do_notification(eb, db->local_abspath, svn_node_dir, action, pool);
+      do_notification(eb, db->moved_to_abspath ? db->moved_to_abspath
+                                               : db->local_abspath,
+                      svn_node_dir, action, pool);
     }
 
   return SVN_NO_ERROR;
@@ -2287,6 +2393,7 @@ open_directory(const char *path,
   svn_wc_conflict_description2_t *tree_conflict = NULL;
   svn_wc__db_status_t status, base_status;
   svn_kind_t wc_kind;
+  svn_error_t *err;
 
   SVN_ERR(make_dir_baton(&db, path, eb, pb, FALSE, pool));
   *child_baton = db;
@@ -2361,13 +2468,34 @@ open_directory(const char *path,
   /* Is this path a fresh tree conflict victim?  If so, skip the tree
      with one notification. */
 
+  /* Check if this directory was moved away. */
+  err = svn_wc__db_read_info(&status, NULL, NULL, NULL, NULL, NULL, NULL,
+                             NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                             NULL, NULL, NULL, NULL, NULL, NULL,
+                             NULL, NULL, NULL, NULL,
+                             NULL, NULL, NULL,
+                             eb->db, db->local_abspath, pool, pool);
+  if (err)
+    {
+      if (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+        svn_error_clear(err);
+      else
+        return svn_error_trace(err);
+    }
+  else if (status == svn_wc__db_status_deleted)
+    SVN_ERR(svn_wc__db_scan_deletion(NULL, &db->moved_to_abspath, NULL,
+                                     &db->moved_to_op_root_abspath,
+                                     eb->db, db->local_abspath,
+                                     db->pool, pool));
+
   /* Check for conflicts only when we haven't already recorded
    * a tree-conflict on a parent node. */
   if (!db->shadowed)
     SVN_ERR(check_tree_conflict(&tree_conflict, eb, db->local_abspath,
                                 status, wc_kind, TRUE,
                                 svn_wc_conflict_action_edit, svn_node_dir,
-                                db->new_relpath, NULL, db->pool, pool));
+                                db->new_relpath, db->moved_to_abspath,
+                                db->pool, pool));
 
   /* Remember the roots of any locally deleted trees. */
   if (tree_conflict != NULL)
@@ -2377,6 +2505,8 @@ open_directory(const char *path,
       SVN_ERR_ASSERT(
                 tree_conflict->reason == svn_wc_conflict_reason_deleted ||
                 tree_conflict->reason == svn_wc_conflict_reason_moved_away ||
+                tree_conflict->reason ==
+                  svn_wc_conflict_reason_moved_away_and_edited ||
                 tree_conflict->reason == svn_wc_conflict_reason_replaced);
 
       /* Continue updating BASE */
@@ -2804,6 +2934,41 @@ close_directory(void *dir_baton,
                 new_actual_props,
                 all_work_items,
                 scratch_pool));
+
+      if (db->moved_to_abspath)
+        {
+          /* Perform another in-DB move of the directory to sync meta-data
+           * of the moved-away node with the new BASE node. */
+          apr_array_header_t *children = NULL;
+          apr_hash_t *children_hash = apr_hash_get(eb->dir_dirents,
+                                                   db->new_relpath,
+                                                   APR_HASH_KEY_STRING);
+          /* The op-root of the move needs to retain its moved-here flag.
+           * Its children are normal copied children. */
+          svn_boolean_t is_move = (strcmp(db->moved_to_op_root_abspath,
+                                          db->moved_to_abspath) == 0);
+
+          /* Add the new directory as a copy and create it on disk. */
+          if (children_hash)
+            SVN_ERR(svn_hash_keys(&children, children_hash, scratch_pool));
+          SVN_ERR(svn_wc__db_op_copy_dir(eb->db, db->moved_to_abspath,
+                                         new_actual_props ? new_actual_props
+                                                          : actual_props,
+                                         db->changed_rev,
+                                         db->changed_date,
+                                         db->changed_author,
+                                         db->new_relpath,
+                                         eb->repos_root,
+                                         eb->repos_uuid,
+                                         *eb->target_revision,
+                                         children,
+                                         is_move,
+                                         db->ambient_depth,
+                                         NULL /* conflict */,
+                                         NULL, /* no work, just modify DB */
+                                         scratch_pool));
+          SVN_ERR(svn_wc__ensure_directory(db->moved_to_abspath, pool));
+        }
     }
 
   /* Process all of the queued work items for this directory.  */
@@ -3256,6 +3421,15 @@ add_file(const char *path,
       do_notification(eb, fb->local_abspath, svn_node_file,
                       svn_wc_notify_tree_conflict, scratch_pool);
     }
+  else if (wc_kind == svn_kind_unknown &&
+           versioned_locally_and_present == FALSE &&
+           pb->moved_to_abspath)
+    {
+      /* The parent directory of the file we're adding was moved.
+       * Add the new file at the new location. */
+      fb->moved_to_abspath = svn_dirent_join(pb->moved_to_abspath,
+                                             fb->name, fb->pool);
+    }
 
   svn_pool_destroy(scratch_pool);
 
@@ -3377,7 +3551,9 @@ open_file(const char *path,
       /* Other modifications wouldn't be a tree conflict */
       SVN_ERR_ASSERT(
                 tree_conflict->reason == svn_wc_conflict_reason_deleted ||
-                tree_conflict->reason == svn_wc_conflict_reason_moved_away||
+                tree_conflict->reason == svn_wc_conflict_reason_moved_away ||
+                tree_conflict->reason ==
+                  svn_wc_conflict_reason_moved_away_and_edited ||
                 tree_conflict->reason == svn_wc_conflict_reason_replaced);
 
       /* Continue updating BASE */
@@ -4579,7 +4755,7 @@ fetch_props_func(apr_hash_t **props,
 }
 
 static svn_error_t *
-fetch_kind_func(svn_node_kind_t *kind,
+fetch_kind_func(svn_kind_t *kind,
                 void *baton,
                 const char *path,
                 apr_pool_t *scratch_pool)
@@ -4587,17 +4763,9 @@ fetch_kind_func(svn_node_kind_t *kind,
   struct fetch_baton *fpb = baton;
   const char *local_abspath = svn_dirent_join(fpb->target_abspath, path,
                                               scratch_pool);
-  svn_kind_t db_kind;
 
-  SVN_ERR(svn_wc__db_read_kind(&db_kind, fpb->db, local_abspath, FALSE,
+  SVN_ERR(svn_wc__db_read_kind(kind, fpb->db, local_abspath, FALSE,
                                scratch_pool));
-
-  if (db_kind == svn_kind_dir)
-    *kind = svn_node_dir;
-  else if (db_kind == svn_kind_file)
-    *kind = svn_node_file;
-  else
-    *kind = svn_node_none;
   
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/showing-merge-info/subversion/libsvn_wc/upgrade.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_wc/upgrade.c?rev=1186075&r1=1186074&r2=1186075&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_wc/upgrade.c (original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_wc/upgrade.c Wed Oct 19 10:33:19 2011
@@ -1404,6 +1404,7 @@ upgrade_to_wcng(void **dir_baton,
   svn_wc_entry_t *this_dir;
   const char *old_wcroot_abspath, *dir_relpath;
   apr_hash_t *text_bases_info;
+  svn_error_t *err;
 
   /* Don't try to mess with the WC if there are old log files left. */
 
@@ -1475,11 +1476,18 @@ upgrade_to_wcng(void **dir_baton,
                              data->sdb, scratch_pool, scratch_pool));
 
   /***** ENTRIES - WRITE *****/
-  SVN_ERR(svn_wc__write_upgraded_entries(dir_baton, parent_baton, db, data->sdb,
-                                         data->repos_id, data->wc_id,
-                                         dir_abspath, data->root_abspath,
-                                         entries, text_bases_info,
-                                         result_pool, scratch_pool));
+  err = svn_wc__write_upgraded_entries(dir_baton, parent_baton, db, data->sdb,
+                                       data->repos_id, data->wc_id,
+                                       dir_abspath, data->root_abspath,
+                                       entries, text_bases_info,
+                                       result_pool, scratch_pool);
+  if (err && err->apr_err == SVN_ERR_WC_CORRUPT)
+    return svn_error_quick_wrap(err,
+                                _("This working copy is corrupt and "
+                                  "cannot be upgraded. Please check out "
+                                  "a new working copy."));
+  else
+    SVN_ERR(err);
 
   /***** WC PROPS *****/
   /* If we don't know precisely where the wcprops are, ignore them.  */

Modified: subversion/branches/showing-merge-info/subversion/libsvn_wc/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_wc/util.c?rev=1186075&r1=1186074&r2=1186075&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_wc/util.c (original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_wc/util.c Wed Oct 19 10:33:19 2011
@@ -150,8 +150,8 @@ svn_wc_dup_notify(const svn_wc_notify_t 
 }
 
 svn_error_t *
-svn_wc_external_item_create(const svn_wc_external_item2_t **item,
-                            apr_pool_t *pool)
+svn_wc_external_item2_create(svn_wc_external_item2_t **item,
+                             apr_pool_t *pool)
 {
   *item = apr_pcalloc(pool, sizeof(svn_wc_external_item2_t));
   return SVN_NO_ERROR;

Modified: subversion/branches/showing-merge-info/subversion/libsvn_wc/wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_wc/wc.h?rev=1186075&r1=1186074&r2=1186075&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_wc/wc.h (original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_wc/wc.h Wed Oct 19 10:33:19 2011
@@ -149,7 +149,7 @@ extern "C" {
  * The bump to 29 renamed the pristine files from '<SHA1>' to '<SHA1>.svn-base'
  * and introduced the EXTERNALS store. Bumped in r1129286.
  *
- * == 1.7.x shipped with format ???
+ * == 1.7.x shipped with format 29
  *
  * Please document any further format changes here.
  */
@@ -350,10 +350,8 @@ svn_wc__prop_array_to_hash(const apr_arr
  *
  * If EXACT_COMPARISON is FALSE, translate LOCAL_ABSPATH's EOL
  * style and keywords to repository-normal form according to its properties,
- * and compare the result with the text base.  If COMPARE_TEXTBASES is
- * TRUE, translate the text base's EOL style and keywords to working-copy
- * form according to LOCAL_ABSPATH's properties, and compare the
- * result with LOCAL_ABSPATH.  Usually, EXACT_COMPARISON should be FALSE.
+ * and compare the result with the text base.
+ * Usually, EXACT_COMPARISON should be FALSE.
  *
  * If LOCAL_ABSPATH does not exist, consider it unmodified.  If it exists
  * but is not under revision control (not even scheduled for

Modified: subversion/branches/showing-merge-info/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_wc/wc_db.c?rev=1186075&r1=1186074&r2=1186075&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_wc/wc_db.c Wed Oct 19 10:33:19 2011
@@ -4178,6 +4178,7 @@ svn_wc__db_op_copy_dir(svn_wc__db_t *db,
                        const char *original_uuid,
                        svn_revnum_t original_revision,
                        const apr_array_header_t *children,
+                       svn_boolean_t is_move,
                        svn_depth_t depth,
                        const svn_skel_t *conflict,
                        const svn_skel_t *work_items,
@@ -4209,7 +4210,7 @@ svn_wc__db_op_copy_dir(svn_wc__db_t *db,
   iwb.changed_rev = changed_rev;
   iwb.changed_date = changed_date;
   iwb.changed_author = changed_author;
-  iwb.moved_here = FALSE;
+  iwb.moved_here = is_move;
 
   if (original_root_url != NULL)
     {
@@ -6403,6 +6404,33 @@ op_delete_txn(void *baton,
         }
 
       select_depth = relpath_depth(local_relpath);
+
+      /* When deleting a moved-here op-root, clear moved-to data at the
+       * pre-move location, transforming the move into a normal delete.
+       * This way, deleting the copied half of a move has the same effect
+       * as reverting it. */
+      if (status == svn_wc__db_status_added ||
+          status == svn_wc__db_status_moved_here)
+        {
+          const char *moved_from_relpath;
+          const char *moved_from_op_root_relpath;
+
+          SVN_ERR(scan_addition(&status, NULL, NULL, NULL, NULL, NULL, NULL,
+                                &moved_from_relpath,
+                                &moved_from_op_root_relpath,
+                                wcroot, local_relpath,
+                                scratch_pool, scratch_pool));
+          if (status == svn_wc__db_status_moved_here &&
+              moved_from_relpath && moved_from_op_root_relpath &&
+              strcmp(moved_from_relpath, moved_from_op_root_relpath) == 0)
+            {
+              SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                                STMT_CLEAR_MOVED_TO_RELPATH));
+              SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id,
+                                        moved_from_op_root_relpath));
+              SVN_ERR(svn_sqlite__step_done(stmt));
+            }
+        }
     }
   else
     {
@@ -6728,18 +6756,10 @@ read_info(svn_wc__db_status_t *status,
             }
           else
             {
-              svn_error_t *err2;
-              err2 = svn_sqlite__column_checksum(checksum, stmt_info, 6,
-                                                 result_pool);
 
-              if (err2 != NULL)
-                err = svn_error_compose_create(
-                         err,
-                         svn_error_createf(
-                               err->apr_err, err2,
-                              _("The node '%s' has a corrupt checksum value."),
-                              path_for_error_message(wcroot, local_relpath,
-                                                     scratch_pool)));
+              err = svn_error_compose_create(
+                        err, svn_sqlite__column_checksum(checksum, stmt_info, 6,
+                                                         result_pool));
             }
         }
       if (recorded_size)
@@ -6922,6 +6942,12 @@ read_info(svn_wc__db_status_t *status,
   if (stmt_act != NULL)
     err = svn_error_compose_create(err, svn_sqlite__reset(stmt_act));
 
+  if (err && err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
+    err = svn_error_quick_wrap(err, 
+                               apr_psprintf(scratch_pool,
+                                            "Error reading node '%s'",
+                                            local_relpath));
+
   SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt_info)));
 
   return SVN_NO_ERROR;
@@ -9994,6 +10020,8 @@ scan_deletion_txn(void *baton,
                       svn_error_clear(err); 
                       moved_to_relpath = NULL;
                       moved_to_op_root_relpath = NULL;
+                      if (sd_baton->moved_to_relpath)
+                        *sd_baton->moved_to_relpath = NULL;
                       found_child = FALSE;
                     }
                   else

Modified: subversion/branches/showing-merge-info/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/libsvn_wc/wc_db.h?rev=1186075&r1=1186074&r2=1186075&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/showing-merge-info/subversion/libsvn_wc/wc_db.h Wed Oct 19 10:33:19 2011
@@ -1229,6 +1229,7 @@ svn_wc__db_op_copy_dir(svn_wc__db_t *db,
                        const char *original_uuid,
                        svn_revnum_t original_revision,
                        const apr_array_header_t *children,
+                       svn_boolean_t is_move,
                        svn_depth_t depth,
                        const svn_skel_t *conflict,
                        const svn_skel_t *work_items,

Modified: subversion/branches/showing-merge-info/subversion/svn/add-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/svn/add-cmd.c?rev=1186075&r1=1186074&r2=1186075&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/svn/add-cmd.c (original)
+++ subversion/branches/showing-merge-info/subversion/svn/add-cmd.c Wed Oct 19 10:33:19 2011
@@ -51,7 +51,7 @@ svn_cl__add(apr_getopt_t *os,
   apr_array_header_t *targets;
   int i;
   apr_pool_t *iterpool;
-  svn_boolean_t seen_nonexistent_target = FALSE;
+  apr_array_header_t *errors = apr_array_make(pool, 0, sizeof(apr_status_t));
 
   SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
                                                       opt_state->targets,
@@ -71,7 +71,6 @@ svn_cl__add(apr_getopt_t *os,
   for (i = 0; i < targets->nelts; i++)
     {
       const char *target = APR_ARRAY_IDX(targets, i, const char *);
-      svn_boolean_t success;
 
       svn_pool_clear(iterpool);
       SVN_ERR(svn_cl__check_cancel(ctx->cancel_baton));
@@ -80,21 +79,34 @@ svn_cl__add(apr_getopt_t *os,
                                opt_state->depth,
                                opt_state->force, opt_state->no_ignore,
                                opt_state->parents, ctx, iterpool),
-               &success, opt_state->quiet,
+               errors, opt_state->quiet,
                SVN_ERR_ENTRY_EXISTS,
                SVN_ERR_WC_PATH_NOT_FOUND,
                SVN_NO_ERROR));
-
-      if (! success)
-        seen_nonexistent_target = TRUE;
     }
 
   svn_pool_destroy(iterpool);
 
-  if (seen_nonexistent_target)
-    return svn_error_create(
-      SVN_ERR_ILLEGAL_TARGET, NULL,
-      _("Could not add all targets because some targets don't exist"));
-  else
-    return SVN_NO_ERROR;
+  if (errors->nelts > 0)
+    {
+      svn_error_t *err;
+
+      err = svn_error_create(SVN_ERR_ILLEGAL_TARGET, NULL, NULL);
+      for (i = 0; i < errors->nelts; i++)
+        {
+          apr_status_t status = APR_ARRAY_IDX(errors, i, apr_status_t);
+          if (status == SVN_ERR_WC_PATH_NOT_FOUND)
+            err = svn_error_quick_wrap(err,
+                                       _("Could not add all targets because "
+                                         "some targets don't exist"));
+          else if (status == SVN_ERR_ENTRY_EXISTS)
+            err = svn_error_quick_wrap(err,
+                                       _("Could not add all targets because "
+                                         "some targets are already versioned"));
+        }
+
+      return svn_error_trace(err);
+    }
+
+  return SVN_NO_ERROR;
 }

Modified: subversion/branches/showing-merge-info/subversion/svn/cat-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/svn/cat-cmd.c?rev=1186075&r1=1186074&r2=1186075&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/svn/cat-cmd.c (original)
+++ subversion/branches/showing-merge-info/subversion/svn/cat-cmd.c Wed Oct 19 10:33:19 2011
@@ -50,7 +50,8 @@ svn_cl__cat(apr_getopt_t *os,
   int i;
   svn_stream_t *out;
   apr_pool_t *subpool = svn_pool_create(pool);
-  svn_boolean_t seen_nonexistent_target = FALSE;
+  apr_array_header_t *errors = apr_array_make(pool, 0, sizeof(apr_status_t));
+  svn_error_t *err;
 
   SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
                                                       opt_state->targets,
@@ -67,7 +68,6 @@ svn_cl__cat(apr_getopt_t *os,
       const char *target = APR_ARRAY_IDX(targets, i, const char *);
       const char *truepath;
       svn_opt_revision_t peg_revision;
-      svn_boolean_t success;
 
       svn_pool_clear(subpool);
       SVN_ERR(svn_cl__check_cancel(ctx->cancel_baton));
@@ -79,21 +79,40 @@ svn_cl__cat(apr_getopt_t *os,
       SVN_ERR(svn_cl__try(svn_client_cat2(out, truepath, &peg_revision,
                                           &(opt_state->start_revision),
                                           ctx, subpool),
-                           &success, opt_state->quiet,
+                           errors, opt_state->quiet,
                            SVN_ERR_UNVERSIONED_RESOURCE,
                            SVN_ERR_ENTRY_NOT_FOUND,
                            SVN_ERR_CLIENT_IS_DIRECTORY,
                            SVN_ERR_FS_NOT_FOUND,
                            SVN_NO_ERROR));
-      if (! success)
-        seen_nonexistent_target = TRUE;
     }
   svn_pool_destroy(subpool);
 
-  if (seen_nonexistent_target)
-    return svn_error_create(
-      SVN_ERR_ILLEGAL_TARGET, NULL,
-      _("Could not cat all targets because some targets don't exist"));
-  else
-    return SVN_NO_ERROR;
+  if (errors->nelts > 0)
+    {
+      err = svn_error_create(SVN_ERR_ILLEGAL_TARGET, NULL, NULL);
+
+      for (i = 0; i < errors->nelts; i++)
+        {
+          apr_status_t status = APR_ARRAY_IDX(errors, i, apr_status_t);
+
+          if (status == SVN_ERR_ENTRY_NOT_FOUND ||
+              status == SVN_ERR_FS_NOT_FOUND)
+            err = svn_error_quick_wrap(err, 
+                                       _("Could not cat all targets because "
+                                         "some targets don't exist"));
+          else if (status == SVN_ERR_UNVERSIONED_RESOURCE)
+            err = svn_error_quick_wrap(err,
+                                       _("Could not cat all targets because "
+                                         "some targets are not versioned"));
+          else if (status == SVN_ERR_CLIENT_IS_DIRECTORY)
+            err = svn_error_quick_wrap(err,
+                                       _("Could not cat all targets because "
+                                         "some targets are directories"));
+        }
+
+      return svn_error_trace(err);
+    }
+  
+  return SVN_NO_ERROR;
 }

Modified: subversion/branches/showing-merge-info/subversion/svn/changelist-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/svn/changelist-cmd.c?rev=1186075&r1=1186074&r2=1186075&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/svn/changelist-cmd.c (original)
+++ subversion/branches/showing-merge-info/subversion/svn/changelist-cmd.c Wed Oct 19 10:33:19 2011
@@ -45,7 +45,7 @@ svn_cl__changelist(apr_getopt_t *os,
   svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
   apr_array_header_t *targets;
   svn_depth_t depth = opt_state->depth;
-  svn_boolean_t success = TRUE;
+  apr_array_header_t *errors = apr_array_make(pool, 0, sizeof(apr_status_t));
 
   /* If we're not removing changelists, then our first argument should
      be the name of a changelist. */
@@ -103,7 +103,7 @@ svn_cl__changelist(apr_getopt_t *os,
                svn_client_add_to_changelist(targets, changelist_name,
                                             depth, opt_state->changelists,
                                             ctx, pool),
-               &success, opt_state->quiet,
+               errors, opt_state->quiet,
                SVN_ERR_UNVERSIONED_RESOURCE,
                SVN_ERR_WC_PATH_NOT_FOUND,
                SVN_NO_ERROR));
@@ -114,16 +114,36 @@ svn_cl__changelist(apr_getopt_t *os,
                svn_client_remove_from_changelists(targets, depth,
                                                   opt_state->changelists,
                                                   ctx, pool),
-               &success, opt_state->quiet,
+               errors, opt_state->quiet,
                SVN_ERR_UNVERSIONED_RESOURCE,
                SVN_ERR_WC_PATH_NOT_FOUND,
                SVN_NO_ERROR));
     }
 
-  if (!success)
-    return svn_error_create(SVN_ERR_ILLEGAL_TARGET, NULL,
-                            _("Could not display info for all targets because "
-                              "some targets don't exist"));
-  else
-    return SVN_NO_ERROR;
+  if (errors->nelts > 0)
+    {
+      int i;
+      svn_error_t *err;
+
+      err = svn_error_create(SVN_ERR_ILLEGAL_TARGET, NULL, NULL);
+      for (i = 0; i < errors->nelts; i++)
+        {
+          apr_status_t status = APR_ARRAY_IDX(errors, i, apr_status_t);
+          
+          if (status == SVN_ERR_WC_PATH_NOT_FOUND)
+            err = svn_error_quick_wrap(err,
+                                       _("Could not display changelists of "
+                                         "all targets because some targets "
+                                         "don't exist"));
+          else if (status == SVN_ERR_UNVERSIONED_RESOURCE)
+            err = svn_error_quick_wrap(err,
+                                       _("Could not display changelists of "
+                                         "all targets because some targets "
+                                         "are not versioned"));
+        }
+
+      return svn_error_trace(err);
+    }
+
+  return SVN_NO_ERROR;
 }

Modified: subversion/branches/showing-merge-info/subversion/svn/cl.h
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/svn/cl.h?rev=1186075&r1=1186074&r2=1186075&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/svn/cl.h (original)
+++ subversion/branches/showing-merge-info/subversion/svn/cl.h Wed Oct 19 10:33:19 2011
@@ -294,15 +294,14 @@ extern const apr_getopt_option_t svn_cl_
  * invoked on an unversioned, nonexistent, or otherwise innocuously
  * errorful resource.  Meant to be wrapped with SVN_ERR().
  *
- * If ERR is null, return SVN_NO_ERROR, setting *SUCCESS to TRUE
- * if SUCCESS is not NULL.
+ * If ERR is null, return SVN_NO_ERROR.
  *
  * Else if ERR->apr_err is one of the error codes supplied in varargs,
  * then handle ERR as a warning (unless QUIET is true), clear ERR, and
- * return SVN_NO_ERROR, setting *SUCCESS to FALSE if SUCCESS is not
- * NULL.
+ * return SVN_NO_ERROR, and push the value of ERR->apr_err into the
+ * ERRORS_SEEN array, if ERRORS_SEEN is not NULL.
  *
- * Else return ERR, setting *SUCCESS to FALSE if SUCCESS is not NULL.
+ * Else return ERR.
  *
  * Typically, error codes like SVN_ERR_UNVERSIONED_RESOURCE,
  * SVN_ERR_ENTRY_NOT_FOUND, etc, are supplied in varargs.  Don't
@@ -310,7 +309,7 @@ extern const apr_getopt_option_t svn_cl_
  */
 svn_error_t *
 svn_cl__try(svn_error_t *err,
-            svn_boolean_t *success,
+            apr_array_header_t *errors_seen,
             svn_boolean_t quiet,
             ...);
 

Modified: subversion/branches/showing-merge-info/subversion/svn/mergeinfo-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/svn/mergeinfo-cmd.c?rev=1186075&r1=1186074&r2=1186075&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/svn/mergeinfo-cmd.c (original)
+++ subversion/branches/showing-merge-info/subversion/svn/mergeinfo-cmd.c Wed Oct 19 10:33:19 2011
@@ -162,8 +162,8 @@ svn_cl__mergeinfo(apr_getopt_t *os,
   svn_client_target_t *target;
   const char *marker;
   /* Default to depth infinity. */
-  svn_depth_t depth = opt_state->depth == svn_depth_unknown
-    ? svn_depth_infinity : opt_state->depth;
+  svn_depth_t depth = (opt_state->depth == svn_depth_unknown)
+                      ? svn_depth_infinity : opt_state->depth;
   struct print_log_rev_baton_t log_rev_baton;
 
   SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,

Modified: subversion/branches/showing-merge-info/subversion/svn/proplist-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/svn/proplist-cmd.c?rev=1186075&r1=1186074&r2=1186075&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/svn/proplist-cmd.c (original)
+++ subversion/branches/showing-merge-info/subversion/svn/proplist-cmd.c Wed Oct 19 10:33:19 2011
@@ -112,6 +112,8 @@ svn_cl__proplist(apr_getopt_t *os,
   svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
   svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
   apr_array_header_t *targets;
+  apr_array_header_t *errors = apr_array_make(scratch_pool, 0,
+                                              sizeof(apr_status_t));
 
   SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
                                                       opt_state->targets,
@@ -168,7 +170,6 @@ svn_cl__proplist(apr_getopt_t *os,
       int i;
       apr_pool_t *iterpool;
       svn_proplist_receiver_t pl_receiver;
-      svn_boolean_t had_errors = FALSE;
 
       if (opt_state->xml)
         {
@@ -190,7 +191,6 @@ svn_cl__proplist(apr_getopt_t *os,
           proplist_baton_t pl_baton;
           const char *truepath;
           svn_opt_revision_t peg_revision;
-          svn_boolean_t success;
 
           svn_pool_clear(iterpool);
           SVN_ERR(svn_cl__check_cancel(ctx->cancel_baton));
@@ -209,13 +209,10 @@ svn_cl__proplist(apr_getopt_t *os,
                                         opt_state->changelists,
                                         pl_receiver, &pl_baton,
                                         ctx, iterpool),
-                   &success, opt_state->quiet,
+                   errors, opt_state->quiet,
                    SVN_ERR_UNVERSIONED_RESOURCE,
                    SVN_ERR_ENTRY_NOT_FOUND,
                    SVN_NO_ERROR));
-
-          if (!success)
-            had_errors = TRUE;
         }
       svn_pool_destroy(iterpool);
 
@@ -223,10 +220,29 @@ svn_cl__proplist(apr_getopt_t *os,
         SVN_ERR(svn_cl__xml_print_footer("properties", scratch_pool));
 
       /* Error out *after* we closed the XML element */
-      if (had_errors)
-        return svn_error_create(SVN_ERR_ILLEGAL_TARGET, NULL,
-                                _("Could not display info for all targets "
-                                  "because some targets don't exist"));
+      if (errors->nelts > 0)
+        {
+          svn_error_t *err;
+          
+          err = svn_error_create(SVN_ERR_ILLEGAL_TARGET, NULL, NULL);
+          for (i = 0; i < errors->nelts; i++)
+            {
+              apr_status_t status = APR_ARRAY_IDX(errors, i, apr_status_t);
+              
+              if (status == SVN_ERR_ENTRY_NOT_FOUND)
+                err = svn_error_quick_wrap(err,
+                                           _("Could not display properties "
+                                             "of all targets because some "
+                                             "targets don't exist"));
+              else if (status == SVN_ERR_UNVERSIONED_RESOURCE)
+                err = svn_error_quick_wrap(err,
+                                           _("Could not display properties "
+                                             "of all targets because some "
+                                             "targets are not versioned"));
+            }
+
+          return svn_error_trace(err);
+        }
     }
 
   return SVN_NO_ERROR;

Modified: subversion/branches/showing-merge-info/subversion/svn/tree-conflicts.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/svn/tree-conflicts.c?rev=1186075&r1=1186074&r2=1186075&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/svn/tree-conflicts.c (original)
+++ subversion/branches/showing-merge-info/subversion/svn/tree-conflicts.c Wed Oct 19 10:33:19 2011
@@ -63,6 +63,7 @@ static const svn_token_map_t map_conflic
   { N_("replace"),      svn_wc_conflict_reason_replaced },
   { N_("unversioned"),  svn_wc_conflict_reason_unversioned },
   { N_("moved away"),   svn_wc_conflict_reason_moved_away },
+  { N_("moved away and edited"), svn_wc_conflict_reason_moved_away_and_edited },
   { N_("moved here"),   svn_wc_conflict_reason_moved_here },
   { NULL,               0 }
 };
@@ -78,6 +79,7 @@ static const svn_token_map_t map_conflic
   { "replace",          svn_wc_conflict_reason_replaced },
   { "unversioned",      svn_wc_conflict_reason_unversioned },
   { "moved-away",       svn_wc_conflict_reason_moved_away },
+  { "moved-away-and-edited", svn_wc_conflict_reason_moved_away_and_edited },
   { "moved-here",       svn_wc_conflict_reason_moved_here },
   { NULL,               0 }
 };

Modified: subversion/branches/showing-merge-info/subversion/svn/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/svn/util.c?rev=1186075&r1=1186074&r2=1186075&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/svn/util.c (original)
+++ subversion/branches/showing-merge-info/subversion/svn/util.c Wed Oct 19 10:33:19 2011
@@ -937,7 +937,7 @@ svn_cl__error_checked_fputs(const char *
 
 svn_error_t *
 svn_cl__try(svn_error_t *err,
-            svn_boolean_t *success,
+            apr_array_header_t *errors_seen,
             svn_boolean_t quiet,
             ...)
 {
@@ -946,12 +946,27 @@ svn_cl__try(svn_error_t *err,
       apr_status_t apr_err;
       va_list ap;
 
-      if (success)
-        *success = FALSE;
-
       va_start(ap, quiet);
       while ((apr_err = va_arg(ap, apr_status_t)) != SVN_NO_ERROR)
         {
+          if (errors_seen)
+            {
+              int i;
+              svn_boolean_t add = TRUE;
+
+              /* Don't report duplicate error codes. */
+              for (i = 0; i < errors_seen->nelts; i++)
+                {
+                  if (APR_ARRAY_IDX(errors_seen, i,
+                                    apr_status_t) == err->apr_err)
+                    {
+                      add = FALSE;
+                      break;
+                    }
+                }
+              if (add)
+                APR_ARRAY_PUSH(errors_seen, apr_status_t) = err->apr_err;
+            }
           if (err->apr_err == apr_err)
             {
               if (! quiet)
@@ -962,10 +977,6 @@ svn_cl__try(svn_error_t *err,
         }
       va_end(ap);
     }
-  else if (success)
-    {
-      *success = TRUE;
-    }
 
   return svn_error_trace(err);
 }

Modified: subversion/branches/showing-merge-info/subversion/svnrdump/load_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/svnrdump/load_editor.c?rev=1186075&r1=1186074&r2=1186075&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/svnrdump/load_editor.c (original)
+++ subversion/branches/showing-merge-info/subversion/svnrdump/load_editor.c Wed Oct 19 10:33:19 2011
@@ -312,8 +312,8 @@ renumber_mergeinfo_revs(svn_string_t **f
 
   if (predates_stream_mergeinfo)
     {
-      SVN_ERR(svn_mergeinfo_merge(final_mergeinfo, predates_stream_mergeinfo,
-                                  subpool));
+      SVN_ERR(svn_mergeinfo_merge2(final_mergeinfo, predates_stream_mergeinfo,
+                                   subpool, subpool));
     }
 
   SVN_ERR(svn_mergeinfo_sort(final_mergeinfo, subpool));

Modified: subversion/branches/showing-merge-info/subversion/tests/cmdline/basic_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/tests/cmdline/basic_tests.py?rev=1186075&r1=1186074&r2=1186075&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/tests/cmdline/basic_tests.py (original)
+++ subversion/branches/showing-merge-info/subversion/tests/cmdline/basic_tests.py Wed Oct 19 10:33:19 2011
@@ -1614,6 +1614,12 @@ def basic_add_parents(sbox):
                                         None,
                                         wc_dir)
 
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'rm', X_path, '--keep-local')
+
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'add', '--parents', zeta_path)
+
 #----------------------------------------------------------------------
 def uri_syntax(sbox):
   'make sure URI syntaxes are parsed correctly'

Modified: subversion/branches/showing-merge-info/subversion/tests/cmdline/cat_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/tests/cmdline/cat_tests.py?rev=1186075&r1=1186074&r2=1186075&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/tests/cmdline/cat_tests.py (original)
+++ subversion/branches/showing-merge-info/subversion/tests/cmdline/cat_tests.py Wed Oct 19 10:33:19 2011
@@ -159,8 +159,7 @@ def cat_skip_uncattable(sbox):
                                        'cat', rho_path, new_file_path)
 
   expected_err3 = expected_err1 + expected_err2 + \
-      ".*svn: E200009: Could not cat all targets because some targets " + \
-      "don't exist\n"
+      ".*svn: E200009: Could not cat all targets because some targets"
   expected_err_re = re.compile(expected_err3, re.DOTALL)
 
   exit_code, output, error = svntest.main.run_svn(1, 'cat', rho_path, G_path, new_file_path)

Modified: subversion/branches/showing-merge-info/subversion/tests/cmdline/depth_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/tests/cmdline/depth_tests.py?rev=1186075&r1=1186074&r2=1186075&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/tests/cmdline/depth_tests.py (original)
+++ subversion/branches/showing-merge-info/subversion/tests/cmdline/depth_tests.py Wed Oct 19 10:33:19 2011
@@ -2811,6 +2811,35 @@ def sparse_update_with_dash_dash_parents
                                         None, None, None, None, None, False,
                                         '--parents', omega_path)
 
+def update_below_depth_empty(sbox):
+  "update below depth empty shouldn't be applied"
+  sbox.build()
+
+  repo_url = sbox.repo_url
+  A = sbox.ospath('A')
+
+  expected_output = svntest.wc.State(sbox.wc_dir, {
+      'A/C'               : Item(status='D '),
+      'A/B'               : Item(status='D '),
+      'A/mu'              : Item(status='D '),
+      'A/D'               : Item(status='D '),
+    })
+  svntest.actions.run_and_verify_update(sbox.wc_dir, expected_output, None,
+                                        None, None, None, None, None, None,
+                                        False,
+                                        '--set-depth', 'empty', A)
+
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'cp', repo_url + '/iota',
+                                           repo_url + '/A/B',
+                                     '-m', 'remote copy')
+
+  expected_output = svntest.wc.State(sbox.wc_dir, {
+    })
+
+  # This update should just update the revision of the working copy
+  svntest.actions.run_and_verify_update(sbox.wc_dir, expected_output, None,
+                                        None, None)
 
 #----------------------------------------------------------------------
 # list all tests here, starting with None:
@@ -2858,6 +2887,7 @@ test_list = [ None,
               update_excluded_path_sticky_depths,
               update_depth_empty_root_of_infinite_children,
               sparse_update_with_dash_dash_parents,
+              update_below_depth_empty,
               ]
 
 if __name__ == "__main__":

Modified: subversion/branches/showing-merge-info/subversion/tests/cmdline/tree_conflict_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/tests/cmdline/tree_conflict_tests.py?rev=1186075&r1=1186074&r2=1186075&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/tests/cmdline/tree_conflict_tests.py (original)
+++ subversion/branches/showing-merge-info/subversion/tests/cmdline/tree_conflict_tests.py Wed Oct 19 10:33:19 2011
@@ -278,6 +278,9 @@ f_moves = [
 
 d_dels = [
   ( create_d, ['dD'] ),
+]
+
+d_moves = [
   ( create_d, ['dM'] ),
 ]
 
@@ -604,12 +607,12 @@ def up_sw_dir_mod_onto_del(sbox):
 def up_sw_dir_del_onto_mod(sbox):
   "up/sw dir: del/rpl/mv onto modify"
   # WC state: any (D necessarily exists; children may have any state)
-  test_tc_up_sw(sbox, d_dels + d_rpls, d_mods)
+  test_tc_up_sw(sbox, d_dels + d_moves + d_rpls, d_mods)
 
 def up_sw_dir_del_onto_del(sbox):
   "up/sw dir: del/rpl/mv onto del/rpl/mv"
   # WC state: any (D necessarily exists; children may have any state)
-  test_tc_up_sw(sbox, d_dels + d_rpls, d_dels + d_rpls)
+  test_tc_up_sw(sbox, d_dels + d_moves + d_rpls, d_dels + d_rpls)
 
 # This is currently set as XFail over ra_dav because it hits
 # issue #3314 'DAV can overwrite directories during copy'
@@ -690,8 +693,8 @@ def merge_file_add_onto_not_none(sbox):
 def merge_dir_mod_onto_not_dir(sbox):
   "merge dir: modify onto not-dir"
   sbox2 = sbox.clone_dependent()
-  test_tc_merge(sbox, d_mods, br_scen = d_dels + d_rpl_f)
-  test_tc_merge(sbox2, d_mods, wc_scen = d_dels)
+  test_tc_merge(sbox, d_mods, br_scen = d_dels + d_moves + d_rpl_f)
+  test_tc_merge(sbox2, d_mods, wc_scen = d_dels + d_moves)
 
 # Test for issue #3150 'tree conflicts with directories as victims'.
 @XFail()
@@ -699,14 +702,14 @@ def merge_dir_mod_onto_not_dir(sbox):
 def merge_dir_del_onto_not_same(sbox):
   "merge dir: del/rpl/mv onto not-same"
   sbox2 = sbox.clone_dependent()
-  test_tc_merge(sbox, d_dels + d_rpls, br_scen = d_mods)
-  test_tc_merge(sbox2, d_dels + d_rpls, wc_scen = d_mods)
+  test_tc_merge(sbox, d_dels + d_moves + d_rpls, br_scen = d_mods)
+  test_tc_merge(sbox2, d_dels + d_moves + d_rpls, wc_scen = d_mods)
 
 def merge_dir_del_onto_not_dir(sbox):
   "merge dir: del/rpl/mv onto not-dir"
   sbox2 = sbox.clone_dependent()
-  test_tc_merge(sbox, d_dels + d_rpls, br_scen = d_dels + d_rpl_f)
-  test_tc_merge(sbox2, d_dels + d_rpls, wc_scen = d_dels)
+  test_tc_merge(sbox, d_dels + d_moves + d_rpls, br_scen = d_dels + d_moves + d_rpl_f)
+  test_tc_merge(sbox2, d_dels + d_moves + d_rpls, wc_scen = d_dels + d_moves)
 
 def merge_dir_add_onto_not_none(sbox):
   "merge dir: add onto not-none"

Modified: subversion/branches/showing-merge-info/subversion/tests/cmdline/update_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/tests/cmdline/update_tests.py?rev=1186075&r1=1186074&r2=1186075&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/tests/cmdline/update_tests.py (original)
+++ subversion/branches/showing-merge-info/subversion/tests/cmdline/update_tests.py Wed Oct 19 10:33:19 2011
@@ -5404,6 +5404,212 @@ def update_to_HEAD_plus_1(sbox):
                                         None, None,
                                         None, None, None, wc_dir, '-r', '2')
 
+def update_moved_dir_leaf_del(sbox):
+  "update locally moved dir with leaf del"
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  svntest.main.run_svn(False, 'rm', '-m', 'remove /A/B/E/alpha',
+                       sbox.repo_url + "/A/B/E/alpha")
+  sbox.simple_move("A/B/E", "A/B/E2")
+
+  # since alpha isn't locally modified, the incoming delete should auto-merge
+  expected_output = svntest.wc.State(wc_dir, {
+    'A/B/E2/alpha' : Item(status='D '),
+  })
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.remove('A/B/E/alpha', 'A/B/E/beta', 'A/B/E')
+  expected_disk.add({
+    'A/B/E2'           : Item(),
+    'A/B/E2/beta'      : Item(contents="This is the file 'beta'.\n"),
+  })
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
+  expected_status.add({
+    'A/B/E2'            : Item(status='A ', copied='+', wc_rev='-'),
+    'A/B/E2/beta'       : Item(status='  ', copied='+', wc_rev='-'),
+    'A/B/E2/alpha'      : Item(status='D ', copied='+', wc_rev='-'),
+  })
+  expected_status.remove('A/B/E/alpha')
+  expected_status.tweak('A/B/E', 'A/B/E/beta', status='D ')
+  svntest.actions.run_and_verify_update(wc_dir,
+                                        expected_output,
+                                        expected_disk,
+                                        expected_status,
+                                        None, None, None,
+                                        None, None, 1)
+
+def update_moved_dir_edited_leaf_del(sbox):
+  "update locally moved dir with edited leaf del"
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  svntest.main.run_svn(False, 'rm', '-m', 'remove /A/B/E/alpha',
+                       sbox.repo_url + "/A/B/E/alpha")
+  sbox.simple_move("A/B/E", "A/B/E2")
+  svntest.main.file_write(sbox.ospath('A/B/E2/alpha'),
+                          "This is a changed 'alpha'.\n")
+
+  # since alpha was modified post-move, the incoming delete should conflict
+  expected_output = svntest.wc.State(wc_dir, {
+    'A/B/E/alpha'       : Item(status='  ', treeconflict='C'),
+  })
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.remove('A/B/E/alpha', 'A/B/E/beta', 'A/B/E')
+  expected_disk.add({
+    'A/B/E2'           : Item(),
+    'A/B/E2/alpha'     : Item(contents="This is a changed 'alpha'.\n"),
+    'A/B/E2/beta'      : Item(contents="This is the file 'beta'.\n"),
+  })
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
+  expected_status.tweak('A/B/E', 'A/B/E/beta', status='D ')
+  expected_status.remove('A/B/E/alpha')
+  expected_status.add({
+    'A/B/E/alpha'       : Item(status='! ', treeconflict='C'),
+    'A/B/E2'            : Item(status='A ', copied='+', wc_rev='-'),
+    'A/B/E2/beta'       : Item(status='  ', copied='+', wc_rev='-'),
+    'A/B/E2/alpha'      : Item(status='M ', copied='+', wc_rev='-'),
+  })
+  svntest.actions.run_and_verify_update(wc_dir,
+                                        expected_output,
+                                        expected_disk,
+                                        expected_status,
+                                        None, None, None,
+                                        None, None, 1)
+
+def update_moved_dir_file_add(sbox):
+  "update locally moved dir with incoming file"
+  sbox.build()
+  wc_dir = sbox.wc_dir
+  foo_path = "A/B/E/foo"
+  foo_content = "This is the file 'foo'.\n"
+
+  svntest.main.file_write(sbox.ospath(foo_path), foo_content, 'wb')
+  sbox.simple_add(foo_path)
+  sbox.simple_commit()
+  # update to go back in time, before the last commit
+  svntest.main.run_svn(False, 'update', '-r', '1', wc_dir)
+  sbox.simple_move("A/B/E", "A/B/E2")
+
+  # the incoming file should auto-merge
+  expected_output = svntest.wc.State(wc_dir, {
+    'A/B/E2/foo' : Item(status='A '),
+  })
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.remove('A/B/E/alpha', 'A/B/E/beta', 'A/B/E')
+  expected_disk.add({
+    'A/B/E2'           : Item(),
+    'A/B/E2/alpha'     : Item(contents="This is the file 'alpha'.\n"),
+    'A/B/E2/beta'      : Item(contents="This is the file 'beta'.\n"),
+    'A/B/E2/foo'       : Item(contents=foo_content),
+  })
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
+  expected_status.tweak('A/B/E', 'A/B/E/alpha', 'A/B/E/beta', status='D ')
+  expected_status.add({
+    'A/B/E/foo'         : Item(status='D ', wc_rev='2'),
+    'A/B/E2'            : Item(status='A ', copied='+', wc_rev='-'),
+    'A/B/E2/beta'       : Item(status='  ', copied='+', wc_rev='-'),
+    'A/B/E2/alpha'      : Item(status='  ', copied='+', wc_rev='-'),
+    'A/B/E2/foo'        : Item(status='A ', copied='+', wc_rev='-'),
+  })
+  svntest.actions.run_and_verify_update(wc_dir,
+                                        expected_output,
+                                        expected_disk,
+                                        expected_status,
+                                        None, None, None,
+                                        None, None, 1)
+
+def update_moved_dir_dir_add(sbox):
+  "update locally moved dir with incoming dir"
+  sbox.build()
+  wc_dir = sbox.wc_dir
+  foo_path = "A/B/E/foo"
+  bar_path = "A/B/E/foo/bar"
+  bar_content = "This is the file 'bar'.\n"
+
+  sbox.simple_mkdir(foo_path)
+  svntest.main.file_write(sbox.ospath(bar_path), bar_content, 'wb')
+  sbox.simple_add(bar_path)
+  sbox.simple_commit()
+  # update to go back in time, before the last commit
+  svntest.main.run_svn(False, 'update', '-r', '1', wc_dir)
+  sbox.simple_move("A/B/E", "A/B/E2")
+
+  # the incoming file should auto-merge
+  expected_output = svntest.wc.State(wc_dir, {
+    'A/B/E2/foo'      : Item(status='A '),
+    'A/B/E2/foo/bar'  : Item(status='A '),
+  })
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.remove('A/B/E/alpha', 'A/B/E/beta', 'A/B/E')
+  expected_disk.add({
+    'A/B/E2'           : Item(),
+    'A/B/E2/alpha'     : Item(contents="This is the file 'alpha'.\n"),
+    'A/B/E2/beta'      : Item(contents="This is the file 'beta'.\n"),
+    'A/B/E2/foo'       : Item(),
+    'A/B/E2/foo/bar'   : Item(contents=bar_content),
+  })
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
+  expected_status.tweak('A/B/E', 'A/B/E/alpha', 'A/B/E/beta', status='D ')
+  expected_status.add({
+    'A/B/E/foo'         : Item(status='D ', wc_rev='2'),
+    'A/B/E/foo/bar'     : Item(status='D ', wc_rev='2'),
+    'A/B/E2'            : Item(status='A ', copied='+', wc_rev='-'),
+    'A/B/E2/beta'       : Item(status='  ', copied='+', wc_rev='-'),
+    'A/B/E2/alpha'      : Item(status='  ', copied='+', wc_rev='-'),
+    'A/B/E2/foo'        : Item(status='A ', copied='+', wc_rev='-'),
+    'A/B/E2/foo/bar'    : Item(status='A ', copied='+', wc_rev='-'),
+  })
+  svntest.actions.run_and_verify_update(wc_dir,
+                                        expected_output,
+                                        expected_disk,
+                                        expected_status,
+                                        None, None, None,
+                                        None, None, 1)
+
+@XFail()
+@Issue(4037)
+def update_moved_dir_file_move(sbox):
+  "update locally moved dir with incoming file move"
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  sbox.simple_move("A/B/E/alpha", "A/B/F/alpha")
+  sbox.simple_commit()
+  # update to go back in time, before the previous commit
+  svntest.main.run_svn(False, 'update', '-r', '1', wc_dir)
+  sbox.simple_move("A/B/E", "A/B/E2")
+
+  # The incoming move should auto-merge such that A/B/F/alpha appears
+  # as moved to A/B/E2/alpha -- this strategy prefers the local user's
+  # change as the solution to the conflict.
+  # ### Ideally, the user should be offered a set of alternative solutions.
+  # ### E.g. the user might prefer if A/B/E2/alpha disappeared and A/B/E/alpha
+  # ### appeared as moved to A/B/F/alpha. But the --accept option does not yet
+  # ### support tree conflicts.
+  expected_output = svntest.wc.State(wc_dir, {
+    'A/B/E2/alpha' : Item(status='A '),
+  })
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.remove('A/B/E/alpha', 'A/B/E/beta', 'A/B/E')
+  expected_disk.add({
+    'A/B/E2'           : Item(),
+    'A/B/E2/alpha'     : Item(contents="This is the file 'alpha'.\n"),
+    'A/B/E2/beta'      : Item(contents="This is the file 'beta'.\n"),
+  })
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
+  expected_status.tweak('A/B/E', 'A/B/E/alpha', 'A/B/E/beta', status='D ')
+  expected_status.add({
+    'A/B/F/alpha'       : Item(status='D '),
+    'A/B/E2'            : Item(status='A ', copied='+', wc_rev='-'),
+    'A/B/E2/alpha'      : Item(status='A ', copied='+', wc_rev='-'),
+    'A/B/E2/beta'       : Item(status='  ', copied='+', wc_rev='-'),
+  })
+  svntest.actions.run_and_verify_update(wc_dir,
+                                        expected_output,
+                                        expected_disk,
+                                        expected_status,
+                                        None, None, None,
+                                        None, None, 1)
 
 #######################################################################
 # Run the tests
@@ -5471,6 +5677,11 @@ test_list = [ None,
               revive_children_of_copy,
               skip_access_denied,
               update_to_HEAD_plus_1,
+              update_moved_dir_leaf_del,
+              update_moved_dir_edited_leaf_del,
+              update_moved_dir_file_add,
+              update_moved_dir_dir_add,
+              update_moved_dir_file_move,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/showing-merge-info/subversion/tests/cmdline/upgrade_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/tests/cmdline/upgrade_tests.py?rev=1186075&r1=1186074&r2=1186075&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/tests/cmdline/upgrade_tests.py (original)
+++ subversion/branches/showing-merge-info/subversion/tests/cmdline/upgrade_tests.py Wed Oct 19 10:33:19 2011
@@ -75,6 +75,23 @@ def replace_sbox_with_tarfile(sbox, tar_
 
   shutil.move(os.path.join(extract_dir, dir), sbox.wc_dir)
 
+def replace_sbox_repo_with_tarfile(sbox, tar_filename, dir=None):
+  try:
+    svntest.main.safe_rmtree(sbox.repo_dir)
+  except OSError, e:
+    pass
+
+  if not dir:
+    dir = tar_filename.split('.')[0]
+    
+  tarpath = os.path.join(os.path.dirname(sys.argv[0]), 'upgrade_tests_data',
+                         tar_filename)
+  t = tarfile.open(tarpath, 'r:bz2')
+  extract_dir = tempfile.mkdtemp(dir=svntest.main.temp_dir)
+  for member in t.getmembers():
+    t.extract(member, extract_dir)
+
+  shutil.move(os.path.join(extract_dir, dir), sbox.repo_dir)
 
 def check_format(sbox, expected_format):
   dot_svn = svntest.main.get_admin_name()
@@ -1181,6 +1198,41 @@ def upgrade_file_externals(sbox):
       'alpha' : {'pname3' : 'pvalue3' },
       })
 
+@Skip(svntest.main.is_ra_type_file)
+def upgrade_absent(sbox):
+  "upgrade absent nodes to server-excluded"
+
+  # Install wc and repos
+  replace_sbox_with_tarfile(sbox, 'upgrade_absent.tar.bz2')
+  replace_sbox_repo_with_tarfile(sbox, 'upgrade_absent_repos.tar.bz2')
+
+  # Update config for authz
+  svntest.main.write_restrictive_svnserve_conf(sbox.repo_dir)
+  svntest.main.write_authz_file(sbox, { "/"      : "*=rw",
+                                        "/A/B"   : "*=",
+                                        "/A/B/E" : "jrandom = rw"})
+
+  # Attempt to use the working copy, this should give an error
+  expected_stderr = wc_is_too_old_regex
+  svntest.actions.run_and_verify_svn(None, None, expected_stderr,
+                                     'info', sbox.wc_dir)
+
+  # Now upgrade the working copy
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'upgrade', sbox.wc_dir)
+
+  # Relocate to allow finding the repository
+  svntest.actions.run_and_verify_svn(None, None, [], 'relocate',
+                                     'svn://127.0.0.1/authz_tests-2',
+                                     sbox.repo_url, sbox.wc_dir)  
+
+  expected_output = svntest.wc.State(sbox.wc_dir, {
+  })
+
+  # Expect no changes and certainly no errors
+  svntest.actions.run_and_verify_update(sbox.wc_dir, expected_output,
+                                        None, None)
+
 ########################################################################
 # Run the tests
 
@@ -1230,6 +1282,7 @@ test_list = [ None,
               upgrade_with_missing_subdir,
               upgrade_locked,
               upgrade_file_externals,
+              upgrade_absent,
              ]
 
 

Modified: subversion/branches/showing-merge-info/subversion/tests/libsvn_subr/cache-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/tests/libsvn_subr/cache-test.c?rev=1186075&r1=1186074&r2=1186075&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/tests/libsvn_subr/cache-test.c (original)
+++ subversion/branches/showing-merge-info/subversion/tests/libsvn_subr/cache-test.c Wed Oct 19 10:33:19 2011
@@ -135,7 +135,7 @@ test_inprocess_cache_basic(apr_pool_t *p
                                       APR_HASH_KEY_STRING,
                                       1,
                                       1,
-                                      APR_HAS_THREADS,
+                                      TRUE,
                                       "",
                                       pool));
 
@@ -182,16 +182,9 @@ test_membuffer_cache_basic(apr_pool_t *p
 {
   svn_cache__t *cache;
   svn_membuffer_t *membuffer;
-  svn_boolean_t thread_safe;
-
-#if APR_HAS_THREADS
-  thread_safe = TRUE;
-#else
-  thread_safe = FALSE;
-#endif
 
   SVN_ERR(svn_cache__membuffer_cache_create(&membuffer, 10*1024, 1,
-                                            thread_safe, pool));
+                                            TRUE, pool));
 
   /* Create a cache with just one entry. */
   SVN_ERR(svn_cache__create_membuffer_cache(&cache,

Modified: subversion/branches/showing-merge-info/subversion/tests/libsvn_wc/op-depth-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/subversion/tests/libsvn_wc/op-depth-test.c?rev=1186075&r1=1186074&r2=1186075&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/branches/showing-merge-info/subversion/tests/libsvn_wc/op-depth-test.c Wed Oct 19 10:33:19 2011
@@ -77,7 +77,7 @@ open_wc_db(svn_sqlite__db_t **sdb,
            apr_pool_t *scratch_pool)
 {
   SVN_ERR(svn_wc__db_util_open_db(sdb, wc_root_abspath, "wc.db",
-                                  svn_sqlite__mode_readonly, my_statements,
+                                  svn_sqlite__mode_readwrite, my_statements,
                                   result_pool, scratch_pool));
   return SVN_NO_ERROR;
 }
@@ -481,6 +481,7 @@ check_db_rows(svn_test__sandbox_t *b,
   /* Compare EXPECTED_HASH with ACTUAL_HASH and return any errors. */
   SVN_ERR(svn_hash_diff(expected_hash, found_hash,
                         compare_nodes_rows, &comparison_baton, b->pool));
+  SVN_ERR(svn_sqlite__close(sdb));
   return comparison_baton.errors;
 }
 

Modified: subversion/branches/showing-merge-info/tools/dev/benchmarks/suite1/benchmark.py
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/tools/dev/benchmarks/suite1/benchmark.py?rev=1186075&r1=1186074&r2=1186075&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/tools/dev/benchmarks/suite1/benchmark.py (original)
+++ subversion/branches/showing-merge-info/tools/dev/benchmarks/suite1/benchmark.py Wed Oct 19 10:33:19 2011
@@ -141,7 +141,7 @@ class Timings:
     return '\n'.join(s)
 
 
-  def compare_to(self, other):
+  def compare_to(self, other, verbose):
     def do_div(a, b):
       if b:
         return float(a) / float(b)
@@ -170,7 +170,10 @@ class Timings:
                % (' ' * len(TOTAL_RUN), selftotal, selfname))
 
 
-    s.append('      min              max              avg         operation')
+    if not verbose:
+      s.append('      avg         operation')
+    else:
+      s.append('      min              max              avg         operation')
 
     names = sorted(self.timings.keys())
 
@@ -182,23 +185,18 @@ class Timings:
       min_me, max_me, avg_me = self.min_max_avg(name)
       min_other, max_other, avg_other = other.min_max_avg(name)
 
-      s.append('%-16s %-16s %-16s  %s' % (
-                 '%7.2f|%+7.3f' % (
-                     do_div(min_me, min_other),
-                     do_diff(min_me, min_other)
-                   ),
-
-                 '%7.2f|%+7.3f' % (
-                     do_div(max_me, max_other),
-                     do_diff(max_me, max_other)
-                   ),
-
-                 '%7.2f|%+7.3f' % (
-                     do_div(avg_me, avg_other),
-                     do_diff(avg_me, avg_other)
-                   ),
+      avg_str = '%7.2f|%+7.3f' % (do_div(avg_me, avg_other),
+                                  do_diff(avg_me, avg_other))
 
-                 name))
+      if not verbose:
+        s.append('%-16s  %s' % (avg_str, name))
+      else:
+        min_str = '%7.2f|%+7.3f' % (do_div(min_me, min_other),
+                                    do_diff(min_me, min_other))
+        max_str = '%7.2f|%+7.3f' % (do_div(max_me, max_other),
+                                    do_diff(max_me, max_other))
+
+        s.append('%-16s %-16s %-16s  %s' % (min_str, max_str, avg_str, name))
 
     s.extend([
       '(legend: "1.23|+0.45" means: slower by factor 1.23 and by 0.45 seconds;',
@@ -296,6 +294,9 @@ def up(*args):
 def st(*args):
   return svn('status', *args)
 
+def info(*args):
+  return svn('info', *args)
+
 _chars = [chr(x) for x in range(ord('a'), ord('z') +1)]
 
 def randstr(len=8):
@@ -444,6 +445,7 @@ def run(levels, spread, N):
         ci(wc)
         up(wc)
         st(wc)
+        info('-R', wc)
 
         trunk_url = file_url + '/trunk'
         branch_url = file_url + '/branch'
@@ -453,6 +455,7 @@ def run(levels, spread, N):
 
         up(wc)
         st(wc)
+        info('-R', wc)
 
         svn('checkout', trunk_url, wc2)
         st(wc2)
@@ -465,6 +468,7 @@ def run(levels, spread, N):
         svn('switch', branch_url, wc2)
         modify_tree(wc2, 0.5)
         st(wc2)
+        info('-R', wc2)
         ci(wc2)
         up(wc2)
         up(wc)
@@ -477,10 +481,12 @@ def run(levels, spread, N):
 
         svn('merge', '--accept=postpone', trunk_url, wc2)
         st(wc2)
+        info('-R', wc2)
         svn('resolve', '--accept=mine-conflict', wc2)
         st(wc2)
         svn('resolved', '-R', wc2)
         st(wc2)
+        info('-R', wc2)
         ci(wc2)
         up(wc2)
         up(wc)
@@ -542,11 +548,12 @@ def cmd_compare(path1, path2):
   t1 = read_from_file(path1)
   t2 = read_from_file(path2)
 
-  print t1.summary()
-  print '---'
-  print t2.summary()
-  print '---'
-  print t2.compare_to(t1)
+  if options.verbose:
+    print t1.summary()
+    print '---'
+    print t2.summary()
+    print '---'
+  print t2.compare_to(t1, options.verbose)
 
 def cmd_combine(dest, *paths):
   total = Timings('--version');

Modified: subversion/branches/showing-merge-info/tools/dev/benchmarks/suite1/cronjob
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/tools/dev/benchmarks/suite1/cronjob?rev=1186075&r1=1186074&r2=1186075&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/tools/dev/benchmarks/suite1/cronjob (original)
+++ subversion/branches/showing-merge-info/tools/dev/benchmarks/suite1/cronjob Wed Oct 19 10:33:19 2011
@@ -22,8 +22,14 @@
 # This is the cronjob as run on our ASF box aka svn-qavm.
 # It uses neels' mad bash script magic called 'pat' to update and
 # build the latest trunk, invokes a benchmark and sends as mail.
+#
+# A word on 'pat': this is a grown-out-of-proportions bash script that holds
+# all the small and large tasks that I do while developing on Subversion.
+# While it works for me, it's not particularly beautifully coded --
+# wouldn't publish it in Subversion's trunk, but if you want to find out
+# what it does: http://hofmeyr.de/pat/
 
-#EMAILS=your@email.addresses
+#EMAILS=your@ema.il add@ress.es
 EMAILS=""
 
 if [ "$USER" = "neels" ]; then
@@ -59,7 +65,7 @@ else
     echo "$subject"
   else
 
-    /home/neels/bin/pat remake
+    NONMAINTAINER=1 /home/neels/bin/pat remake
     if [ "$?" -ne "0" ]; then
       subject="Failed to build $rev."
       echo "$subject" > "$results"

Modified: subversion/branches/showing-merge-info/tools/dev/benchmarks/suite1/run
URL: http://svn.apache.org/viewvc/subversion/branches/showing-merge-info/tools/dev/benchmarks/suite1/run?rev=1186075&r1=1186074&r2=1186075&view=diff
==============================================================================
--- subversion/branches/showing-merge-info/tools/dev/benchmarks/suite1/run (original)
+++ subversion/branches/showing-merge-info/tools/dev/benchmarks/suite1/run Wed Oct 19 10:33:19 2011
@@ -44,13 +44,8 @@ batch(){
   spread="$2"
   N="$3"
   pre="${levels}x${spread}_"
-  echo
-  echo "---------------------------------------------------------------------"
-  echo
-  echo "Results for dir levels: $levels  spread: $spread"
   "$benchmark" "--svn=$SVN_A" run "${pre}$SVN_A_NAME" $levels $spread $N >/dev/null
   "$benchmark" "--svn=$SVN_B" run "${pre}$SVN_B_NAME" $levels $spread $N >/dev/null
-  "$benchmark" compare "${pre}$SVN_A_NAME" "${pre}$SVN_B_NAME"
 }
 
 N=6
@@ -75,22 +70,44 @@ cs=100
 {
 started="$(date)"
 echo "Started at $started"
-echo ""
 
 batch $al $as $N
 batch $bl $bs $N
 batch $cl $cs $N
 
-echo ""
-echo =========================================================================
-echo ""
 "$benchmark" combine "total_$SVN_A_NAME" *x*"_$SVN_A_NAME" >/dev/null
 "$benchmark" combine "total_$SVN_B_NAME" *x*"_$SVN_B_NAME" >/dev/null
 
-echo "comparing averaged totals..."
+echo ""
+echo "Averaged-total results across all runs:"
+echo "---------------------------------------"
+echo ""
 "$benchmark" compare "total_$SVN_A_NAME" "total_$SVN_B_NAME"
 
 echo ""
+echo ""
+echo "Above totals split into separate <dir-levels>x<dir-spread> runs:"
+echo "----------------------------------------------------------------"
+echo ""
+
+for pre in "${al}x${as}_" "${bl}x${bs}_" "${cl}x${cs}_"; do
+  "$benchmark" compare "${pre}$SVN_A_NAME" "${pre}$SVN_B_NAME"
+  echo ""
+done
+
+echo ""
+echo ""
+echo "More detail:"
+echo "------------"
+echo ""
+
+for pre in "${al}x${as}_" "${bl}x${bs}_" "${cl}x${cs}_" "total_"; do
+  "$benchmark" compare -v "${pre}$SVN_A_NAME" "${pre}$SVN_B_NAME"
+  echo ""
+  echo ""
+done
+
+echo ""
 echo "Had started at $started,"
 echo "       done at $(date)"
 pwd