subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hwri...@apache.org
Subject svn commit: r1424772 [2/4] - in /subversion/branches/ev2-export: ./ build/ build/ac-macros/ build/win32/ subversion/bindings/cxxhl/include/ subversion/bindings/cxxhl/include/svncxxhl/ subversion/bindings/cxxhl/include/types/ subversion/bindings/cxxhl/s...
Date Fri, 21 Dec 2012 00:23:41 GMT
Modified: subversion/branches/ev2-export/subversion/libsvn_client/repos_diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/repos_diff.c?rev=1424772&r1=1424771&r2=1424772&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/repos_diff.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/repos_diff.c Fri Dec 21 00:23:39 2012
@@ -143,6 +143,9 @@ struct dir_baton {
   /* A cache of any property changes (svn_prop_t) received for this dir. */
   apr_array_header_t *propchanges;
 
+  /* Boolean indicating whether a node property was changed */
+  svn_boolean_t has_propchange;
+
   /* The pool passed in by add_dir, open_dir, or open_root.
      Also, the pool this dir baton is allocated in. */
   apr_pool_t *pool;
@@ -199,6 +202,9 @@ struct file_baton {
   /* A cache of any property changes (svn_prop_t) received for this file. */
   apr_array_header_t *propchanges;
 
+  /* Boolean indicating whether a node property was changed */
+  svn_boolean_t has_propchange;
+
   /* The pool passed in by add_file or open_file.
      Also, the pool this file_baton is allocated in. */
   apr_pool_t *pool;
@@ -230,7 +236,7 @@ make_dir_baton(const char *path,
   dir_baton->skip_children = FALSE;
   dir_baton->pool = dir_pool;
   dir_baton->path = apr_pstrdup(dir_pool, path);
-  dir_baton->propchanges  = apr_array_make(pool, 1, sizeof(svn_prop_t));
+  dir_baton->propchanges  = apr_array_make(pool, 8, sizeof(svn_prop_t));
   dir_baton->base_revision = base_revision;
 
   return dir_baton;
@@ -256,7 +262,7 @@ make_file_baton(const char *path,
   file_baton->skip = FALSE;
   file_baton->pool = file_pool;
   file_baton->path = apr_pstrdup(file_pool, path);
-  file_baton->propchanges  = apr_array_make(pool, 1, sizeof(svn_prop_t));
+  file_baton->propchanges  = apr_array_make(pool, 8, sizeof(svn_prop_t));
   file_baton->base_revision = edit_baton->revision;
 
   return file_baton;
@@ -271,29 +277,29 @@ make_file_baton(const char *path,
 static void
 get_file_mime_types(const char **mimetype1,
                     const char **mimetype2,
-                    struct file_baton *b)
+                    struct file_baton *fb)
 {
   /* Defaults */
   *mimetype1 = NULL;
   *mimetype2 = NULL;
 
-  if (b->pristine_props)
+  if (fb->pristine_props)
     {
       svn_string_t *pristine_val;
-      pristine_val = apr_hash_get(b->pristine_props, SVN_PROP_MIME_TYPE,
+      pristine_val = apr_hash_get(fb->pristine_props, SVN_PROP_MIME_TYPE,
                                   strlen(SVN_PROP_MIME_TYPE));
       if (pristine_val)
         *mimetype2 = *mimetype1 = pristine_val->data;
     }
 
-  if (b->propchanges)
+  if (fb->propchanges)
     {
       int i;
       svn_prop_t *propchange;
 
-      for (i = 0; i < b->propchanges->nelts; i++)
+      for (i = 0; i < fb->propchanges->nelts; i++)
         {
-          propchange = &APR_ARRAY_IDX(b->propchanges, i, svn_prop_t);
+          propchange = &APR_ARRAY_IDX(fb->propchanges, i, svn_prop_t);
           if (strcmp(propchange->name, SVN_PROP_MIME_TYPE) == 0)
             {
               if (propchange->value)
@@ -305,22 +311,22 @@ get_file_mime_types(const char **mimetyp
 }
 
 
-/* Get revision B->base_revision of the file described by B from the
- * repository, through B->edit_baton->ra_session.
+/* Get revision FB->base_revision of the file described by FB from the
+ * repository, through FB->edit_baton->ra_session.
  *
  * Unless PROPS_ONLY is true:
- *   Set B->path_start_revision to the path of a new temporary file containing
+ *   Set FB->path_start_revision to the path of a new temporary file containing
  *   the file's text.
- *   Set B->start_md5_checksum to that file's MD-5 checksum.
- *   Install a pool cleanup handler on B->pool to delete the file.
+ *   Set FB->start_md5_checksum to that file's MD-5 checksum.
+ *   Install a pool cleanup handler on FB->pool to delete the file.
  *
  * Always:
- *   Set B->pristine_props to a new hash containing the file's properties.
+ *   Set FB->pristine_props to a new hash containing the file's properties.
  *
- * Allocate all results in B->pool.
+ * Allocate all results in FB->pool.
  */
 static svn_error_t *
-get_file_from_ra(struct file_baton *b,
+get_file_from_ra(struct file_baton *fb,
                  svn_boolean_t props_only,
                  apr_pool_t *scratch_pool)
 {
@@ -328,30 +334,30 @@ get_file_from_ra(struct file_baton *b,
     {
       svn_stream_t *fstream;
 
-      SVN_ERR(svn_stream_open_unique(&fstream, &(b->path_start_revision), NULL,
-                                     svn_io_file_del_on_pool_cleanup,
-                                     b->pool, scratch_pool));
+      SVN_ERR(svn_stream_open_unique(&fstream, &(fb->path_start_revision),
+                                     NULL, svn_io_file_del_on_pool_cleanup,
+                                     fb->pool, scratch_pool));
 
-      fstream = svn_stream_checksummed2(fstream, NULL, &b->start_md5_checksum,
+      fstream = svn_stream_checksummed2(fstream, NULL, &fb->start_md5_checksum,
                                         svn_checksum_md5, TRUE, scratch_pool);
 
       /* Retrieve the file and its properties */
-      SVN_ERR(svn_ra_get_file(b->edit_baton->ra_session,
-                              b->path,
-                              b->base_revision,
+      SVN_ERR(svn_ra_get_file(fb->edit_baton->ra_session,
+                              fb->path,
+                              fb->base_revision,
                               fstream, NULL,
-                              &(b->pristine_props),
-                              b->pool));
+                              &(fb->pristine_props),
+                              fb->pool));
       SVN_ERR(svn_stream_close(fstream));
     }
   else
     {
-      SVN_ERR(svn_ra_get_file(b->edit_baton->ra_session,
-                              b->path,
-                              b->base_revision,
+      SVN_ERR(svn_ra_get_file(fb->edit_baton->ra_session,
+                              fb->path,
+                              fb->base_revision,
                               NULL, NULL,
-                              &(b->pristine_props),
-                              b->pool));
+                              &(fb->pristine_props),
+                              fb->pool));
     }
 
   return SVN_NO_ERROR;
@@ -461,10 +467,10 @@ open_root(void *edit_baton,
           void **root_baton)
 {
   struct edit_baton *eb = edit_baton;
-  struct dir_baton *b = make_dir_baton("", NULL, eb, FALSE, base_revision,
-                                       pool);
+  struct dir_baton *db = make_dir_baton("", NULL, eb, FALSE, base_revision,
+                                        pool);
 
-  *root_baton = b;
+  *root_baton = db;
   return SVN_NO_ERROR;
 }
 
@@ -477,26 +483,26 @@ diff_deleted_file(svn_wc_notify_state_t 
                   struct edit_baton *eb,
                   apr_pool_t *scratch_pool)
 {
-  struct file_baton *b = make_file_baton(path, FALSE, eb, scratch_pool);
-/*  struct edit_baton *eb = b->edit_baton;*/
+  struct file_baton *fb = make_file_baton(path, FALSE, eb, scratch_pool);
+/*  struct edit_baton *eb = fb->edit_baton;*/
   const char *mimetype1, *mimetype2;
 
   if (eb->cancel_func)
     SVN_ERR(eb->cancel_func(eb->cancel_baton));
 
   if (eb->text_deltas)
-    SVN_ERR(get_file_from_ra(b, FALSE, scratch_pool));
+    SVN_ERR(get_file_from_ra(fb, FALSE, scratch_pool));
   else
-    SVN_ERR(get_empty_file(eb, &b->path_start_revision));
-  SVN_ERR(get_empty_file(eb, &b->path_end_revision));
-  get_file_mime_types(&mimetype1, &mimetype2, b);
+    SVN_ERR(get_empty_file(eb, &fb->path_start_revision));
+  SVN_ERR(get_empty_file(eb, &fb->path_end_revision));
+  get_file_mime_types(&mimetype1, &mimetype2, fb);
 
   SVN_ERR(eb->diff_callbacks->file_deleted(state_p, tree_conflicted_p,
-                                           b->path,
-                                           b->path_start_revision,
-                                           b->path_end_revision,
+                                           fb->path,
+                                           fb->path_start_revision,
+                                           fb->path_end_revision,
                                            mimetype1, mimetype2,
-                                           b->pristine_props,
+                                           fb->pristine_props,
                                            eb->diff_cmd_baton,
                                            scratch_pool));
   return SVN_NO_ERROR;
@@ -654,26 +660,26 @@ add_directory(const char *path,
 {
   struct dir_baton *pb = parent_baton;
   struct edit_baton *eb = pb->edit_baton;
-  struct dir_baton *b;
+  struct dir_baton *db;
   svn_wc_notify_state_t state;
 
   /* ### TODO: support copyfrom? */
 
-  b = make_dir_baton(path, pb, eb, TRUE, SVN_INVALID_REVNUM, pool);
-  *child_baton = b;
+  db = make_dir_baton(path, pb, eb, TRUE, SVN_INVALID_REVNUM, pool);
+  *child_baton = db;
 
   /* Skip *everything* within a newly tree-conflicted directory,
    * and directories the children of which should be skipped. */
   if (pb->skip || pb->tree_conflicted || pb->skip_children)
     {
-      b->skip = TRUE;
+      db->skip = TRUE;
       return SVN_NO_ERROR;
     }
 
 
   SVN_ERR(eb->diff_callbacks->dir_added(
-                &state, &b->tree_conflicted,
-                &b->skip, &b->skip_children, b->path,
+                &state, &db->tree_conflicted,
+                &db->skip, &db->skip_children, db->path,
                 eb->target_revision, copyfrom_path, copyfrom_revision,
                 eb->diff_cmd_baton, pool));
 
@@ -692,12 +698,12 @@ add_directory(const char *path,
 
       /* Find out if a pending delete notification for this path is
        * still around. */
-      dpn = apr_hash_get(eb->deleted_paths, b->path, APR_HASH_KEY_STRING);
+      dpn = apr_hash_get(eb->deleted_paths, db->path, APR_HASH_KEY_STRING);
       if (dpn)
         {
           /* If any was found, we will handle the pending 'deleted path
            * notification' (DPN) here. Remove it from the list. */
-          apr_hash_set(eb->deleted_paths, b->path,
+          apr_hash_set(eb->deleted_paths, db->path,
                        APR_HASH_KEY_STRING, NULL);
 
           /* the pending delete might be on a different node kind. */
@@ -707,7 +713,7 @@ add_directory(const char *path,
 
       /* Determine what the notification (ACTION) should be.
        * In case of a pending 'delete', this might become a 'replace'. */
-      if (b->tree_conflicted)
+      if (db->tree_conflicted)
         action = svn_wc_notify_tree_conflict;
       else if (dpn)
         {
@@ -723,7 +729,7 @@ add_directory(const char *path,
       else
         action = svn_wc_notify_update_add;
 
-      notify = svn_wc_create_notify(b->path, action, pool);
+      notify = svn_wc_create_notify(db->path, action, pool);
       notify->kind = kind;
       notify->content_state = notify->prop_state = state;
       (*eb->notify_func)(eb->notify_baton, notify, pool);
@@ -742,24 +748,24 @@ open_directory(const char *path,
 {
   struct dir_baton *pb = parent_baton;
   struct edit_baton *eb = pb->edit_baton;
-  struct dir_baton *b;
+  struct dir_baton *db;
 
-  b = make_dir_baton(path, pb, pb->edit_baton, FALSE, base_revision, pool);
+  db = make_dir_baton(path, pb, eb, FALSE, base_revision, pool);
 
-  *child_baton = b;
+  *child_baton = db;
 
   /* Skip *everything* within a newly tree-conflicted directory
    * and directories the children of which should be skipped. */
   if (pb->skip || pb->tree_conflicted || pb->skip_children)
     {
-      b->skip = TRUE;
+      db->skip = TRUE;
       return SVN_NO_ERROR;
     }
 
   SVN_ERR(eb->diff_callbacks->dir_opened(
-                &b->tree_conflicted, &b->skip,
-                &b->skip_children, b->path, base_revision,
-                b->edit_baton->diff_cmd_baton, pool));
+                &db->tree_conflicted, &db->skip,
+                &db->skip_children, db->path, base_revision,
+                eb->diff_cmd_baton, pool));
 
   return SVN_NO_ERROR;
 }
@@ -775,22 +781,22 @@ add_file(const char *path,
          void **file_baton)
 {
   struct dir_baton *pb = parent_baton;
-  struct file_baton *b;
+  struct file_baton *fb;
 
   /* ### TODO: support copyfrom? */
 
-  b = make_file_baton(path, TRUE, pb->edit_baton, pool);
-  *file_baton = b;
+  fb = make_file_baton(path, TRUE, pb->edit_baton, pool);
+  *file_baton = fb;
 
   /* Skip *everything* within a newly tree-conflicted directory.
    * and directories the children of which should be skipped. */
   if (pb->skip || pb->tree_conflicted || pb->skip_children)
     {
-      b->skip = TRUE;
+      fb->skip = TRUE;
       return SVN_NO_ERROR;
     }
 
-  b->pristine_props = pb->edit_baton->empty_hash;
+  fb->pristine_props = pb->edit_baton->empty_hash;
 
   return SVN_NO_ERROR;
 }
@@ -804,24 +810,24 @@ open_file(const char *path,
           void **file_baton)
 {
   struct dir_baton *pb = parent_baton;
-  struct file_baton *b;
+  struct file_baton *fb;
   struct edit_baton *eb = pb->edit_baton;
-  b = make_file_baton(path, FALSE, pb->edit_baton, pool);
-  *file_baton = b;
+  fb = make_file_baton(path, FALSE, pb->edit_baton, pool);
+  *file_baton = fb;
 
   /* Skip *everything* within a newly tree-conflicted directory
    * and directories the children of which should be skipped. */
   if (pb->skip || pb->tree_conflicted || pb->skip_children)
     {
-      b->skip = TRUE;
+      fb->skip = TRUE;
       return SVN_NO_ERROR;
     }
 
-  b->base_revision = base_revision;
+  fb->base_revision = base_revision;
 
   SVN_ERR(eb->diff_callbacks->file_opened(
-                   &b->tree_conflicted, &b->skip,
-                   b->path, base_revision, eb->diff_cmd_baton, pool));
+                   &fb->tree_conflicted, &fb->skip,
+                   fb->path, base_revision, eb->diff_cmd_baton, pool));
 
   return SVN_NO_ERROR;
 }
@@ -831,14 +837,15 @@ static svn_error_t *
 window_handler(svn_txdelta_window_t *window,
                void *window_baton)
 {
-  struct file_baton *b = window_baton;
+  struct file_baton *fb = window_baton;
 
-  SVN_ERR(b->apply_handler(window, b->apply_baton));
+  SVN_ERR(fb->apply_handler(window, fb->apply_baton));
 
   if (!window)
     {
-      b->result_md5_checksum = svn_checksum__from_digest_md5(b->result_digest,
-                                                             b->pool);
+      fb->result_md5_checksum = svn_checksum__from_digest_md5(
+                                        fb->result_digest,
+                                        fb->pool);
     }
 
   return SVN_NO_ERROR;
@@ -852,13 +859,13 @@ apply_textdelta(void *file_baton,
                 svn_txdelta_window_handler_t *handler,
                 void **handler_baton)
 {
-  struct file_baton *b = file_baton;
+  struct file_baton *fb = file_baton;
   svn_stream_t *src_stream;
   svn_stream_t *result_stream;
-  apr_pool_t *scratch_pool = b->pool;
+  apr_pool_t *scratch_pool = fb->pool;
 
   /* Skip *everything* within a newly tree-conflicted directory. */
-  if (b->skip)
+  if (fb->skip)
     {
       *handler = svn_delta_noop_window_handler;
       *handler_baton = NULL;
@@ -866,11 +873,11 @@ apply_textdelta(void *file_baton,
     }
 
   /* If we're not sending file text, then ignore any that we receive. */
-  if (! b->edit_baton->text_deltas)
+  if (! fb->edit_baton->text_deltas)
     {
       /* Supply valid paths to indicate there is a text change. */
-      SVN_ERR(get_empty_file(b->edit_baton, &b->path_start_revision));
-      SVN_ERR(get_empty_file(b->edit_baton, &b->path_end_revision));
+      SVN_ERR(get_empty_file(fb->edit_baton, &fb->path_start_revision));
+      SVN_ERR(get_empty_file(fb->edit_baton, &fb->path_end_revision));
 
       *handler = svn_delta_noop_window_handler;
       *handler_baton = NULL;
@@ -879,12 +886,12 @@ apply_textdelta(void *file_baton,
     }
 
   /* We need the expected pristine file, so go get it */
-  if (!b->added)
-    SVN_ERR(get_file_from_ra(b, FALSE, scratch_pool));
+  if (!fb->added)
+    SVN_ERR(get_file_from_ra(fb, FALSE, scratch_pool));
   else
-    SVN_ERR(get_empty_file(b->edit_baton, &(b->path_start_revision)));
+    SVN_ERR(get_empty_file(fb->edit_baton, &(fb->path_start_revision)));
 
-  SVN_ERR_ASSERT(b->path_start_revision != NULL);
+  SVN_ERR_ASSERT(fb->path_start_revision != NULL);
 
   if (base_md5_digest != NULL)
     {
@@ -893,30 +900,30 @@ apply_textdelta(void *file_baton,
       SVN_ERR(svn_checksum_parse_hex(&base_md5_checksum, svn_checksum_md5,
                                      base_md5_digest, scratch_pool));
 
-      if (!svn_checksum_match(base_md5_checksum, b->start_md5_checksum))
+      if (!svn_checksum_match(base_md5_checksum, fb->start_md5_checksum))
         return svn_error_trace(svn_checksum_mismatch_err(
                                       base_md5_checksum,
-                                      b->start_md5_checksum,
+                                      fb->start_md5_checksum,
                                       scratch_pool,
                                       _("Base checksum mismatch for '%s'"),
-                                      b->path));
+                                      fb->path));
     }
 
   /* Open the file to be used as the base for second revision */
-  SVN_ERR(svn_stream_open_readonly(&src_stream, b->path_start_revision,
+  SVN_ERR(svn_stream_open_readonly(&src_stream, fb->path_start_revision,
                                    scratch_pool, scratch_pool));
 
   /* Open the file that will become the second revision after applying the
      text delta, it starts empty */
-  SVN_ERR(svn_stream_open_unique(&result_stream, &b->path_end_revision, NULL,
+  SVN_ERR(svn_stream_open_unique(&result_stream, &fb->path_end_revision, NULL,
                                  svn_io_file_del_on_pool_cleanup,
                                  scratch_pool, scratch_pool));
 
   svn_txdelta_apply(src_stream,
                     result_stream,
-                    b->result_digest,
-                    b->path, b->pool,
-                    &(b->apply_handler), &(b->apply_baton));
+                    fb->result_digest,
+                    fb->path, fb->pool,
+                    &(fb->apply_handler), &(fb->apply_baton));
 
   *handler = window_handler;
   *handler_baton = file_baton;
@@ -939,20 +946,20 @@ close_file(void *file_baton,
            const char *expected_md5_digest,
            apr_pool_t *pool)
 {
-  struct file_baton *b = file_baton;
-  struct edit_baton *eb = b->edit_baton;
+  struct file_baton *fb = file_baton;
+  struct edit_baton *eb = fb->edit_baton;
   svn_wc_notify_state_t content_state = svn_wc_notify_state_unknown;
   svn_wc_notify_state_t prop_state = svn_wc_notify_state_unknown;
   apr_pool_t *scratch_pool;
 
   /* Skip *everything* within a newly tree-conflicted directory. */
-  if (b->skip)
+  if (fb->skip)
     {
-      svn_pool_destroy(b->pool);
+      svn_pool_destroy(fb->pool);
       return SVN_NO_ERROR;
     }
 
-  scratch_pool = b->pool;
+  scratch_pool = fb->pool;
 
   if (expected_md5_digest && eb->text_deltas)
     {
@@ -961,57 +968,56 @@ close_file(void *file_baton,
       SVN_ERR(svn_checksum_parse_hex(&expected_md5_checksum, svn_checksum_md5,
                                      expected_md5_digest, scratch_pool));
 
-      if (!svn_checksum_match(expected_md5_checksum, b->result_md5_checksum))
+      if (!svn_checksum_match(expected_md5_checksum, fb->result_md5_checksum))
         return svn_error_trace(svn_checksum_mismatch_err(
                                       expected_md5_checksum,
-                                      b->result_md5_checksum,
+                                      fb->result_md5_checksum,
                                       pool,
                                       _("Checksum mismatch for '%s'"),
-                                      b->path));
+                                      fb->path));
     }
 
-  if (!b->added && b->propchanges->nelts > 0)
+  if (fb->path_end_revision || fb->has_propchange)
     {
-      if (!b->pristine_props)
+      const char *mimetype1, *mimetype2;
+
+      if (!fb->added && !fb->pristine_props)
         {
           /* We didn't receive a text change, so we have no pristine props.
              Retrieve just the props now. */
-          SVN_ERR(get_file_from_ra(b, TRUE, scratch_pool));
+          SVN_ERR(get_file_from_ra(fb, TRUE, scratch_pool));
         }
 
-      remove_non_prop_changes(b->pristine_props, b->propchanges);
-    }
+      if (fb->pristine_props)
+        remove_non_prop_changes(fb->pristine_props, fb->propchanges);
 
-  if (b->path_end_revision || b->propchanges->nelts > 0)
-    {
-      const char *mimetype1, *mimetype2;
-      get_file_mime_types(&mimetype1, &mimetype2, b);
+      get_file_mime_types(&mimetype1, &mimetype2, fb);
 
 
-      if (b->added)
+      if (fb->added)
         SVN_ERR(eb->diff_callbacks->file_added(
-                 &content_state, &prop_state, &b->tree_conflicted,
-                 b->path,
-                 b->path_end_revision ? b->path_start_revision : NULL,
-                 b->path_end_revision,
+                 &content_state, &prop_state, &fb->tree_conflicted,
+                 fb->path,
+                 fb->path_end_revision ? fb->path_start_revision : NULL,
+                 fb->path_end_revision,
                  0,
-                 b->edit_baton->target_revision,
+                 eb->target_revision,
                  mimetype1, mimetype2,
                  NULL, SVN_INVALID_REVNUM,
-                 b->propchanges, b->pristine_props,
-                 b->edit_baton->diff_cmd_baton,
+                 fb->propchanges, fb->pristine_props,
+                 eb->diff_cmd_baton,
                  scratch_pool));
       else
         SVN_ERR(eb->diff_callbacks->file_changed(
                  &content_state, &prop_state,
-                 &b->tree_conflicted, b->path,
-                 b->path_end_revision ? b->path_start_revision : NULL,
-                 b->path_end_revision,
-                 b->edit_baton->revision,
-                 b->edit_baton->target_revision,
+                 &fb->tree_conflicted, fb->path,
+                 fb->path_end_revision ? fb->path_start_revision : NULL,
+                 fb->path_end_revision,
+                 eb->revision,
+                 eb->target_revision,
                  mimetype1, mimetype2,
-                 b->propchanges, b->pristine_props,
-                 b->edit_baton->diff_cmd_baton,
+                 fb->propchanges, fb->pristine_props,
+                 eb->diff_cmd_baton,
                  scratch_pool));
     }
 
@@ -1025,12 +1031,12 @@ close_file(void *file_baton,
 
       /* Find out if a pending delete notification for this path is
        * still around. */
-      dpn = apr_hash_get(eb->deleted_paths, b->path, APR_HASH_KEY_STRING);
+      dpn = apr_hash_get(eb->deleted_paths, fb->path, APR_HASH_KEY_STRING);
       if (dpn)
         {
           /* If any was found, we will handle the pending 'deleted path
            * notification' (DPN) here. Remove it from the list. */
-          apr_hash_set(eb->deleted_paths, b->path,
+          apr_hash_set(eb->deleted_paths, fb->path,
                        APR_HASH_KEY_STRING, NULL);
 
           /* the pending delete might be on a different node kind. */
@@ -1040,12 +1046,12 @@ close_file(void *file_baton,
 
       /* Determine what the notification (ACTION) should be.
        * In case of a pending 'delete', this might become a 'replace'. */
-      if (b->tree_conflicted)
+      if (fb->tree_conflicted)
         action = svn_wc_notify_tree_conflict;
       else if (dpn)
         {
           if (dpn->action == svn_wc_notify_update_delete
-              && b->added)
+              && fb->added)
             action = svn_wc_notify_update_replace;
           else
             /* Note: dpn->action might be svn_wc_notify_tree_conflict */
@@ -1054,19 +1060,19 @@ close_file(void *file_baton,
       else if ((content_state == svn_wc_notify_state_missing)
                 || (content_state == svn_wc_notify_state_obstructed))
         action = svn_wc_notify_skip;
-      else if (b->added)
+      else if (fb->added)
         action = svn_wc_notify_update_add;
       else
         action = svn_wc_notify_update_update;
 
-      notify = svn_wc_create_notify(b->path, action, scratch_pool);
+      notify = svn_wc_create_notify(fb->path, action, scratch_pool);
       notify->kind = kind;
       notify->content_state = content_state;
       notify->prop_state = prop_state;
       (*eb->notify_func)(eb->notify_baton, notify, scratch_pool);
     }
 
-  svn_pool_destroy(b->pool); /* Destroy file and scratch pool */
+  svn_pool_destroy(fb->pool); /* Destroy file and scratch pool */
 
   return SVN_NO_ERROR;
 }
@@ -1082,8 +1088,8 @@ static svn_error_t *
 close_directory(void *dir_baton,
                 apr_pool_t *pool)
 {
-  struct dir_baton *b = dir_baton;
-  struct edit_baton *eb = b->edit_baton;
+  struct dir_baton *db = dir_baton;
+  struct edit_baton *eb = db->edit_baton;
   svn_wc_notify_state_t content_state = svn_wc_notify_state_unknown;
   svn_wc_notify_state_t prop_state = svn_wc_notify_state_unknown;
   svn_boolean_t skipped = FALSE;
@@ -1091,56 +1097,59 @@ close_directory(void *dir_baton,
   apr_hash_t *pristine_props;
 
   /* Skip *everything* within a newly tree-conflicted directory. */
-  if (b->skip)
+  if (db->skip)
     {
-      svn_pool_destroy(b->pool);
+      svn_pool_destroy(db->pool);
       return SVN_NO_ERROR;
     }
 
-  scratch_pool = b->pool;
+  scratch_pool = db->pool;
 
-  if (b->added)
-    {
-      pristine_props = eb->empty_hash;
-    }
-  else
+  if (db->has_propchange)
     {
-      SVN_ERR(svn_ra_get_dir2(eb->ra_session, NULL, NULL, &pristine_props,
-                              b->path, b->base_revision, 0, scratch_pool));
-    }
-
-  if (b->propchanges->nelts > 0)
-    {
-      remove_non_prop_changes(pristine_props, b->propchanges);
-    }
+      if (db->added)
+        {
+          pristine_props = eb->empty_hash;
+        }
+      else
+        {
+          SVN_ERR(svn_ra_get_dir2(eb->ra_session, NULL, NULL, &pristine_props,
+                                  db->path, db->base_revision, 0, scratch_pool));
+        }
 
-  if (b->propchanges->nelts > 0)
-    {
-      svn_boolean_t tree_conflicted = FALSE;
-      SVN_ERR(eb->diff_callbacks->dir_props_changed(
-               &prop_state, &tree_conflicted,
-               b->path, b->added,
-               b->propchanges, pristine_props,
-               b->edit_baton->diff_cmd_baton, scratch_pool));
-      if (tree_conflicted)
-        b->tree_conflicted = TRUE;
+      if (db->propchanges->nelts > 0)
+        {
+          remove_non_prop_changes(pristine_props, db->propchanges);
+        }
 
-      if (prop_state == svn_wc_notify_state_obstructed
-          || prop_state == svn_wc_notify_state_missing)
+      if (db->propchanges->nelts > 0)
         {
-          content_state = prop_state;
-          skipped = TRUE;
+          svn_boolean_t tree_conflicted = FALSE;
+          SVN_ERR(eb->diff_callbacks->dir_props_changed(
+                   &prop_state, &tree_conflicted,
+                   db->path, db->added,
+                   db->propchanges, pristine_props,
+                   eb->diff_cmd_baton, scratch_pool));
+          if (tree_conflicted)
+            db->tree_conflicted = TRUE;
+
+          if (prop_state == svn_wc_notify_state_obstructed
+              || prop_state == svn_wc_notify_state_missing)
+            {
+              content_state = prop_state;
+              skipped = TRUE;
+            }
         }
     }
 
   SVN_ERR(eb->diff_callbacks->dir_closed(NULL, NULL, NULL,
-                                         b->path, b->added,
-                                         b->edit_baton->diff_cmd_baton,
+                                         db->path, db->added,
+                                         eb->diff_cmd_baton,
                                          scratch_pool));
 
   /* Notify about any deleted paths within this directory that have not
    * already been notified. */
-  if (!skipped && !b->added && eb->notify_func)
+  if (!skipped && !db->added && eb->notify_func)
     {
       apr_hash_index_t *hi;
 
@@ -1151,11 +1160,11 @@ close_directory(void *dir_baton,
           const char *deleted_path = svn__apr_hash_index_key(hi);
           deleted_path_notify_t *dpn = svn__apr_hash_index_val(hi);
 
-          /* Ignore paths which are not children of b->path.  (There
+          /* Ignore paths which are not children of bb->path.  (There
              should be none due to editor ordering constraints, but
              ra_serf drops the ball here -- see issue #3802 for
              details.) */
-          if (! svn_relpath_skip_ancestor(b->path, deleted_path))
+          if (! svn_relpath_skip_ancestor(db->path, deleted_path))
             continue;
 
           notify = svn_wc_create_notify(deleted_path, dpn->action, pool);
@@ -1170,19 +1179,19 @@ close_directory(void *dir_baton,
 
   /* Notify about this directory itself (unless it was added, in which
    * case the notification was done at that time). */
-  if (!b->added && eb->notify_func)
+  if (!db->added && eb->notify_func)
     {
       svn_wc_notify_t *notify;
       svn_wc_notify_action_t action;
 
-      if (b->tree_conflicted)
+      if (db->tree_conflicted)
         action = svn_wc_notify_tree_conflict;
       else if (skipped)
         action = svn_wc_notify_skip;
       else
         action = svn_wc_notify_update_update;
 
-      notify = svn_wc_create_notify(b->path, action, pool);
+      notify = svn_wc_create_notify(db->path, action, pool);
       notify->kind = svn_node_dir;
 
       /* In case of a tree conflict during merge, the diff callback
@@ -1195,7 +1204,7 @@ close_directory(void *dir_baton,
       (*eb->notify_func)(eb->notify_baton, notify, scratch_pool);
     }
 
-  svn_pool_destroy(b->pool); /* Destroy baton and scratch_pool */
+  svn_pool_destroy(db->pool); /* Destroy baton and scratch_pool */
 
   return SVN_NO_ERROR;
 }
@@ -1210,16 +1219,19 @@ change_file_prop(void *file_baton,
                  const svn_string_t *value,
                  apr_pool_t *pool)
 {
-  struct file_baton *b = file_baton;
+  struct file_baton *fb = file_baton;
   svn_prop_t *propchange;
 
   /* Skip *everything* within a newly tree-conflicted directory. */
-  if (b->skip)
+  if (fb->skip)
     return SVN_NO_ERROR;
 
-  propchange = apr_array_push(b->propchanges);
-  propchange->name = apr_pstrdup(b->pool, name);
-  propchange->value = value ? svn_string_dup(value, b->pool) : NULL;
+  if (!fb->has_propchange && svn_property_kind2(name) == svn_prop_regular_kind)
+    fb->has_propchange = TRUE;
+
+  propchange = apr_array_push(fb->propchanges);
+  propchange->name = apr_pstrdup(fb->pool, name);
+  propchange->value = value ? svn_string_dup(value, fb->pool) : NULL;
 
   return SVN_NO_ERROR;
 }
@@ -1240,6 +1252,9 @@ change_dir_prop(void *dir_baton,
   if (db->skip)
     return SVN_NO_ERROR;
 
+  if (!db->has_propchange && svn_property_kind2(name) == svn_prop_regular_kind)
+    db->has_propchange = TRUE;
+
   propchange = apr_array_push(db->propchanges);
   propchange->name = apr_pstrdup(db->pool, name);
   propchange->value = value ? svn_string_dup(value, db->pool) : NULL;

Modified: subversion/branches/ev2-export/subversion/libsvn_client/switch.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/switch.c?rev=1424772&r1=1424771&r2=1424772&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/switch.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/switch.c Fri Dec 21 00:23:39 2012
@@ -267,7 +267,7 @@ switch_internal(svn_revnum_t *result_rev
       if (needs_iprop_cache)
         {
           SVN_ERR(svn_ra_get_inherited_props(ra_session, &inherited_props,
-                                             "", switch_loc->rev, pool,
+                                             "", switch_loc->rev, TRUE, pool,
                                              pool));
           apr_hash_set(wcroot_iprops, local_abspath, APR_HASH_KEY_STRING,
                        inherited_props);

Modified: subversion/branches/ev2-export/subversion/libsvn_client/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/update.c?rev=1424772&r1=1424771&r2=1424772&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/update.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/update.c Fri Dec 21 00:23:39 2012
@@ -377,8 +377,8 @@ update_internal(svn_revnum_t *result_rev
   dfb.anchor_url = anchor_loc->url;
 
   err = svn_client__get_inheritable_props(&wcroot_iprops, local_abspath,
-                                          revnum, depth, ra_session, ctx,
-                                          pool, pool);
+                                          revnum, depth, TRUE, ra_session,
+                                          ctx, pool, pool);
 
   /* We might be trying to update to a non-existant path-rev. */
   if (err)

Modified: subversion/branches/ev2-export/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_fs_fs/fs_fs.c?rev=1424772&r1=1424771&r2=1424772&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_fs_fs/fs_fs.c Fri Dec 21 00:23:39 2012
@@ -2329,10 +2329,6 @@ get_node_revision_body(node_revision_t *
                                   svn_stream_from_aprfile2(revision_file, FALSE,
                                                            pool),
                                   pool));
-  /* Workaround issue #4031: is-fresh-txn-root in revision files. */
-  if (svn_fs_fs__id_txn_id(id) == NULL)
-    (*noderev_p)->is_fresh_txn_root = FALSE;
-
 
   /* The noderev is not in cache, yet. Add it, if caching has been enabled. */
   return set_cached_node_revision_body(*noderev_p, fs, id, pool);
@@ -8139,9 +8135,13 @@ write_final_rev(const svn_fs_id_t **new_
   if (noderev->prop_rep)
     noderev->prop_rep->sha1_checksum = NULL;
 
+  /* Workaround issue #4031: is-fresh-txn-root in revision files. */
+  noderev->is_fresh_txn_root = FALSE;
+
   /* Write out our new node-revision. */
   if (at_root)
     SVN_ERR(validate_root_noderev(fs, noderev, rev, pool));
+
   SVN_ERR(svn_fs_fs__write_noderev(svn_stream_from_aprfile2(file, TRUE, pool),
                                    noderev, ffd->format,
                                    svn_fs_fs__fs_supports_mergeinfo(fs),
@@ -8560,23 +8560,6 @@ write_reps_to_cache(svn_fs_t *fs,
   return SVN_NO_ERROR;
 }
 
-/* Implements svn_sqlite__transaction_callback_t. */
-static svn_error_t *
-commit_sqlite_txn_callback(void *baton, svn_sqlite__db_t *db,
-                           apr_pool_t *scratch_pool)
-{
-  struct commit_baton *cb = baton;
-
-  /* Write new entries to the rep-sharing database.
-   *
-   * We use an sqlite transcation to speed things up;
-   * see <http://www.sqlite.org/faq.html#q19>.
-   */
-  SVN_ERR(write_reps_to_cache(cb->fs, cb->reps_to_cache, scratch_pool));
-
-  return SVN_NO_ERROR;
-}
-
 svn_error_t *
 svn_fs_fs__commit(svn_revnum_t *new_rev_p,
                   svn_fs_t *fs,
@@ -8611,9 +8594,15 @@ svn_fs_fs__commit(svn_revnum_t *new_rev_
   if (ffd->rep_sharing_allowed)
     {
       SVN_ERR(svn_fs_fs__open_rep_cache(fs, pool));
-      SVN_ERR(svn_sqlite__with_transaction(ffd->rep_cache_db,
-                                           commit_sqlite_txn_callback,
-                                           &cb, pool));
+
+      /* Write new entries to the rep-sharing database.
+       *
+       * We use an sqlite transaction to speed things up;
+       * see <http://www.sqlite.org/faq.html#q19>.
+       */
+      SVN_SQLITE__WITH_TXN(
+        write_reps_to_cache(fs, cb.reps_to_cache, pool),
+        ffd->rep_cache_db);
     }
 
   return SVN_NO_ERROR;

Modified: subversion/branches/ev2-export/subversion/libsvn_fs_fs/rep-cache.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_fs_fs/rep-cache.c?rev=1424772&r1=1424771&r2=1424772&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_fs_fs/rep-cache.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_fs_fs/rep-cache.c Fri Dec 21 00:23:39 2012
@@ -76,26 +76,30 @@ open_rep_cache(void *baton,
 {
   svn_fs_t *fs = baton;
   fs_fs_data_t *ffd = fs->fsap_data;
+  svn_sqlite__db_t *sdb;
   const char *db_path;
   int version;
 
   /* Open (or create) the sqlite database.  It will be automatically
      closed when fs->pool is destoyed. */
   db_path = path_rep_cache_db(fs->path, pool);
-  SVN_ERR(svn_sqlite__open(&ffd->rep_cache_db, db_path,
+  SVN_ERR(svn_sqlite__open(&sdb, db_path,
                            svn_sqlite__mode_rwcreate, statements,
                            0, NULL,
                            fs->pool, pool));
 
-  SVN_ERR(svn_sqlite__read_schema_version(&version, ffd->rep_cache_db, pool));
+  SVN_ERR(svn_sqlite__read_schema_version(&version, sdb, pool));
   if (version < REP_CACHE_SCHEMA_FORMAT)
     {
       /* Must be 0 -- an uninitialized (no schema) database. Create
          the schema. Results in schema version of 1.  */
-      SVN_ERR(svn_sqlite__exec_statements(ffd->rep_cache_db,
-                                          STMT_CREATE_SCHEMA));
+      SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_CREATE_SCHEMA));
     }
 
+  /* This is used as a flag that the database is available so don't
+     set it earlier. */
+  ffd->rep_cache_db = sdb;
+
   return SVN_NO_ERROR;
 }
 
@@ -151,16 +155,15 @@ svn_fs_fs__walk_rep_reference(svn_fs_t *
   /* Check global invariants. */
   if (start == 0)
     {
-      svn_sqlite__stmt_t *stmt2;
       svn_revnum_t max;
 
-      SVN_ERR(svn_sqlite__get_statement(&stmt2, ffd->rep_cache_db,
+      SVN_ERR(svn_sqlite__get_statement(&stmt, ffd->rep_cache_db,
                                         STMT_GET_MAX_REV));
-      SVN_ERR(svn_sqlite__step(&have_row, stmt2));
-      max = svn_sqlite__column_revnum(stmt2, 0);
+      SVN_ERR(svn_sqlite__step(&have_row, stmt));
+      max = svn_sqlite__column_revnum(stmt, 0);
+      SVN_ERR(svn_sqlite__reset(stmt));
       if (SVN_IS_VALID_REVNUM(max))  /* The rep-cache could be empty. */
         SVN_ERR(svn_fs_fs__revision_exists(max, fs, iterpool));
-      SVN_ERR(svn_sqlite__reset(stmt2));
     }
 
   SVN_ERR(svn_sqlite__get_statement(&stmt, ffd->rep_cache_db,
@@ -174,6 +177,7 @@ svn_fs_fs__walk_rep_reference(svn_fs_t *
     {
       representation_t *rep;
       const char *sha1_digest;
+      svn_error_t *err;
 
       /* Clear ITERPOOL occasionally. */
       if (iterations++ % 16 == 0)
@@ -181,21 +185,29 @@ svn_fs_fs__walk_rep_reference(svn_fs_t *
 
       /* Check for cancellation. */
       if (cancel_func)
-        SVN_ERR(cancel_func(cancel_baton));
+        {
+          err = cancel_func(cancel_baton);
+          if (err)
+            return svn_error_compose_create(err, svn_sqlite__reset(stmt));
+        }
 
       /* Construct a representation_t. */
       rep = apr_pcalloc(iterpool, sizeof(*rep));
       sha1_digest = svn_sqlite__column_text(stmt, 0, iterpool);
-      SVN_ERR(svn_checksum_parse_hex(&rep->sha1_checksum,
-                                     svn_checksum_sha1, sha1_digest,
-                                     iterpool));
+      err = svn_checksum_parse_hex(&rep->sha1_checksum,
+                                   svn_checksum_sha1, sha1_digest,
+                                   iterpool);
+      if (err)
+        return svn_error_compose_create(err, svn_sqlite__reset(stmt));
       rep->revision = svn_sqlite__column_revnum(stmt, 1);
       rep->offset = svn_sqlite__column_int64(stmt, 2);
       rep->size = svn_sqlite__column_int64(stmt, 3);
       rep->expanded_size = svn_sqlite__column_int64(stmt, 4);
 
       /* Walk. */
-      SVN_ERR(walker(rep, walker_baton, fs, iterpool));
+      err = walker(rep, walker_baton, fs, iterpool);
+      if (err)
+        return svn_error_compose_create(err, svn_sqlite__reset(stmt));
 
       SVN_ERR(svn_sqlite__step(&have_row, stmt));
     }
@@ -247,10 +259,12 @@ svn_fs_fs__get_rep_reference(representat
   else
     *rep = NULL;
 
+  SVN_ERR(svn_sqlite__reset(stmt));
+
   if (*rep)
     SVN_ERR(rep_has_been_born(*rep, fs, pool));
 
-  return svn_sqlite__reset(stmt);
+  return SVN_NO_ERROR;
 }
 
 svn_error_t *

Modified: subversion/branches/ev2-export/subversion/libsvn_ra/ra_loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra/ra_loader.c?rev=1424772&r1=1424771&r2=1424772&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra/ra_loader.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra/ra_loader.c Fri Dec 21 00:23:39 2012
@@ -1299,6 +1299,7 @@ svn_ra_get_inherited_props(svn_ra_sessio
                            apr_array_header_t **iprops,
                            const char *path,
                            svn_revnum_t revision,
+                           svn_boolean_t use_relpath_keys,
                            apr_pool_t *result_pool,
                            apr_pool_t *scratch_pool)
 {
@@ -1324,6 +1325,23 @@ svn_ra_get_inherited_props(svn_ra_sessio
                                                result_pool, scratch_pool));
     }
 
+  if (use_relpath_keys && (*iprops)->nelts)
+    {
+      const char *repos_root_url;
+      int i;
+
+      SVN_ERR(svn_ra_get_repos_root2(session, &repos_root_url, scratch_pool));
+      for (i = 0; i < (*iprops)->nelts; i++)
+        {
+          svn_prop_inherited_item_t *elt =
+            APR_ARRAY_IDX(*iprops, i, svn_prop_inherited_item_t *);
+          elt->path_or_url =
+            svn_dirent_skip_ancestor(repos_root_url, elt->path_or_url);
+          elt->path_or_url = svn_path_uri_decode(elt->path_or_url,
+                                                 result_pool);
+        }
+    }
+
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/update.c?rev=1424772&r1=1424771&r2=1424772&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/update.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/update.c Fri Dec 21 00:23:39 2012
@@ -503,26 +503,42 @@ update_cdata(svn_ra_serf__xml_estate_t *
 static svn_ra_serf__connection_t *
 get_best_connection(report_context_t *ctx)
 {
-  svn_ra_serf__connection_t * conn;
-  int first_conn;
+  svn_ra_serf__connection_t *conn;
+  int first_conn = 1;
 
   /* Skip the first connection if the REPORT response hasn't been completely
-     received yet. */
-  first_conn = ctx->report_received ? 0: 1;
-
+     received yet or if we're being told to limit our connections to
+     2 (because this could be an attempt to ensure that we do all our
+     auxiliary GETs/PROPFINDs on a single connection).
+
+     ### FIXME: This latter requirement (max_connections > 2) is
+     ### really just a hack to work around the fact that some update
+     ### editor implementations (such as svnrdump's dump editor)
+     ### simply can't handle the way ra_serf violates the editor v1
+     ### drive ordering requirements.
+     ### 
+     ### See http://subversion.tigris.org/issues/show_bug.cgi?id=4116.
+  */
+  if (ctx->report_received && (ctx->sess->max_connections > 2))
+    first_conn = 0;
+
+  /* Currently, we just cycle connections.  In the future we could
+     store the number of pending requests on each connection, or
+     perform other heuristics, to achieve better connection usage.
+     (As an optimization, if there's only one available auxiliary
+     connection to use, don't bother doing all the cur_conn math --
+     just return that one connection.)  */
   if (ctx->sess->num_conns - first_conn == 1)
-    return ctx->sess->conns[first_conn];
-
-  /* Currently just cycle connections. In future we could store number of
-   * pending requests on each connection for better connection usage. */
-  conn = ctx->sess->conns[ctx->sess->cur_conn];
-
-  /* Switch our connection. */
-  ctx->sess->cur_conn++;
-
-  if (ctx->sess->cur_conn >= ctx->sess->num_conns)
-      ctx->sess->cur_conn = first_conn;
-
+    {
+      conn = ctx->sess->conns[first_conn];
+    }
+  else
+    {
+      conn = ctx->sess->conns[ctx->sess->cur_conn];
+      ctx->sess->cur_conn++;
+      if (ctx->sess->cur_conn >= ctx->sess->num_conns)
+        ctx->sess->cur_conn = first_conn;
+    }
   return conn;
 }
 

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/cmdline.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/cmdline.c?rev=1424772&r1=1424771&r2=1424772&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/cmdline.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/cmdline.c Fri Dec 21 00:23:39 2012
@@ -33,8 +33,10 @@
 #include <unistd.h>
 #else
 #include <crtdbg.h>
+#include <io.h>
 #endif
 
+#include <apr.h>                /* for STDIN_FILENO */
 #include <apr_errno.h>          /* for apr_strerror */
 #include <apr_general.h>        /* for apr_initialize/apr_terminate */
 #include <apr_strings.h>        /* for apr_snprintf */
@@ -923,3 +925,24 @@ svn_cmdline__print_xml_prop_hash(svn_str
 
     return SVN_NO_ERROR;
 }
+
+svn_boolean_t
+svn_cmdline__be_interactive(svn_boolean_t non_interactive,
+                            svn_boolean_t force_interactive)
+{
+  /* If neither --non-interactive nor --force-interactive was passed,
+   * be interactive if stdin is a terminal.
+   * If --force-interactive was passed, always be interactive. */
+  if (!force_interactive && !non_interactive)
+    {
+#ifdef WIN32
+      return (_isatty(STDIN_FILENO) != 0);
+#else
+      return (isatty(STDIN_FILENO) != 0);
+#endif
+    }
+  else if (force_interactive) 
+    return TRUE;
+
+  return !non_interactive;
+}

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/deprecated.c?rev=1424772&r1=1424771&r2=1424772&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/deprecated.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/deprecated.c Fri Dec 21 00:23:39 2012
@@ -45,6 +45,7 @@
 
 #include "opt.h"
 #include "private/svn_opt_private.h"
+#include "private/svn_mergeinfo_private.h"
 
 #include "svn_private_config.h"
 
@@ -1122,8 +1123,11 @@ svn_rangelist_merge(svn_rangelist_t **ra
                     const svn_rangelist_t *changes,
                     apr_pool_t *pool)
 {
-  return svn_error_trace(svn_rangelist_merge2(*rangelist, changes,
-                                              pool, pool));
+  SVN_ERR(svn_rangelist_merge2(*rangelist, changes,
+                               pool, pool));
+
+  return svn_error_trace(
+            svn_rangelist__combine_adjacent_ranges(*rangelist, pool));
 }
 
 svn_error_t *

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/error.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/error.c?rev=1424772&r1=1424771&r2=1424772&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/error.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/error.c Fri Dec 21 00:23:39 2012
@@ -221,6 +221,8 @@ svn_error_quick_wrap(svn_error_t *child,
                           new_msg);
 }
 
+/* Messages in tracing errors all point to this static string. */
+static const char error_tracing_link[] = "traced call";
 
 svn_error_t *
 svn_error__trace(const char *file, long line, svn_error_t *err)
@@ -235,8 +237,11 @@ svn_error__trace(const char *file, long 
   /* Only do the work when an error occurs.  */
   if (err)
     {
+      svn_error_t *trace;
       svn_error__locate(file, line);
-      return svn_error_quick_wrap(err, SVN_ERR__TRACED);
+      trace = make_error_internal(err->apr_err, err);
+      trace->message = error_tracing_link;
+      return trace;
     }
   return SVN_NO_ERROR;
 
@@ -383,7 +388,7 @@ svn_error__is_tracing_link(svn_error_t *
      ### we add a boolean field to svn_error_t that's set only for
      ### these "placeholder error chain" items.  Not such a bad idea,
      ### really...  */
-  return (err && err->message && !strcmp(err->message, SVN_ERR__TRACED));
+  return (err && err->message && !strcmp(err->message, error_tracing_link));
 #else
   return FALSE;
 #endif

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/mergeinfo.c?rev=1424772&r1=1424771&r2=1424772&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/mergeinfo.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/mergeinfo.c Fri Dec 21 00:23:39 2012
@@ -611,6 +611,58 @@ svn_rangelist__parse(svn_rangelist_t **r
   return SVN_NO_ERROR;
 }
 
+svn_error_t *
+svn_rangelist__combine_adjacent_ranges(svn_rangelist_t *rangelist,
+                                       apr_pool_t *scratch_pool)
+{
+  int i;
+  svn_merge_range_t *range, *lastrange;
+
+  lastrange = APR_ARRAY_IDX(rangelist, 0, svn_merge_range_t *);
+
+  for (i = 1; i < rangelist->nelts; i++)
+    {
+      range = APR_ARRAY_IDX(rangelist, i, svn_merge_range_t *);
+      if (lastrange->start <= range->end
+          && range->start <= lastrange->end)
+        {
+          /* The ranges are adjacent or intersect. */
+
+          /* svn_mergeinfo_parse promises to combine overlapping
+             ranges as long as their inheritability is the same. */
+          if (range->start < lastrange->end
+              && range->inheritable != lastrange->inheritable)
+            {
+              return svn_error_createf(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
+                                       _("Unable to parse overlapping "
+                                         "revision ranges '%s' and '%s' "
+                                         "with different inheritance "
+                                         "types"),
+                                       range_to_string(lastrange,
+                                                       scratch_pool),
+                                       range_to_string(range,
+                                                       scratch_pool));
+            }
+
+          /* Combine overlapping or adjacent ranges with the
+             same inheritability. */
+          if (lastrange->inheritable == range->inheritable)
+            {
+              lastrange->end = MAX(range->end, lastrange->end);
+              if (i + 1 < rangelist->nelts)
+                memmove(rangelist->elts + (rangelist->elt_size * i),
+                        rangelist->elts + (rangelist->elt_size * (i + 1)),
+                        rangelist->elt_size * (rangelist->nelts - i));
+              rangelist->nelts--;
+              i--;
+            }
+        }
+      lastrange = APR_ARRAY_IDX(rangelist, i, svn_merge_range_t *);
+    }
+
+  return SVN_NO_ERROR;
+}
+
 /* revisionline -> PATHNAME COLON revisionlist */
 static svn_error_t *
 parse_revision_line(const char **input, const char *end, svn_mergeinfo_t hash,
@@ -648,52 +700,10 @@ parse_revision_line(const char **input, 
      and make sure there are no overlapping ranges. */
   if (rangelist->nelts > 1)
     {
-      int i;
-      svn_merge_range_t *range, *lastrange;
-
       qsort(rangelist->elts, rangelist->nelts, rangelist->elt_size,
             svn_sort_compare_ranges);
-      lastrange = APR_ARRAY_IDX(rangelist, 0, svn_merge_range_t *);
-
-      for (i = 1; i < rangelist->nelts; i++)
-        {
-          range = APR_ARRAY_IDX(rangelist, i, svn_merge_range_t *);
-          if (lastrange->start <= range->end
-              && range->start <= lastrange->end)
-            {
-              /* The ranges are adjacent or intersect. */
 
-              /* svn_mergeinfo_parse promises to combine overlapping
-                 ranges as long as their inheritability is the same. */
-              if (range->start < lastrange->end
-                  && range->inheritable != lastrange->inheritable)
-                {
-                  return svn_error_createf(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
-                                           _("Unable to parse overlapping "
-                                             "revision ranges '%s' and '%s' "
-                                             "with different inheritance "
-                                             "types"),
-                                           range_to_string(lastrange,
-                                                           scratch_pool),
-                                           range_to_string(range,
-                                                           scratch_pool));
-                }
-
-              /* Combine overlapping or adjacent ranges with the
-                 same inheritability. */
-              if (lastrange->inheritable == range->inheritable)
-                {
-                  lastrange->end = MAX(range->end, lastrange->end);
-                  if (i + 1 < rangelist->nelts)
-                    memmove(rangelist->elts + (rangelist->elt_size * i),
-                            rangelist->elts + (rangelist->elt_size * (i + 1)),
-                            rangelist->elt_size * (rangelist->nelts - i));
-                  rangelist->nelts--;
-                  i--;
-                }
-            }
-          lastrange = APR_ARRAY_IDX(rangelist, i, svn_merge_range_t *);
-        }
+      SVN_ERR(svn_rangelist__combine_adjacent_ranges(rangelist, scratch_pool));
     }
 
   /* Handle any funky mergeinfo with relative merge source paths that

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/properties.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/properties.c?rev=1424772&r1=1424771&r2=1424772&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/properties.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/properties.c Fri Dec 21 00:23:39 2012
@@ -244,8 +244,8 @@ svn_categorize_props(const apr_array_hea
 
 svn_error_t *
 svn_prop_diffs(apr_array_header_t **propdiffs,
-               apr_hash_t *target_props,
-               apr_hash_t *source_props,
+               const apr_hash_t *target_props,
+               const apr_hash_t *source_props,
                apr_pool_t *pool)
 {
   apr_hash_index_t *hi;
@@ -257,7 +257,8 @@ svn_prop_diffs(apr_array_header_t **prop
 
   /* Loop over SOURCE_PROPS and examine each key.  This will allow us to
      detect any `deletion' events or `set-modification' events.  */
-  for (hi = apr_hash_first(pool, source_props); hi; hi = apr_hash_next(hi))
+  for (hi = apr_hash_first(pool, (apr_hash_t *)source_props); hi;
+       hi = apr_hash_next(hi))
     {
       const void *key;
       apr_ssize_t klen;
@@ -269,7 +270,7 @@ svn_prop_diffs(apr_array_header_t **prop
       propval1 = val;
 
       /* Does property name exist in TARGET_PROPS? */
-      propval2 = apr_hash_get(target_props, key, klen);
+      propval2 = apr_hash_get((apr_hash_t *)target_props, key, klen);
 
       if (propval2 == NULL)
         {
@@ -289,7 +290,8 @@ svn_prop_diffs(apr_array_header_t **prop
 
   /* Loop over TARGET_PROPS and examine each key.  This allows us to
      detect `set-creation' events */
-  for (hi = apr_hash_first(pool, target_props); hi; hi = apr_hash_next(hi))
+  for (hi = apr_hash_first(pool, (apr_hash_t *)target_props); hi;
+       hi = apr_hash_next(hi))
     {
       const void *key;
       apr_ssize_t klen;
@@ -301,7 +303,7 @@ svn_prop_diffs(apr_array_header_t **prop
       propval = val;
 
       /* Does property name exist in SOURCE_PROPS? */
-      if (NULL == apr_hash_get(source_props, key, klen))
+      if (NULL == apr_hash_get((apr_hash_t *)source_props, key, klen))
         {
           /* Add a set (creation) event to the array */
           svn_prop_t *p = apr_array_push(ary);
@@ -354,13 +356,16 @@ svn_prop_array_dup(const apr_array_heade
 }
 
 apr_array_header_t *
-svn_prop_hash_to_array(apr_hash_t *hash, apr_pool_t *pool)
+svn_prop_hash_to_array(const apr_hash_t *hash,
+                       apr_pool_t *pool)
 {
   apr_hash_index_t *hi;
-  apr_array_header_t *array = apr_array_make(pool, apr_hash_count(hash),
+  apr_array_header_t *array = apr_array_make(pool,
+                                             apr_hash_count((apr_hash_t *)hash),
                                              sizeof(svn_prop_t));
 
-  for (hi = apr_hash_first(pool, hash); hi; hi = apr_hash_next(hi))
+  for (hi = apr_hash_first(pool, (apr_hash_t *)hash); hi;
+       hi = apr_hash_next(hi))
     {
       const void *key;
       void *val;
@@ -376,13 +381,14 @@ svn_prop_hash_to_array(apr_hash_t *hash,
 }
 
 apr_hash_t *
-svn_prop_hash_dup(apr_hash_t *hash,
+svn_prop_hash_dup(const apr_hash_t *hash,
                   apr_pool_t *pool)
 {
   apr_hash_index_t *hi;
   apr_hash_t *new_hash = apr_hash_make(pool);
 
-  for (hi = apr_hash_first(pool, hash); hi; hi = apr_hash_next(hi))
+  for (hi = apr_hash_first(pool, (apr_hash_t *)hash); hi;
+       hi = apr_hash_next(hi))
     {
       const void *key;
       apr_ssize_t klen;
@@ -465,7 +471,7 @@ svn_prop_name_is_valid(const char *prop_
 }
 
 const char *
-svn_prop_get_value(apr_hash_t *props,
+svn_prop_get_value(const apr_hash_t *props,
                    const char *prop_name)
 {
   svn_string_t *str;
@@ -473,7 +479,7 @@ svn_prop_get_value(apr_hash_t *props,
   if (!props)
     return NULL;
 
-  str = apr_hash_get(props, prop_name, APR_HASH_KEY_STRING);
+  str = apr_hash_get((apr_hash_t *)props, prop_name, APR_HASH_KEY_STRING);
 
   if (str)
     return str->data;

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/skel.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/skel.c?rev=1424772&r1=1424771&r2=1424772&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/skel.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/skel.c Fri Dec 21 00:23:39 2012
@@ -824,7 +824,8 @@ svn_skel__unparse_proplist(svn_skel_t **
 svn_error_t *
 svn_skel__unparse_iproplist(svn_skel_t **skel_p,
                             const apr_array_header_t *inherited_props,
-                            apr_pool_t *result_pool)
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool)
 {
   svn_skel_t *skel = svn_skel__make_empty_list(result_pool);
 
@@ -833,7 +834,6 @@ svn_skel__unparse_iproplist(svn_skel_t *
     {
       int i;
       apr_hash_index_t *hi;
-      apr_pool_t *subpool = svn_pool_create(result_pool);
 
       for (i = 0; i < inherited_props->nelts; i++)
         {
@@ -843,10 +843,8 @@ svn_skel__unparse_iproplist(svn_skel_t *
           svn_skel_t *skel_list = svn_skel__make_empty_list(result_pool);
           svn_skel_t *skel_atom;
 
-          svn_pool_clear(subpool);
-
           /* Loop over hash entries */
-          for (hi = apr_hash_first(subpool, iprop->prop_hash);
+          for (hi = apr_hash_first(scratch_pool, iprop->prop_hash);
                hi;
                hi = apr_hash_next(hi))
             {
@@ -872,7 +870,6 @@ svn_skel__unparse_iproplist(svn_skel_t *
           svn_skel__append(skel, skel_atom);
           svn_skel__append(skel, skel_list);
         }
-      svn_pool_destroy(subpool);
     }
 
   /* Validate and return the skel. */

Modified: subversion/branches/ev2-export/subversion/libsvn_subr/sqlite.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_subr/sqlite.c?rev=1424772&r1=1424771&r2=1424772&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_subr/sqlite.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_subr/sqlite.c Fri Dec 21 00:23:39 2012
@@ -493,7 +493,7 @@ svn_sqlite__bind_iprops(svn_sqlite__stmt
     return svn_error_trace(svn_sqlite__bind_blob(stmt, slot, NULL, 0));
 
   SVN_ERR(svn_skel__unparse_iproplist(&skel, inherited_props,
-                                      scratch_pool));
+                                      scratch_pool, scratch_pool));
   properties = svn_skel__unparse(skel, scratch_pool);
   return svn_error_trace(svn_sqlite__bind_blob(stmt,
                                                slot,
@@ -992,18 +992,44 @@ reset_all_statements(svn_sqlite__db_t *d
   return err;
 }
 
-/* The body of svn_sqlite__with_transaction() and
-   svn_sqlite__with_immediate_transaction(), which see. */
-static svn_error_t *
-with_transaction(svn_sqlite__db_t *db,
-                 svn_sqlite__transaction_callback_t cb_func,
-                 void *cb_baton,
-                 apr_pool_t *scratch_pool /* NULL allowed */)
+svn_error_t *
+svn_sqlite__begin_transaction(svn_sqlite__db_t *db)
 {
   svn_sqlite__stmt_t *stmt;
-  svn_error_t *err;
 
-  err = cb_func(cb_baton, db, scratch_pool);
+  SVN_ERR(get_internal_statement(&stmt, db,
+                                 STMT_INTERNAL_BEGIN_TRANSACTION));
+  SVN_ERR(svn_sqlite__step_done(stmt));
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_sqlite__begin_immediate_transaction(svn_sqlite__db_t *db)
+{
+  svn_sqlite__stmt_t *stmt;
+
+  SVN_ERR(get_internal_statement(&stmt, db,
+                                 STMT_INTERNAL_BEGIN_IMMEDIATE_TRANSACTION));
+  SVN_ERR(svn_sqlite__step_done(stmt));
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_sqlite__begin_savepoint(svn_sqlite__db_t *db)
+{
+  svn_sqlite__stmt_t *stmt;
+
+  SVN_ERR(get_internal_statement(&stmt, db,
+                                 STMT_INTERNAL_SAVEPOINT_SVN));
+  SVN_ERR(svn_sqlite__step_done(stmt));
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_sqlite__finish_transaction(svn_sqlite__db_t *db,
+                               svn_error_t *err)
+{
+  svn_sqlite__stmt_t *stmt;
 
   /* Commit or rollback the sqlite transaction. */
   if (err)
@@ -1051,46 +1077,10 @@ with_transaction(svn_sqlite__db_t *db,
 }
 
 svn_error_t *
-svn_sqlite__with_transaction(svn_sqlite__db_t *db,
-                             svn_sqlite__transaction_callback_t cb_func,
-                             void *cb_baton,
-                             apr_pool_t *scratch_pool /* NULL allowed */)
+svn_sqlite__finish_savepoint(svn_sqlite__db_t *db,
+                             svn_error_t *err)
 {
   svn_sqlite__stmt_t *stmt;
-  SVN_ERR(get_internal_statement(&stmt, db,
-                                 STMT_INTERNAL_BEGIN_TRANSACTION));
-  SVN_ERR(svn_sqlite__step_done(stmt));
-  return svn_error_trace(with_transaction(db, cb_func, cb_baton,
-                                          scratch_pool));
-}
-
-svn_error_t *
-svn_sqlite__with_immediate_transaction(
-  svn_sqlite__db_t *db,
-  svn_sqlite__transaction_callback_t cb_func,
-  void *cb_baton,
-  apr_pool_t *scratch_pool /* NULL allowed */)
-{
-  svn_sqlite__stmt_t *stmt;
-  SVN_ERR(get_internal_statement(&stmt, db,
-                                 STMT_INTERNAL_BEGIN_IMMEDIATE_TRANSACTION));
-  SVN_ERR(svn_sqlite__step_done(stmt));
-  return svn_error_trace(with_transaction(db, cb_func, cb_baton,
-                                          scratch_pool));
-}
-
-svn_error_t *
-svn_sqlite__with_lock(svn_sqlite__db_t *db,
-                      svn_sqlite__transaction_callback_t cb_func,
-                      void *cb_baton,
-                      apr_pool_t *scratch_pool)
-{
-  svn_error_t *err;
-  svn_sqlite__stmt_t *stmt;
-
-  SVN_ERR(get_internal_statement(&stmt, db, STMT_INTERNAL_SAVEPOINT_SVN));
-  SVN_ERR(svn_sqlite__step_done(stmt));
-  err = cb_func(cb_baton, db, scratch_pool);
 
   if (err)
     {
@@ -1131,6 +1121,37 @@ svn_sqlite__with_lock(svn_sqlite__db_t *
 }
 
 svn_error_t *
+svn_sqlite__with_transaction(svn_sqlite__db_t *db,
+                             svn_sqlite__transaction_callback_t cb_func,
+                             void *cb_baton,
+                             apr_pool_t *scratch_pool /* NULL allowed */)
+{
+  SVN_SQLITE__WITH_TXN(cb_func(cb_baton, db, scratch_pool), db);
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_sqlite__with_immediate_transaction(
+  svn_sqlite__db_t *db,
+  svn_sqlite__transaction_callback_t cb_func,
+  void *cb_baton,
+  apr_pool_t *scratch_pool /* NULL allowed */)
+{
+  SVN_SQLITE__WITH_IMMEDIATE_TXN(cb_func(cb_baton, db, scratch_pool), db);
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_sqlite__with_lock(svn_sqlite__db_t *db,
+                      svn_sqlite__transaction_callback_t cb_func,
+                      void *cb_baton,
+                      apr_pool_t *scratch_pool /* NULL allowed */)
+{
+  SVN_SQLITE__WITH_LOCK(cb_func(cb_baton, db, scratch_pool), db);
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
 svn_sqlite__hotcopy(const char *src_path,
                     const char *dst_path,
                     apr_pool_t *scratch_pool)

Modified: subversion/branches/ev2-export/subversion/libsvn_wc/adm_ops.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/adm_ops.c?rev=1424772&r1=1424771&r2=1424772&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/adm_ops.c Fri Dec 21 00:23:39 2012
@@ -898,20 +898,41 @@ svn_wc_delete4(svn_wc_context_t *wc_ctx,
 
 
 /* Schedule the single node at LOCAL_ABSPATH, of kind KIND, for addition in
- * its parent directory in the WC.  It will have no properties. */
+ * its parent directory in the WC.  It will have the regular properties
+ * provided in PROPS, or none if that is NULL.
+ *
+ * If the node is a file, set its on-disk executable and read-only bits to
+ * match its properties and lock state,
+ * ### only if it has an svn:executable or svn:needs-lock property.
+ * ### This is to match the previous behaviour of setting its props
+ *     afterwards by calling svn_wc_prop_set4(), but is not very clean.
+ *
+ * Sync the on-disk executable and read-only bits accordingly.
+ */
 static svn_error_t *
 add_from_disk(svn_wc__db_t *db,
               const char *local_abspath,
               svn_node_kind_t kind,
+              const apr_hash_t *props,
               apr_pool_t *scratch_pool)
 {
   if (kind == svn_node_file)
     {
-      SVN_ERR(svn_wc__db_op_add_file(db, local_abspath, NULL, scratch_pool));
+      svn_skel_t *work_item = NULL;
+
+      if (props && (svn_prop_get_value(props, SVN_PROP_EXECUTABLE)
+                    || svn_prop_get_value(props, SVN_PROP_NEEDS_LOCK)))
+        SVN_ERR(svn_wc__wq_build_sync_file_flags(&work_item, db, local_abspath,
+                                                 scratch_pool, scratch_pool));
+
+      SVN_ERR(svn_wc__db_op_add_file(db, local_abspath, props, work_item,
+                                     scratch_pool));
+      if (work_item)
+        SVN_ERR(svn_wc__wq_run(db, local_abspath, NULL, NULL, scratch_pool));
     }
   else
     {
-      SVN_ERR(svn_wc__db_op_add_directory(db, local_abspath, NULL,
+      SVN_ERR(svn_wc__db_op_add_directory(db, local_abspath, props, NULL,
                                           scratch_pool));
     }
 
@@ -1273,7 +1294,7 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
 
   if (!copyfrom_url)  /* Case 2a: It's a simple add */
     {
-      SVN_ERR(add_from_disk(db, local_abspath, kind,
+      SVN_ERR(add_from_disk(db, local_abspath, kind, NULL,
                             scratch_pool));
       if (kind == svn_node_dir && !db_row_exists)
         {
@@ -1346,11 +1367,12 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
 
 
 svn_error_t *
-svn_wc_add_from_disk(svn_wc_context_t *wc_ctx,
-                     const char *local_abspath,
-                     svn_wc_notify_func2_t notify_func,
-                     void *notify_baton,
-                     apr_pool_t *scratch_pool)
+svn_wc_add_from_disk2(svn_wc_context_t *wc_ctx,
+                      const char *local_abspath,
+                      const apr_hash_t *props,
+                      svn_wc_notify_func2_t notify_func,
+                      void *notify_baton,
+                      apr_pool_t *scratch_pool)
 {
   svn_node_kind_t kind;
 
@@ -1358,7 +1380,21 @@ svn_wc_add_from_disk(svn_wc_context_t *w
                              NULL, SVN_INVALID_REVNUM, scratch_pool));
   SVN_ERR(check_can_add_to_parent(NULL, NULL, wc_ctx->db, local_abspath,
                                   scratch_pool, scratch_pool));
-  SVN_ERR(add_from_disk(wc_ctx->db, local_abspath, kind,
+
+  /* Canonicalize and check the props */
+  if (props)
+    {
+      apr_hash_t *new_props;
+
+      SVN_ERR(svn_wc__canonicalize_props(
+                &new_props,
+                local_abspath, kind, props, FALSE /* skip_some_checks */,
+                scratch_pool, scratch_pool));
+      props = new_props;
+    }
+
+  /* Add to the DB and maybe update on-disk executable read-only bits */
+  SVN_ERR(add_from_disk(wc_ctx->db, local_abspath, kind, props,
                         scratch_pool));
 
   /* Report the addition to the caller. */
@@ -1368,6 +1404,7 @@ svn_wc_add_from_disk(svn_wc_context_t *w
                                                      svn_wc_notify_add,
                                                      scratch_pool);
       notify->kind = kind;
+      notify->mime_type = svn_prop_get_value(props, SVN_PROP_MIME_TYPE);
       (*notify_func)(notify_baton, notify, scratch_pool);
     }
 
@@ -1578,12 +1615,17 @@ revert_restore_handle_copied_dirs(svn_bo
 /* Make the working tree under LOCAL_ABSPATH to depth DEPTH match the
    versioned tree.  This function is called after svn_wc__db_op_revert
    has done the database revert and created the revert list.  Notifies
-   for all paths equal to or below LOCAL_ABSPATH that are reverted. */
+   for all paths equal to or below LOCAL_ABSPATH that are reverted.
+
+   REVERT_ROOT is true for explicit revert targets and FALSE for targets
+   reached via recursion.
+ */
 static svn_error_t *
 revert_restore(svn_wc__db_t *db,
                const char *local_abspath,
                svn_depth_t depth,
                svn_boolean_t use_commit_times,
+               svn_boolean_t revert_root,
                svn_cancel_func_t cancel_func,
                void *cancel_baton,
                svn_wc_notify_func2_t notify_func,
@@ -1604,10 +1646,31 @@ revert_restore(svn_wc__db_t *db,
 #endif
   svn_boolean_t copied_here;
   svn_kind_t reverted_kind;
+  svn_boolean_t is_wcroot;
 
   if (cancel_func)
     SVN_ERR(cancel_func(cancel_baton));
 
+  SVN_ERR(svn_wc__db_is_wcroot(&is_wcroot, db, local_abspath, scratch_pool));
+  if (is_wcroot && !revert_root)
+    {
+      /* Issue #4162: Obstructing working copy. We can't access the working
+         copy data from the parent working copy for this node by just using
+         local_abspath */
+
+      if (notify_func)
+        {
+          svn_wc_notify_t *notify = svn_wc_create_notify(
+                                        local_abspath,
+                                        svn_wc_notify_update_skip_obstruction,
+                                        scratch_pool);
+
+          notify_func(notify_baton, notify, scratch_pool);
+        }
+
+      return SVN_NO_ERROR; /* We don't revert obstructing working copies */
+    }
+
   SVN_ERR(svn_wc__db_revert_list_read(&notify_required,
                                       &conflict_files,
                                       &copied_here, &reverted_kind,
@@ -1920,7 +1983,7 @@ revert_restore(svn_wc__db_t *db,
                                           iterpool);
 
           SVN_ERR(revert_restore(db, child_abspath, depth,
-                                 use_commit_times,
+                                 use_commit_times, FALSE /* revert root */,
                                  cancel_func, cancel_baton,
                                  notify_func, notify_baton,
                                  iterpool));
@@ -1974,7 +2037,7 @@ revert_internal(svn_wc__db_t *db,
 
   if (!err)
     err = revert_restore(db, local_abspath, depth,
-                         use_commit_times,
+                         use_commit_times, TRUE /* revert root */,
                          cancel_func, cancel_baton,
                          notify_func, notify_baton,
                          scratch_pool);

Modified: subversion/branches/ev2-export/subversion/libsvn_wc/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/deprecated.c?rev=1424772&r1=1424771&r2=1424772&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/deprecated.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/deprecated.c Fri Dec 21 00:23:39 2012
@@ -903,6 +903,18 @@ svn_wc_delete(const char *path,
 }
 
 svn_error_t *
+svn_wc_add_from_disk(svn_wc_context_t *wc_ctx,
+                     const char *local_abspath,
+                     svn_wc_notify_func2_t notify_func,
+                     void *notify_baton,
+                     apr_pool_t *scratch_pool)
+{
+  SVN_ERR(svn_wc_add_from_disk2(wc_ctx, local_abspath, NULL,
+                                 notify_func, notify_baton, scratch_pool));
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
 svn_wc_add3(const char *path,
             svn_wc_adm_access_t *parent_access,
             svn_depth_t depth,

Modified: subversion/branches/ev2-export/subversion/libsvn_wc/props.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/props.c?rev=1424772&r1=1424771&r2=1424772&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/props.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/props.c Fri Dec 21 00:23:39 2012
@@ -1573,12 +1573,15 @@ validate_prop_against_node_kind(const ch
 
 
 struct getter_baton {
+  const svn_string_t *mime_type;
   const char *local_abspath;
-  svn_wc__db_t *db;
 };
 
 
-/* */
+/* Provide the MIME_TYPE and/or push the content to STREAM for the file
+ * referenced by (getter_baton *) BATON.
+ *
+ * Implements svn_wc_canonicalize_svn_prop_get_file_t. */
 static svn_error_t *
 get_file_for_validation(const svn_string_t **mime_type,
                         svn_stream_t *stream,
@@ -1588,18 +1591,15 @@ get_file_for_validation(const svn_string
   struct getter_baton *gb = baton;
 
   if (mime_type)
-    SVN_ERR(svn_wc__internal_propget(mime_type, gb->db, gb->local_abspath,
-                                     SVN_PROP_MIME_TYPE, pool, pool));
+    *mime_type = gb->mime_type;
 
   if (stream)
     {
       svn_stream_t *read_stream;
 
-      /* Open GB->LOCAL_ABSPATH. */
+      /* Copy the text of GB->LOCAL_ABSPATH into STREAM. */
       SVN_ERR(svn_stream_open_readonly(&read_stream, gb->local_abspath,
                                        pool, pool));
-
-      /* Copy from the file into the translating stream. */
       SVN_ERR(svn_stream_copy3(read_stream, svn_stream_disown(stream, pool),
                                NULL, NULL, pool));
     }
@@ -1608,7 +1608,16 @@ get_file_for_validation(const svn_string
 }
 
 
-/* */
+/* Validate that a file has a 'non-binary' MIME type and contains
+ * self-consistent line endings.  If not, then return an error.
+ *
+ * Call GETTER (which must not be NULL) with GETTER_BATON to get the
+ * file's MIME type and/or content.  If the MIME type is non-null and
+ * is categorized as 'binary' then return an error and do not request
+ * the file content.
+ *
+ * Use PATH (a local path or a URL) only for error messages.
+ */
 static svn_error_t *
 validate_eol_prop_against_file(const char *path,
                                svn_wc_canonicalize_svn_prop_get_file_t getter,
@@ -1670,6 +1679,10 @@ do_propset(svn_wc__db_t *db,
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
 
+  SVN_ERR_W(svn_wc__db_read_props(&prophash, db, local_abspath,
+                                  scratch_pool, scratch_pool),
+            _("Failed to load current properties"));
+
   /* Setting an inappropriate property is not allowed (unless
      overridden by 'skip_checks', in some circumstances).  Deleting an
      inappropriate property is allowed, however, since older clients
@@ -1680,8 +1693,9 @@ do_propset(svn_wc__db_t *db,
       const svn_string_t *new_value;
       struct getter_baton gb;
 
+      gb.mime_type = apr_hash_get(prophash,
+                                  SVN_PROP_MIME_TYPE, APR_HASH_KEY_STRING);
       gb.local_abspath = local_abspath;
-      gb.db = db;
 
       SVN_ERR(svn_wc_canonicalize_svn_prop(&new_value, name, value,
                                            local_abspath, kind,
@@ -1699,10 +1713,6 @@ do_propset(svn_wc__db_t *db,
                                                scratch_pool, scratch_pool));
     }
 
-  SVN_ERR_W(svn_wc__db_read_props(&prophash, db, local_abspath,
-                                  scratch_pool, scratch_pool),
-            _("Failed to load current properties"));
-
   /* If we're changing this file's list of expanded keywords, then
    * we'll need to invalidate its text timestamp, since keyword
    * expansion affects the comparison of working file to text base.
@@ -1958,6 +1968,83 @@ svn_wc_prop_set4(svn_wc_context_t *wc_ct
   return SVN_NO_ERROR;
 }
 
+/* Check that NAME names a regular prop. Return an error if it names an
+ * entry prop or a WC prop. */
+static svn_error_t *
+ensure_prop_is_regular_kind(const char *name)
+{
+  enum svn_prop_kind prop_kind = svn_property_kind2(name);
+
+  /* we don't do entry properties here */
+  if (prop_kind == svn_prop_entry_kind)
+    return svn_error_createf(SVN_ERR_BAD_PROP_KIND, NULL,
+                             _("Property '%s' is an entry property"), name);
+
+  /* Check to see if we're setting the dav cache. */
+  if (prop_kind == svn_prop_wc_kind)
+    return svn_error_createf(SVN_ERR_BAD_PROP_KIND, NULL,
+                             _("Property '%s' is a WC property, not "
+                               "a regular property"), name);
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc__canonicalize_props(apr_hash_t **prepared_props,
+                           const char *local_abspath,
+                           svn_node_kind_t node_kind,
+                           const apr_hash_t *props,
+                           svn_boolean_t skip_some_checks,
+                           apr_pool_t *result_pool,
+                           apr_pool_t *scratch_pool)
+{
+  const svn_string_t *mime_type;
+  struct getter_baton gb;
+  apr_hash_index_t *hi;
+
+  /* While we allocate new parts of *PREPARED_PROPS in RESULT_POOL, we
+     don't promise to deep-copy the unchanged keys and values. */
+  *prepared_props = apr_hash_make(result_pool);
+
+  /* Before we can canonicalize svn:eol-style we need to know svn:mime-type,
+   * so process that first. */
+  mime_type = apr_hash_get((apr_hash_t *)props,
+                           SVN_PROP_MIME_TYPE, APR_HASH_KEY_STRING);
+  if (mime_type)
+    {
+      SVN_ERR(svn_wc_canonicalize_svn_prop(
+                &mime_type, SVN_PROP_MIME_TYPE, mime_type,
+                local_abspath, node_kind, skip_some_checks,
+                NULL, NULL, scratch_pool));
+      apr_hash_set(*prepared_props, SVN_PROP_MIME_TYPE, APR_HASH_KEY_STRING,
+                   mime_type);
+    }
+
+  /* Set up the context for canonicalizing the other properties. */
+  gb.mime_type = mime_type;
+  gb.local_abspath = local_abspath;
+
+  /* Check and canonicalize the other properties. */
+  for (hi = apr_hash_first(scratch_pool, (apr_hash_t *)props); hi;
+       hi = apr_hash_next(hi))
+    {
+      const char *name = svn__apr_hash_index_key(hi);
+      const svn_string_t *value = svn__apr_hash_index_val(hi);
+
+      if (strcmp(name, SVN_PROP_MIME_TYPE) == 0)
+        continue;
+
+      SVN_ERR(ensure_prop_is_regular_kind(name));
+      SVN_ERR(svn_wc_canonicalize_svn_prop(
+                &value, name, value,
+                local_abspath, node_kind, skip_some_checks,
+                get_file_for_validation, &gb, scratch_pool));
+      apr_hash_set(*prepared_props, name, APR_HASH_KEY_STRING, value);
+    }
+
+  return SVN_NO_ERROR;
+}
+
 
 svn_error_t *
 svn_wc_canonicalize_svn_prop(const svn_string_t **propval_p,

Modified: subversion/branches/ev2-export/subversion/libsvn_wc/props.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/props.h?rev=1424772&r1=1424771&r2=1424772&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/props.h (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/props.h Fri Dec 21 00:23:39 2012
@@ -56,6 +56,30 @@ svn_wc__internal_propget(const svn_strin
                          apr_pool_t *result_pool,
                          apr_pool_t *scratch_pool);
 
+/* Validate and canonicalize the PROPS like svn_wc_prop_set4() does;
+ * see that function for details of the SKIP_SOME_CHECKS option.
+ *
+ * The properties are checked against the node at LOCAL_ABSPATH (which
+ * need not be under version control) of kind KIND.  This text of this
+ * node may be read (if it is a file) in order to validate the
+ * svn:eol-style property.
+ *
+ * Only regular props are accepted; WC props and entry props raise an error
+ * (unlike svn_wc_prop_set4() which accepts WC props).
+ *
+ * Set *PREPARED_PROPS to the resulting canonicalized properties,
+ * allocating any new data in RESULT_POOL but making shallow copies of
+ * keys and unchanged values from PROPS.
+ */
+svn_error_t *
+svn_wc__canonicalize_props(apr_hash_t **prepared_props,
+                           const char *local_abspath,
+                           svn_node_kind_t node_kind,
+                           const apr_hash_t *props,
+                           svn_boolean_t skip_some_checks,
+                           apr_pool_t *result_pool,
+                           apr_pool_t *scratch_pool);
+
 
 /* Given LOCAL_ABSPATH/DB and an array of PROPCHANGES based on
    SERVER_BASEPROPS, calculate what changes should be applied to the working

Modified: subversion/branches/ev2-export/subversion/libsvn_wc/translate.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/translate.h?rev=1424772&r1=1424771&r2=1424772&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/translate.h (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/translate.h Fri Dec 21 00:23:39 2012
@@ -103,15 +103,21 @@ void svn_wc__eol_value_from_string(const
    If a keyword is in the list, but no corresponding value is
    available, do not create a hash entry for it.  If no keywords are
    found in the list, or if there is no list, set *KEYWORDS to NULL.
+     ### THIS LOOKS WRONG -- it creates a hash entry for every recognized kw
+         and expands each missing value as an empty string or "-1" or similar.
 
    Use LOCAL_ABSPATH to expand keyword values.
 
    If WRI_ABSPATH is not NULL, retrieve the information for LOCAL_ABSPATH
    from the working copy identified by WRI_ABSPATH. Falling back to file
    external information if the file is not present as versioned node.
+     ### THIS IS NOT IMPLEMENTED -- WRI_ABSPATH is ignored
 
    If FOR_NORMALIZATION is TRUE, just return a list of keywords instead of
    calculating their intended values.
+     ### This would be better done by a separate API, since in this case
+         only the KEYWORD_LIST input parameter is needed. (And there is no
+         need to print "-1" as the revision value.)
 
    Use SCRATCH_POOL for any temporary allocations.
 */

Modified: subversion/branches/ev2-export/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_wc/wc-queries.sql?rev=1424772&r1=1424771&r2=1424772&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/branches/ev2-export/subversion/libsvn_wc/wc-queries.sql Fri Dec 21 00:23:39 2012
@@ -357,7 +357,7 @@ WHERE work.wc_id = ?1 AND work.local_rel
 LIMIT 1
 
 -- STMT_SELECT_DELETION_INFO_SCAN
-/* ### FIXME.  modes_move.moved_to IS NOT NULL works when there is
+/* ### FIXME.  moved.moved_to IS NOT NULL works when there is
  only one move but we need something else when there are several. */
 SELECT (SELECT b.presence FROM nodes AS b
          WHERE b.wc_id = ?1 AND b.local_relpath = ?2 AND b.op_depth = 0),



Mime
View raw message