You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2014/01/26 16:07:57 UTC

svn commit: r1561502 [2/3] - in /subversion/branches/fsfs-ucsnorm: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ subversion/bindings/javahl/src/org/apache/subversion/javahl/ subversion/bindings/javahl/src/org/apache/subversion/...

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/rep-cache.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/rep-cache.h?rev=1561502&r1=1561501&r2=1561502&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/rep-cache.h (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/rep-cache.h Sun Jan 26 15:07:56 2014
@@ -61,7 +61,8 @@ svn_fs_fs__walk_rep_reference(svn_fs_t *
 
 /* Return the representation REP in FS which has fulltext CHECKSUM.
    REP is allocated in POOL.  If the rep cache database has not been
-   opened, just set *REP to NULL. */
+   opened, just set *REP to NULL.  Returns SVN_ERR_FS_CORRUPT if
+   a reference beyond HEAD is detected. */
 svn_error_t *
 svn_fs_fs__get_rep_reference(representation_t **rep,
                              svn_fs_t *fs,
@@ -69,16 +70,13 @@ svn_fs_fs__get_rep_reference(representat
                              apr_pool_t *pool);
 
 /* Set the representation REP in FS, using REP->CHECKSUM.
-   Use POOL for temporary allocations.
+   Use POOL for temporary allocations.  Returns SVN_ERR_FS_CORRUPT if
+   an existing reference beyond HEAD is detected.
 
-   If the rep cache database has not been opened, this may be a no op.
-
-   If REJECT_DUP is TRUE, return an error if there is an existing
-   match for REP->CHECKSUM. */
+   If the rep cache database has not been opened, this may be a no op. */
 svn_error_t *
 svn_fs_fs__set_rep_reference(svn_fs_t *fs,
                              representation_t *rep,
-                             svn_boolean_t reject_dup,
                              apr_pool_t *pool);
 
 /* Delete from the cache all reps corresponding to revisions younger

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/structure
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/structure?rev=1561502&r1=1561501&r2=1561502&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/structure (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/structure Sun Jan 26 15:07:56 2014
@@ -180,6 +180,7 @@ Mergeinfo metadata:
 Revision changed paths list:
   Format 1-3: Does not contain the node's kind.
   Format 4+:  Contains the node's kind.
+  Format 7+:  Contains the mergeinfo-mod flag.
 
 Shard packing:
   Format 4:   Applied to revision data only.
@@ -544,8 +545,8 @@ defined:
   props     "<rev> <item_index> <length> <size> <digest>" for props rep
             <rev> and <item_index> give location of rep
             <length> gives length of rep, sans header and trailer
-            <size> gives size of expanded rep; may be 0 if equal
-             to the length
+            <size> gives size of expanded rep; for props only, it may be 0
+             if equal to the length
             <digest> gives hex MD5 digest of expanded rep
             ### in formats >=4, also present:
             <sha1-digest> gives hex SHA1 digest of expanded rep
@@ -574,20 +575,23 @@ its location is not yet known.
 
 The changed-path data is represented as a series of changed-path
 items, each consisting of two lines.  The first line has the format
-"<id> <action> <text-mod> <prop-mod> <path>\n", where <id> is the
-node-rev ID of the new node-rev, <action> is "add", "delete",
-"replace", or "modify", <text-mod> and <prop-mod> are "true" or
-"false" indicating whether the text and/or properties changed, and
-<path> is the changed pathname.  For deletes, <id> is the node-rev ID
-of the deleted node-rev, and <text-mod> and <prop-mod> are always
-"false".  The second line has the format "<rev> <path>\n" containing
-the node-rev's copyfrom information if it has any; if it does not, the
-second line is blank.
+"<id> <action> <text-mod> <prop-mod> <mergeinfo-mod> <path>\n",
+where <id> is the node-rev ID of the new node-rev, <action> is "add",
+"delete", "replace", or "modify", <text-mod>, <prop-mod>, and
+<mergeinfo-mod>  are "true" or "false" indicating whether the text,
+properties and/or mergeinfo changed, and <path> is the changed pathname.
+For deletes, <id> is the node-rev ID of the deleted node-rev, and
+<text-mod> and <prop-mod> are always "false".  The second line has the
+format "<rev> <path>\n" containing the node-rev's copyfrom information
+if it has any; if it does not, the second line is blank.
 
 Starting with FS format 4, <action> may contain the kind ("file" or
 "dir") of the node, after a hyphen; for example, an added directory
 may be represented as "add-dir".
 
+Before with FS format 7, <mergeinfo-mod> flag is not available.  It may
+also be missing in revisions upgraded from pre-f7 formats.
+
 In physical addressing mode, at the very end of a rev file is a pair of
 lines containing "\n<root-offset> <cp-offset>\n", where <root-offset> is
 the offset of the root directory node revision and <cp-offset> is the

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/transaction.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/transaction.c?rev=1561502&r1=1561501&r2=1561502&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/transaction.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/transaction.c Sun Jan 26 15:07:56 2014
@@ -621,6 +621,7 @@ replace_change(svn_fs_path_change2_t *ol
                                                pool);
   old_change->text_mod = new_change->text_mod;
   old_change->prop_mod = new_change->prop_mod;
+  old_change->mergeinfo_mod = new_change->mergeinfo_mod;
   if (new_change->copyfrom_rev == SVN_INVALID_REVNUM)
     {
       old_change->copyfrom_rev = SVN_INVALID_REVNUM;
@@ -716,6 +717,7 @@ fold_change(apr_hash_t *changes,
               old_change->change_kind = svn_fs_path_change_delete;
               old_change->text_mod = info->text_mod;
               old_change->prop_mod = info->prop_mod;
+              old_change->mergeinfo_mod = info->mergeinfo_mod;
               old_change->copyfrom_rev = SVN_INVALID_REVNUM;
               old_change->copyfrom_path = NULL;
             }
@@ -743,6 +745,8 @@ fold_change(apr_hash_t *changes,
             old_change->text_mod = TRUE;
           if (info->prop_mod)
             old_change->prop_mod = TRUE;
+          if (info->mergeinfo_mod == svn_tristate_true)
+            old_change->mergeinfo_mod = svn_tristate_true;
           break;
         }
 
@@ -1441,10 +1445,14 @@ set_uniquifier(svn_fs_t *fs,
                apr_pool_t *pool)
 {
   svn_fs_fs__id_part_t temp;
+  fs_fs_data_t *ffd = fs->fsap_data;
 
-  SVN_ERR(get_new_txn_node_id(&temp, fs, &rep->txn_id, pool));
-  rep->uniquifier.noderev_txn_id = rep->txn_id;
-  rep->uniquifier.number = temp.number;
+  if (ffd->format >= SVN_FS_FS__MIN_REP_SHARING_FORMAT)
+    {
+      SVN_ERR(get_new_txn_node_id(&temp, fs, &rep->txn_id, pool));
+      rep->uniquifier.noderev_txn_id = rep->txn_id;
+      rep->uniquifier.number = temp.number;
+    }
 
   return SVN_NO_ERROR;
 }
@@ -1570,6 +1578,7 @@ svn_fs_fs__add_change(svn_fs_t *fs,
                       svn_fs_path_change_kind_t change_kind,
                       svn_boolean_t text_mod,
                       svn_boolean_t prop_mod,
+                      svn_boolean_t mergeinfo_mod,
                       svn_node_kind_t node_kind,
                       svn_revnum_t copyfrom_rev,
                       const char *copyfrom_path,
@@ -1587,6 +1596,9 @@ svn_fs_fs__add_change(svn_fs_t *fs,
   change = svn_fs__path_change_create_internal(id, change_kind, pool);
   change->text_mod = text_mod;
   change->prop_mod = prop_mod;
+  change->mergeinfo_mod = mergeinfo_mod
+                        ? svn_tristate_true
+                        : svn_tristate_false;
   change->node_kind = node_kind;
   change->copyfrom_rev = copyfrom_rev;
   change->copyfrom_path = apr_pstrdup(pool, copyfrom_path);
@@ -2093,7 +2105,7 @@ rep_write_get_baton(struct rep_write_bat
                           &whb,
                           b->rep_stream,
                           diff_version,
-                          SVN_DELTA_COMPRESSION_LEVEL_DEFAULT,
+                          ffd->delta_compression_level,
                           pool);
 
   b->delta_stream = svn_txdelta_target_push(wh, whb, source, b->pool);
@@ -2601,7 +2613,7 @@ write_container_rep(representation_t *re
 
       /* update the representation */
       rep->size = whb->size;
-      rep->expanded_size = 0;
+      rep->expanded_size = whb->size;
     }
 
   return SVN_NO_ERROR;
@@ -2684,7 +2696,7 @@ write_container_delta_rep(representation
                           &diff_whb,
                           file_stream,
                           diff_version,
-                          SVN_DELTA_COMPRESSION_LEVEL_DEFAULT,
+                          ffd->delta_compression_level,
                           pool);
 
   whb = apr_pcalloc(pool, sizeof(*whb));
@@ -3979,9 +3991,7 @@ write_reps_to_cache(svn_fs_t *fs,
     {
       representation_t *rep = APR_ARRAY_IDX(reps_to_cache, i, representation_t *);
 
-      /* FALSE because we don't care if another parallel commit happened to
-       * collide with us.  (Non-parallel collisions will not be detected.) */
-      SVN_ERR(svn_fs_fs__set_rep_reference(fs, rep, FALSE, scratch_pool));
+      SVN_ERR(svn_fs_fs__set_rep_reference(fs, rep, scratch_pool));
     }
 
   return SVN_NO_ERROR;

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/transaction.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/transaction.h?rev=1561502&r1=1561501&r2=1561502&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/transaction.h (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/transaction.h Sun Jan 26 15:07:56 2014
@@ -138,12 +138,12 @@ svn_fs_fs__set_entry(svn_fs_t *fs,
 
 /* Add a change to the changes record for filesystem FS in transaction
    TXN_ID.  Mark path PATH, having node-id ID, as changed according to
-   the type in CHANGE_KIND.  If the text representation was changed
-   set TEXT_MOD to TRUE, and likewise for PROP_MOD.  If this change
-   was the result of a copy, set COPYFROM_REV and COPYFROM_PATH to the
-   revision and path of the copy source, otherwise they should be set
-   to SVN_INVALID_REVNUM and NULL.  Perform any temporary allocations
-   from POOL. */
+   the type in CHANGE_KIND.  If the text representation was changed set
+   TEXT_MOD to TRUE, and likewise for PROP_MOD as well as MERGEINFO_MOD.
+   If this change was the result of a copy, set COPYFROM_REV and
+   COPYFROM_PATH to the revision and path of the copy source, otherwise
+   they should be set to SVN_INVALID_REVNUM and NULL.  Perform any
+   temporary allocations from POOL. */
 svn_error_t *
 svn_fs_fs__add_change(svn_fs_t *fs,
                       const svn_fs_fs__id_part_t *txn_id,
@@ -152,6 +152,7 @@ svn_fs_fs__add_change(svn_fs_t *fs,
                       svn_fs_path_change_kind_t change_kind,
                       svn_boolean_t text_mod,
                       svn_boolean_t prop_mod,
+                      svn_boolean_t mergeinfo_mod,
                       svn_node_kind_t node_kind,
                       svn_revnum_t copyfrom_rev,
                       const char *copyfrom_path,

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/tree.c?rev=1561502&r1=1561501&r2=1561502&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/tree.c Sun Jan 26 15:07:56 2014
@@ -1057,8 +1057,8 @@ open_path(parent_path_t **parent_path_p,
                 rest_path = rest_key;
               else
                 {
-                  svn_dirent_dirname(lookup->path, pool);
-                  rest_path = lookup->path + strlen(dirname) + 1;
+                  const char *part = svn_dirent_dirname(lookup->path, pool);
+                  rest_path = lookup->path + strlen(part) + 1;
                 }
             }
         }
@@ -1363,11 +1363,11 @@ get_dag(dag_node_t **dag_node_p,
 /* Add a change to the changes table in FS, keyed on transaction id
    TXN_ID, and indicated that a change of kind CHANGE_KIND occurred on
    PATH (whose node revision id is--or was, in the case of a
-   deletion--NODEREV_ID), and optionally that TEXT_MODs or PROP_MODs
-   occurred.  If the change resulted from a copy, COPYFROM_REV and
-   COPYFROM_PATH specify under which revision and path the node was
-   copied from.  If this was not part of a copy, COPYFROM_REV should
-   be SVN_INVALID_REVNUM.  Do all this as part of POOL.  */
+   deletion--NODEREV_ID), and optionally that TEXT_MODs, PROP_MODs or
+   MERGEINFO_MODs occurred.  If the change resulted from a copy,
+   COPYFROM_REV and COPYFROM_PATH specify under which revision and path
+   the node was copied from.  If this was not part of a copy, COPYFROM_REV
+   should be SVN_INVALID_REVNUM.  Do all this as part of POOL.  */
 static svn_error_t *
 add_change(svn_fs_t *fs,
            const svn_fs_fs__id_part_t *txn_id,
@@ -1376,6 +1376,7 @@ add_change(svn_fs_t *fs,
            svn_fs_path_change_kind_t change_kind,
            svn_boolean_t text_mod,
            svn_boolean_t prop_mod,
+           svn_boolean_t mergeinfo_mod,
            svn_node_kind_t node_kind,
            svn_revnum_t copyfrom_rev,
            const char *copyfrom_path,
@@ -1383,7 +1384,8 @@ add_change(svn_fs_t *fs,
 {
   return svn_fs_fs__add_change(fs, txn_id,
                                svn_fs__canonicalize_abspath(path, pool),
-                               noderev_id, change_kind, text_mod, prop_mod,
+                               noderev_id, change_kind,
+                               text_mod, prop_mod, mergeinfo_mod,
                                node_kind, copyfrom_rev, copyfrom_path,
                                pool);
 }
@@ -1631,6 +1633,7 @@ fs_change_node_prop(svn_fs_root_t *root,
   apr_hash_t *proplist;
   path_lookup_t lookup;
   const svn_fs_fs__id_part_t *txn_id;
+  svn_boolean_t modeinfo_mod = FALSE;
 
   if (! root->is_txn_root)
     return SVN_FS__NOT_TXN(root);
@@ -1674,6 +1677,8 @@ fs_change_node_prop(svn_fs_root_t *root,
           SVN_ERR(svn_fs_fs__dag_set_has_mergeinfo(parent_path->node,
                                                    (value != NULL), pool));
         }
+
+      modeinfo_mod = TRUE;
     }
 
   /* Set the property. */
@@ -1686,7 +1691,7 @@ fs_change_node_prop(svn_fs_root_t *root,
   /* Make a record of this modification in the changes table. */
   return add_change(root->fs, txn_id, path,
                     svn_fs_fs__dag_get_id(parent_path->node),
-                    svn_fs_path_change_modify, FALSE, TRUE,
+                    svn_fs_path_change_modify, FALSE, TRUE, modeinfo_mod,
                     svn_fs_fs__dag_node_kind(parent_path->node),
                     SVN_INVALID_REVNUM, NULL, pool);
 }
@@ -2531,8 +2536,8 @@ fs_make_dir(svn_fs_root_t *root,
 
   /* Make a record of this modification in the changes table. */
   return add_change(root->fs, txn_id, path, svn_fs_fs__dag_get_id(sub_dir),
-                    svn_fs_path_change_add, FALSE, FALSE, svn_node_dir,
-                    SVN_INVALID_REVNUM, NULL, pool);
+                    svn_fs_path_change_add, FALSE, FALSE, FALSE,
+                    svn_node_dir, SVN_INVALID_REVNUM, NULL, pool);
 }
 
 
@@ -2590,7 +2595,7 @@ fs_delete_node(svn_fs_root_t *root,
   /* Make a record of this modification in the changes table. */
   return add_change(root->fs, txn_id, path,
                     svn_fs_fs__dag_get_id(parent_path->node),
-                    svn_fs_path_change_delete, FALSE, FALSE, kind,
+                    svn_fs_path_change_delete, FALSE, FALSE, FALSE, kind,
                     SVN_INVALID_REVNUM, NULL, pool);
 }
 
@@ -2839,8 +2844,8 @@ copy_helper(svn_fs_root_t *from_root,
       /* Make a record of this modification in the changes table. */
       SVN_ERR(get_dag(&new_node, to_root, to_path, TRUE, pool));
       SVN_ERR(add_change(to_root->fs, txn_id, to_path,
-                         svn_fs_fs__dag_get_id(new_node), kind, FALSE, FALSE,
-                         svn_fs_fs__dag_node_kind(from_node),
+                         svn_fs_fs__dag_get_id(new_node), kind, FALSE,
+                         FALSE, FALSE, svn_fs_fs__dag_node_kind(from_node),
                          from_root->rev, from_canonpath, pool));
     }
   else
@@ -2996,8 +3001,8 @@ fs_make_file(svn_fs_root_t *root,
 
   /* Make a record of this modification in the changes table. */
   return add_change(root->fs, txn_id, path, svn_fs_fs__dag_get_id(child),
-                    svn_fs_path_change_add, TRUE, FALSE, svn_node_file,
-                    SVN_INVALID_REVNUM, NULL, pool);
+                    svn_fs_path_change_add, TRUE, FALSE, FALSE,
+                    svn_node_file, SVN_INVALID_REVNUM, NULL, pool);
 }
 
 
@@ -3255,8 +3260,8 @@ apply_textdelta(void *baton, apr_pool_t 
   /* Make a record of this modification in the changes table. */
   return add_change(tb->root->fs, txn_id, tb->path,
                     svn_fs_fs__dag_get_id(tb->node),
-                    svn_fs_path_change_modify, TRUE, FALSE, svn_node_file,
-                    SVN_INVALID_REVNUM, NULL, pool);
+                    svn_fs_path_change_modify, TRUE, FALSE, FALSE,
+                    svn_node_file, SVN_INVALID_REVNUM, NULL, pool);
 }
 
 
@@ -3390,8 +3395,8 @@ apply_text(void *baton, apr_pool_t *pool
   /* Make a record of this modification in the changes table. */
   return add_change(tb->root->fs, txn_id, tb->path,
                     svn_fs_fs__dag_get_id(tb->node),
-                    svn_fs_path_change_modify, TRUE, FALSE, svn_node_file,
-                    SVN_INVALID_REVNUM, NULL, pool);
+                    svn_fs_path_change_modify, TRUE, FALSE, FALSE,
+                    svn_node_file, SVN_INVALID_REVNUM, NULL, pool);
 }
 
 

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/verify.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/verify.c?rev=1561502&r1=1561501&r2=1561502&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/verify.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/verify.c Sun Jan 26 15:07:56 2014
@@ -233,6 +233,8 @@ compare_l2p_to_p2l_index(svn_fs_t *fs,
 
   svn_pool_destroy(iterpool);
 
+  SVN_ERR(svn_fs_fs__close_revision_file(&rev_file));
+
   return SVN_NO_ERROR;
 }
 
@@ -321,6 +323,8 @@ compare_p2l_to_l2p_index(svn_fs_t *fs,
 
   svn_pool_destroy(iterpool);
 
+  SVN_ERR(svn_fs_fs__close_revision_file(&rev_file));
+
   return SVN_NO_ERROR;
 }
 
@@ -576,6 +580,8 @@ compare_p2l_to_rev(svn_fs_t *fs,
 
   svn_pool_destroy(iterpool);
 
+  SVN_ERR(svn_fs_fs__close_revision_file(rev_file));
+
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_util/fs-util.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_util/fs-util.c?rev=1561502&r1=1561501&r2=1561502&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_util/fs-util.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_util/fs-util.c Sun Jan 26 15:07:56 2014
@@ -198,6 +198,7 @@ svn_fs__path_change_create_internal(cons
   change = apr_pcalloc(pool, sizeof(*change));
   change->node_rev_id = node_rev_id;
   change->change_kind = change_kind;
+  change->mergeinfo_mod = svn_tristate_unknown;
 
   return change;
 }

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_ra_serf/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_ra_serf/commit.c?rev=1561502&r1=1561501&r2=1561502&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_ra_serf/commit.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_ra_serf/commit.c Sun Jan 26 15:07:56 2014
@@ -1039,7 +1039,10 @@ setup_if_header_recursive(svn_boolean_t 
   apr_pool_t *iterpool = NULL;
 
   if (!commit_ctx->lock_tokens)
-    return SVN_NO_ERROR;
+    {
+      *added = FALSE;
+      return SVN_NO_ERROR;
+    }
 
   /* We try to create a directory, so within the Subversion world that
      would imply that there is nothing here, but mod_dav_svn still sees
@@ -1982,10 +1985,6 @@ apply_textdelta(void *file_baton,
    * writing to a temporary file (ugh). A special svn stream serf bucket
    * that returns EAGAIN until we receive the done call?  But, when
    * would we run through the serf context?  Grr.
-   *
-   * ctx->pool is the same for all files in the commit that send a
-   * textdelta so this file is explicitly closed in close_file to
-   * avoid too many simultaneously open files.
    */
 
   ctx->stream = svn_stream_lazyopen_create(delayed_commit_stream_open,

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_ra_serf/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_ra_serf/update.c?rev=1561502&r1=1561501&r2=1561502&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_ra_serf/update.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_ra_serf/update.c Sun Jan 26 15:07:56 2014
@@ -2259,6 +2259,47 @@ typedef struct update_delay_baton_t
   void *inner_handler_baton;
 } update_delay_baton_t;
 
+/* Helper for update_delay_handler() and process_pending() to
+   call UDB->INNER_HANDLER with buffer pointed by DATA. */
+static svn_error_t *
+process_buffer(update_delay_baton_t *udb,
+               serf_request_t *request,
+               const void *data,
+               apr_size_t len,
+               svn_boolean_t at_eof,
+               serf_bucket_alloc_t *alloc,
+               apr_pool_t *pool)
+{
+  serf_bucket_t *tmp_bucket;
+  svn_error_t *err;
+
+  /* ### This code (and the eagain bucket code) can probably be
+      ### simplified by using a bit of aggregate bucket magic.
+      ### See mail from Ivan to dev@s.a.o. */
+  if (at_eof)
+  {
+      tmp_bucket = serf_bucket_simple_create(data, len, NULL, NULL,
+                                             alloc);
+  }
+  else
+  {
+      tmp_bucket = svn_ra_serf__create_bucket_with_eagain(data, len,
+                                                          alloc);
+  }
+
+  /* If not at EOF create a bucket that finishes with EAGAIN, otherwise
+      use a standard bucket with default EOF handling */
+  err = udb->inner_handler(request, tmp_bucket,
+                           udb->inner_handler_baton, pool);
+
+  /* And free the bucket explicitly to avoid growing request allocator
+     storage (in a loop) */
+  serf_bucket_destroy(tmp_bucket);
+
+  return svn_error_trace(err);
+}
+
+
 /* Delaying wrapping reponse handler, to avoid creating too many
    requests to deliver efficiently */
 static svn_error_t *
@@ -2293,8 +2334,6 @@ update_delay_handler(serf_request_t *req
           apr_size_t len;
           svn_boolean_t at_eof = FALSE;
           svn_error_t *err;
-          serf_bucket_alloc_t *alloc;
-          serf_bucket_t *tmp_bucket;
 
           status = serf_bucket_read(response, PARSE_CHUNK_SIZE, &data, &len);
           if (SERF_BUCKET_READ_ERROR(status))
@@ -2310,31 +2349,10 @@ update_delay_handler(serf_request_t *req
           if (len == 0 && !at_eof)
             return svn_ra_serf__wrap_err(status, NULL);
 
-          alloc = serf_request_get_alloc(request);
+          err = process_buffer(udb, request, data, len, at_eof,
+                               serf_request_get_alloc(request),
+                               iterpool);
 
-          /* ### This code (and the eagain bucket code) can probably be
-             ### simplified by using a bit of aggregate bucket magic.
-             ### See mail from Ivan to dev@s.a.o. */
-          if (at_eof)
-            {
-              tmp_bucket = serf_bucket_simple_create(data, len, NULL, NULL,
-                                                     alloc);
-            }
-          else
-            {
-              tmp_bucket = svn_ra_serf__create_bucket_with_eagain(data, len,
-                                                                  alloc);
-            }
-
-          /* If not at EOF create a bucket that finishes with EAGAIN, otherwise
-             use a standard bucket with default EOF handling */
-          err = udb->inner_handler(request, tmp_bucket,
-                                   udb->inner_handler_baton, iterpool);
-
-          /* And free the bucket explicitly to avoid growing request allocator
-             storage (in a loop) */
-          serf_bucket_destroy(tmp_bucket);
-          
           if (err && SERF_BUCKET_READ_ERROR(err->apr_err))
             return svn_error_trace(err);
           else if (err && APR_STATUS_IS_EAGAIN(err->apr_err))
@@ -2398,7 +2416,7 @@ process_pending(update_delay_baton_t *ud
     {
       const char *data;
       apr_size_t len;
-      serf_bucket_t *tmp_bucket;
+      svn_boolean_t at_eof;
       svn_error_t *err;
 
       if (!iterpool)
@@ -2411,22 +2429,15 @@ process_pending(update_delay_baton_t *ud
 
       SVN_ERR(svn_spillbuf__read(&data, &len, udb->spillbuf, iterpool));
 
-      if (data == NULL)
-        {
-          if (!udb->report->report_received)
-            break;
-
-          tmp_bucket = serf_bucket_simple_create("", 0, NULL, NULL, alloc);
-        }
+      if (data == NULL && !udb->report->report_received)
+        break;
+      else if (data == NULL)
+        at_eof = TRUE;
       else
-        tmp_bucket = svn_ra_serf__create_bucket_with_eagain(data, len, alloc);
-
-      /* If not at EOF create a bucket that finishes with EAGAIN, otherwise
-         use a standard bucket with default EOF handling */
-      err = udb->inner_handler(NULL /* allowed? */, tmp_bucket,
-                               udb->inner_handler_baton, iterpool);
+        at_eof = FALSE;
 
-      serf_bucket_destroy(tmp_bucket);
+      err = process_buffer(udb, NULL /* allowed? */, data, len,
+                           at_eof, alloc, iterpool);
 
       if (err && APR_STATUS_IS_EAGAIN(err->apr_err))
         {

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_ra_serf/xml.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_ra_serf/xml.c?rev=1561502&r1=1561501&r2=1561502&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_ra_serf/xml.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_ra_serf/xml.c Sun Jan 26 15:07:56 2014
@@ -59,10 +59,6 @@
      (patch) <= XML_MICRO_VERSION))
 #endif /* APR_VERSION_AT_LEAST */
 
-#if XML_VERSION_AT_LEAST(1, 95, 8)
-#define EXPAT_HAS_STOPPARSER
-#endif
-
 /* Read/write chunks of this size into the spillbuf.  */
 #define PARSE_CHUNK_SIZE 8000
 
@@ -849,23 +845,34 @@ xml_cb_cdata(svn_ra_serf__xml_context_t 
 
 /* svn_error_t * wrapper around XML_Parse */
 static APR_INLINE svn_error_t *
-parse_xml(XML_Parser parser, const char *data, apr_size_t len, svn_boolean_t is_final)
+parse_xml(struct expat_ctx_t *ectx, const char *data, apr_size_t len, svn_boolean_t is_final)
 {
-  int xml_status = XML_Parse(parser, data, (int)len, is_final);
+  int xml_status = XML_Parse(ectx->parser, data, (int)len, is_final);
   const char *msg;
+  int xml_code;
 
-  /* ### Perhaps we should filter some specific error codes on systems
-         that use STOPPARSER to hide addtional errors */
   if (xml_status == XML_STATUS_OK)
-    return SVN_NO_ERROR;
+    return ectx->inner_error;
+
+  xml_code = XML_GetErrorCode(ectx->parser);
+
+#if XML_VERSION_AT_LEAST(1, 95, 8)
+  /* If we called XML_StopParser() expat will return an abort error. If we
+     have a better error stored we should ignore it as it will not help
+     the end-user to store it in the error chain. */
+  if (xml_code == XML_ERROR_ABORTED && ectx->inner_error)
+    return ectx->inner_error;
+#endif
 
-  msg = XML_ErrorString(XML_GetErrorCode(parser));
+  msg = XML_ErrorString(xml_code);
 
-  return svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA,
-                          svn_error_createf(SVN_ERR_XML_MALFORMED, NULL,
-                                            _("Malformed XML: %s"),
-                                            msg),
-                          _("The XML response contains invalid XML"));
+  return svn_error_compose_create(
+            ectx->inner_error,
+            svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA,
+                             svn_error_createf(SVN_ERR_XML_MALFORMED, NULL,
+                                               _("Malformed XML: %s"),
+                                               msg),
+                             _("The XML response contains invalid XML")));
 }
 
 /* Apr pool cleanup handler to release an XML_Parser in success and error
@@ -896,7 +903,7 @@ expat_start(void *userData, const char *
   ectx->inner_error = svn_error_trace(xml_cb_start(ectx->xmlctx,
                                                    raw_name, attrs));
 
-#ifdef EXPAT_HAS_STOPPARSER
+#if XML_VERSION_AT_LEAST(1, 95, 8)
   if (ectx->inner_error)
     (void) XML_StopParser(ectx->parser, 0 /* resumable */);
 #endif
@@ -914,7 +921,7 @@ expat_end(void *userData, const char *ra
 
   ectx->inner_error = svn_error_trace(xml_cb_end(ectx->xmlctx, raw_name));
 
-#ifdef EXPAT_HAS_STOPPARSER
+#if XML_VERSION_AT_LEAST(1, 95, 8)
   if (ectx->inner_error)
     (void) XML_StopParser(ectx->parser, 0 /* resumable */);
 #endif
@@ -932,7 +939,7 @@ expat_cdata(void *userData, const char *
 
   ectx->inner_error = svn_error_trace(xml_cb_cdata(ectx->xmlctx, data, len));
 
-#ifdef EXPAT_HAS_STOPPARSER
+#if XML_VERSION_AT_LEAST(1, 95, 8)
   if (ectx->inner_error)
     (void) XML_StopParser(ectx->parser, 0 /* resumable */);
 #endif
@@ -1008,9 +1015,7 @@ expat_response_handler(serf_request_t *r
       else if (APR_STATUS_IS_EOF(status))
         at_eof = TRUE;
 
-      err = parse_xml(ectx->parser, data, len, at_eof /* isFinal */);
-
-      err = svn_error_compose_create(ectx->inner_error, err);
+      err = parse_xml(ectx, data, len, at_eof /* isFinal */);
 
       if (at_eof || err)
         {

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_repos/dump.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_repos/dump.c?rev=1561502&r1=1561501&r2=1561502&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_repos/dump.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_repos/dump.c Sun Jan 26 15:07:56 2014
@@ -2209,23 +2209,22 @@ svn_repos_verify_fs3(svn_repos_t *repos,
                       verify_notify, verify_notify_baton,
                       cancel_func, cancel_baton, pool);
 
-  if (err && !keep_going)
+  if (err)
     {
+      if (err->apr_err == SVN_ERR_CANCELLED)
+        return svn_error_trace(err);
+
       found_corruption = TRUE;
       notify_verification_error(SVN_INVALID_REVNUM, err, notify_func,
                                 notify_baton, iterpool);
       svn_error_clear(err);
-      return svn_error_createf(SVN_ERR_REPOS_CORRUPTED, NULL,
-                               _("Repository '%s' failed to verify"),
-                               svn_dirent_local_style(svn_repos_path(repos,
-                                                                     pool),
-                                                      pool));
-    }
-  else
-    {
-      if (err)
-        found_corruption = TRUE;
-      svn_error_clear(err);
+
+      if (!keep_going)
+        return svn_error_createf(SVN_ERR_REPOS_CORRUPTED, NULL,
+                                _("Repository '%s' failed to verify"),
+                                svn_dirent_local_style(svn_repos_path(repos,
+                                                                      pool),
+                                                        pool));
     }
 
   for (rev = start_rev; rev <= end_rev; rev++)
@@ -2240,6 +2239,9 @@ svn_repos_verify_fs3(svn_repos_t *repos,
 
       if (err)
         {
+          if (err->apr_err == SVN_ERR_CANCELLED)
+            return svn_error_trace(err);
+
           found_corruption = TRUE;
           notify_verification_error(rev, err, notify_func, notify_baton,
                                     iterpool);

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_repos/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_repos/log.c?rev=1561502&r1=1561501&r2=1561502&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_repos/log.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_repos/log.c Sun Jan 26 15:07:56 2014
@@ -788,6 +788,10 @@ fs_mergeinfo_changed(svn_mergeinfo_catal
       changed_path = key;
       change = val;
 
+      /* If there was no mergeinfo change on this item, ignore it. */
+      if (change->mergeinfo_mod == svn_tristate_false)
+        continue;
+
       /* If there was no property change on this item, ignore it. */
       if (! change->prop_mod)
         continue;

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_repos/rev_hunt.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_repos/rev_hunt.c?rev=1561502&r1=1561501&r2=1561502&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_repos/rev_hunt.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_repos/rev_hunt.c Sun Jan 26 15:07:56 2014
@@ -1043,7 +1043,8 @@ get_merged_mergeinfo(apr_hash_t **merged
   while (1)
     {
       svn_fs_path_change2_t *changed_path = svn_hash_gets(changed_paths, path);
-      if (changed_path && changed_path->prop_mod)
+      if (changed_path && changed_path->prop_mod
+          && changed_path->mergeinfo_mod != svn_tristate_false)
         break;
       if (svn_fspath__is_root(path, strlen(path)))
         {

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_subr/io.c?rev=1561502&r1=1561501&r2=1561502&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_subr/io.c Sun Jan 26 15:07:56 2014
@@ -1688,10 +1688,10 @@ io_set_file_perms(const char *path,
 #ifdef WIN32
 /* This is semantically the same as the APR utf8_to_unicode_path
    function, but reimplemented here because APR does not export it. */
-static svn_error_t*
-io_utf8_to_unicode_path(const WCHAR **result,
-                        const char *source,
-                        apr_pool_t *result_pool)
+svn_error_t*
+svn_io__utf8_to_unicode_longpath(const WCHAR **result,
+                                 const char *source,
+                                 apr_pool_t *result_pool)
 {
     /* This is correct, we don't twist the filename if it will
      * definitely be shorter than 248 characters.  It merits some
@@ -1803,7 +1803,7 @@ io_win_file_attrs_set(const char *fname,
     DWORD flags;
     const WCHAR *wfname;
 
-    SVN_ERR(io_utf8_to_unicode_path(&wfname, fname, pool));
+    SVN_ERR(svn_io__utf8_to_unicode_longpath(&wfname, fname, pool));
 
     flags = GetFileAttributesW(wfname);
     if (flags == 0xFFFFFFFF)
@@ -3599,6 +3599,7 @@ svn_io_file_aligned_seek(apr_file_t *fil
       aligned_offset = offset - (offset % block_size);
       fill_buffer = TRUE;
     }
+  else
 #endif
     {
       aligned_offset = offset - (offset % file_buffer_size);

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_subr/sqlite.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_subr/sqlite.c?rev=1561502&r1=1561501&r2=1561502&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_subr/sqlite.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_subr/sqlite.c Sun Jan 26 15:07:56 2014
@@ -65,6 +65,10 @@ extern int (*const svn_sqlite3__api_conf
 #error SQLite is too old -- version 3.7.12 is the minimum required version
 #endif
 
+#ifndef SQLITE_DETERMINISTIC
+#define SQLITE_DETERMINISTIC 0
+#endif
+
 #ifdef SVN_UNICODE_NORMALIZATION_FIXES
 /* Limit the length of a GLOB or LIKE pattern. */
 #ifndef SQLITE_MAX_LIKE_PATTERN_LENGTH
@@ -113,7 +117,7 @@ sqlite_profiler(void *data, const char *
 static void
 sqlite_error_log(void* baton, int err, const char* msg)
 {
-  fprintf(stderr, "DBG: sqlite[S%d]: %s\n", err, msg);
+  fprintf(SVN_DBG_OUTPUT, "DBG: sqlite[S%d]: %s\n", err, msg);
 }
 #endif
 
@@ -1059,13 +1063,23 @@ svn_sqlite__open(svn_sqlite__db_t **db, 
                                       "svn-ucs-nfd", SQLITE_UTF8,
                                       *db, collate_ucs_nfd),
              *db);
-  SQLITE_ERR(sqlite3_create_function((*db)->db3, "glob", 2, SQLITE_UTF8,
+  /* ### Is it really necessary to override these functions?
+         I would assume the default implementation to be collation agnostic?
+         And otherwise our implementation should be...
+
+         The default implementation is in some cases index backed, while our
+         implementation can't be. With an index based on the collation it could
+         be. */
+  SQLITE_ERR(sqlite3_create_function((*db)->db3, "glob", 2,
+                                     SQLITE_UTF8 | SQLITE_DETERMINISTIC,
                                      *db, glob_ucs_nfd, NULL, NULL),
              *db);
-  SQLITE_ERR(sqlite3_create_function((*db)->db3, "like", 2, SQLITE_UTF8,
+  SQLITE_ERR(sqlite3_create_function((*db)->db3, "like", 2,
+                                     SQLITE_UTF8 | SQLITE_DETERMINISTIC,
                                      *db, like_ucs_nfd, NULL, NULL),
              *db);
-  SQLITE_ERR(sqlite3_create_function((*db)->db3, "like", 3, SQLITE_UTF8,
+  SQLITE_ERR(sqlite3_create_function((*db)->db3, "like", 3,
+                                     SQLITE_UTF8 | SQLITE_DETERMINISTIC,
                                      *db, like_ucs_nfd, NULL, NULL),
              *db);
 #endif /* SVN_UNICODE_NORMALIZATION_FIXES */
@@ -1437,9 +1451,11 @@ svn_error_t *
 svn_sqlite__create_scalar_function(svn_sqlite__db_t *db,
                                    const char *func_name,
                                    int argc,
+                                   svn_boolean_t deterministic,
                                    svn_sqlite__func_t func,
                                    void *baton)
 {
+  int eTextRep;
   struct function_wrapper_baton_t *fwb = apr_pcalloc(db->state_pool,
                                                      sizeof(*fwb));
 
@@ -1447,7 +1463,11 @@ svn_sqlite__create_scalar_function(svn_s
   fwb->func = func;
   fwb->baton = baton;
 
-  SQLITE_ERR(sqlite3_create_function(db->db3, func_name, argc, SQLITE_ANY,
+  eTextRep = SQLITE_ANY;
+  if (deterministic)
+    eTextRep |= SQLITE_DETERMINISTIC;
+
+  SQLITE_ERR(sqlite3_create_function(db->db3, func_name, argc, eTextRep,
                                      fwb, wrapped_func, NULL, NULL),
              db);
 

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_subr/stream.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_subr/stream.c?rev=1561502&r1=1561501&r2=1561502&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_subr/stream.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_subr/stream.c Sun Jan 26 15:07:56 2014
@@ -30,6 +30,7 @@
 #include <apr_file_io.h>
 #include <apr_errno.h>
 #include <apr_md5.h>
+#include <apr_portable.h>
 
 #include <zlib.h>
 
@@ -41,10 +42,12 @@
 #include "svn_checksum.h"
 #include "svn_path.h"
 #include "svn_private_config.h"
+#include "private/svn_atomic.h"
 #include "private/svn_error_private.h"
 #include "private/svn_eol_private.h"
 #include "private/svn_io_private.h"
 #include "private/svn_subr_private.h"
+#include "private/svn_utf_private.h"
 
 
 struct svn_stream_t {
@@ -1860,3 +1863,324 @@ svn_stream_lazyopen_create(svn_stream_la
 
   return stream;
 }
+
+/* Baton for install streams */
+struct install_baton_t
+{
+  struct baton_apr baton_apr;
+  const char *tmp_path;
+};
+
+#ifdef WIN32
+
+#if _WIN32_WINNT < 0x600 /* Does the SDK assume Windows Vista+? */
+typedef struct _FILE_RENAME_INFO {
+  BOOL   ReplaceIfExists;
+  HANDLE RootDirectory;
+  DWORD  FileNameLength;
+  WCHAR  FileName[1];
+} FILE_RENAME_INFO, *PFILE_RENAME_INFO;
+
+#define FileRenameInfo 3
+
+typedef BOOL (WINAPI *SetFileInformationByHandle_t)(HANDLE hFile,
+                                                    int FileInformationClass,
+                                                    LPVOID lpFileInformation,
+                                                    DWORD dwBufferSize);
+
+static volatile SetFileInformationByHandle_t SetFileInformationByHandle_p = 0;
+#define SetFileInformationByHandle (*SetFileInformationByHandle_p)
+
+static volatile svn_atomic_t SetFileInformationByHandle_a = 0;
+
+
+static svn_error_t *
+find_SetFileInformationByHandle(void *baton, apr_pool_t *scratch_pool)
+{
+  HMODULE kernel32 = GetModuleHandle("Kernel32.dll");
+
+  if (kernel32)
+    {
+      SetFileInformationByHandle_p =
+                    (SetFileInformationByHandle_t)
+                      GetProcAddress(kernel32, "SetFileInformationByHandle");
+    }
+
+  return SVN_NO_ERROR;
+}
+#endif /* WIN32 < Vista */
+
+/* Create and open a tempfile in DIRECTORY. Return its handle and path */
+static svn_error_t *
+create_tempfile(HANDLE *hFile,
+                const char **file_path,
+                const char *directory,
+                apr_pool_t *result_pool,
+                apr_pool_t *scratch_pool)
+{
+  const char *unique_name;
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+  static svn_atomic_t tempname_counter;
+  int baseNr = (GetTickCount() << 11) + 13 * svn_atomic_inc(&tempname_counter)
+               + GetCurrentProcessId();
+  int i = 0;
+  HANDLE h;
+
+  /* Shares common idea with io.c's temp_file_create */
+
+  do
+    {
+      apr_uint32_t unique_nr;
+      WCHAR *w_name;
+
+      /* Generate a number that should be unique for this application and
+         usually for the entire computer to reduce the number of cycles
+         through this loop. (A bit of calculation is much cheaper than
+         disk io) */
+      unique_nr = baseNr + 7 * i++;
+
+
+      svn_pool_clear(iterpool);
+      unique_name = svn_dirent_join(directory,
+                                    apr_psprintf(iterpool, "svn-%X",
+                                                 unique_nr),
+                                    iterpool);
+
+      SVN_ERR(svn_io__utf8_to_unicode_longpath(&w_name, unique_name,
+                                               iterpool));
+
+      /* Create a completely not-sharable file to avoid indexers, and other
+         filesystem watchers locking the file while we are still writing.
+
+         We need DELETE privileges to move the file. */
+      h = CreateFileW(w_name, GENERIC_WRITE | DELETE, 0 /* share */,
+                      NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
+
+      if (h == INVALID_HANDLE_VALUE)
+        {
+          apr_status_t status = apr_get_os_error();;
+          if (i > 1000)
+            return svn_error_createf(SVN_ERR_IO_UNIQUE_NAMES_EXHAUSTED,
+                           svn_error_wrap_apr(status, NULL),
+                           _("Unable to make name in '%s'"),
+                           svn_dirent_local_style(directory, scratch_pool));
+
+          if (!APR_STATUS_IS_EEXIST(status) && !APR_STATUS_IS_EACCES(status))
+            return svn_error_wrap_apr(status, NULL);
+        }
+    }
+  while (h == INVALID_HANDLE_VALUE);
+
+  *hFile = h;
+  *file_path = apr_pstrdup(result_pool, unique_name);
+  svn_pool_destroy(iterpool);
+
+  return SVN_NO_ERROR;
+}
+
+/* Implements svn_close_fn_t */
+static svn_error_t *
+install_close(void *baton)
+{
+  struct install_baton_t *ib = baton;
+
+  /* Flush the data cached in APR, but don't close the file yet */
+  SVN_ERR(svn_io_file_flush(ib->baton_apr.file, ib->baton_apr.pool));
+
+  return SVN_NO_ERROR;
+}
+
+#endif /* WIN32 */
+
+svn_error_t *
+svn_stream__create_for_install(svn_stream_t **install_stream,
+                               const char *tmp_abspath,
+                               apr_pool_t *result_pool,
+                               apr_pool_t *scratch_pool)
+{
+  apr_file_t *file;
+  struct install_baton_t *ib;
+  const char *tmp_path;
+
+#ifdef WIN32
+  HANDLE hInstall;
+  apr_status_t status;
+
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(tmp_abspath));
+
+  SVN_ERR(create_tempfile(&hInstall, &tmp_path, tmp_abspath,
+                          scratch_pool, scratch_pool));
+
+  /* Wrap as a standard APR file to allow sharing implementation.
+
+     But do note that some file functions (such as retrieving the name)
+     don't work on this wrapper. */
+  /* ### Buffered, or not? */
+  status = apr_os_file_put(&file, &hInstall,
+                           APR_WRITE | APR_BINARY | APR_BUFFERED,
+                           result_pool);
+
+  if (status)
+    {
+      CloseHandle(hInstall);
+      return svn_error_wrap_apr(status, NULL);
+    }
+
+  tmp_path = svn_dirent_internal_style(tmp_path, result_pool);
+#else
+
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(tmp_abspath));
+
+  SVN_ERR(svn_io_open_unique_file3(&file, &tmp_path, tmp_abspath,
+                                   svn_io_file_del_none,
+                                   result_pool, scratch_pool));
+#endif
+  *install_stream = svn_stream_from_aprfile2(file, FALSE, result_pool);
+
+  ib = apr_pcalloc(result_pool, sizeof(*ib));
+  ib->baton_apr = *(struct baton_apr*)(*install_stream)->baton;
+
+  assert((void*)&ib->baton_apr == (void*)ib); /* baton pointer is the same */
+
+  (*install_stream)->baton = ib;
+
+  ib->tmp_path = tmp_path;
+
+#ifdef WIN32
+  /* Don't close the file on stream close; flush instead */
+  svn_stream_set_close(*install_stream, install_close);
+#else
+  /* ### Install pool cleanup handler for tempfile? */
+#endif
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_stream__install_stream(svn_stream_t *install_stream,
+                           const char *final_abspath,
+                           svn_boolean_t make_parents,
+                           apr_pool_t *scratch_pool)
+{
+  struct install_baton_t *ib = install_stream->baton;
+  svn_error_t *err;
+
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(final_abspath));
+#ifdef WIN32
+
+#if _WIN32_WINNT < 0x600
+  SVN_ERR(svn_atomic__init_once(&SetFileInformationByHandle_a,
+                                find_SetFileInformationByHandle,
+                                NULL, scratch_pool));
+
+  if (!SetFileInformationByHandle_p)
+    SVN_ERR(svn_io_file_close(ib->baton_apr.file, scratch_pool));
+  else
+#endif /* WIN32 < Windows Vista */
+    {
+      WCHAR *w_final_abspath;
+      size_t path_len;
+      size_t rename_size;
+      FILE_RENAME_INFO *rename_info;
+      HANDLE hFile;
+
+      apr_os_file_get(&hFile, ib->baton_apr.file);
+
+      SVN_ERR(svn_utf__win32_utf8_to_utf16(&w_final_abspath,
+                                           svn_dirent_local_style(
+                                                          final_abspath,
+                                                          scratch_pool),
+                                           NULL, scratch_pool));
+      path_len = wcslen(w_final_abspath);
+      rename_size = sizeof(*rename_info) + sizeof(WCHAR) * path_len;
+
+      /* The rename info struct doesn't need hacks for long paths,
+         so no ugly escaping calls here */
+      rename_info = apr_pcalloc(scratch_pool, rename_size);
+      rename_info->ReplaceIfExists = TRUE;
+      rename_info->FileNameLength = path_len;
+      memcpy(rename_info->FileName, w_final_abspath, path_len * sizeof(WCHAR));
+
+      if (!SetFileInformationByHandle(hFile, FileRenameInfo, rename_info,
+                                      rename_size))
+        {
+          svn_boolean_t retry = FALSE;
+          err = svn_error_wrap_apr(apr_get_os_error(), NULL);
+
+          /* ### rhuijben: I wouldn't be surprised if we later find out that we
+                           have to fall back to close+rename on some specific
+                           error values here, to support some non standard NAS
+                           and filesystem scenarios. */
+
+          if (make_parents && err && APR_STATUS_IS_ENOENT(err->apr_err))
+            {
+              svn_error_t *err2;
+
+              err2 = svn_io_make_dir_recursively(svn_dirent_dirname(final_abspath,
+                                                            scratch_pool),
+                                                 scratch_pool);
+
+              if (err2)
+                return svn_error_trace(svn_error_compose_create(err, err2));
+              else
+                svn_error_clear(err);
+
+              retry = TRUE;
+              err = NULL;
+            }
+          else if (err && (APR_STATUS_IS_EACCES(err->apr_err)
+                           || APR_STATUS_IS_EEXIST(err->apr_err)))
+            {
+              svn_error_clear(err);
+              retry = TRUE;
+              err = NULL;
+
+              /* Set the destination file writable because Windows will not allow
+                 us to rename when final_abspath is read-only. */
+              SVN_ERR(svn_io_set_file_read_write(final_abspath, TRUE,
+                                                 scratch_pool));
+            }
+
+          if (retry)
+            {
+              if (!SetFileInformationByHandle(hFile, FileRenameInfo,
+                                              rename_info, rename_size))
+                {
+                  err = svn_error_wrap_apr(apr_get_os_error(), NULL);
+                }
+            }
+        }
+      else
+        err = NULL;
+
+      return svn_error_compose_create(err,
+                                      svn_io_file_close(ib->baton_apr.file,
+                                                        scratch_pool));
+    }
+#endif
+
+  err = svn_io_file_rename(ib->tmp_path, final_abspath, scratch_pool);
+
+  /* A missing directory is too common to not cover here. */
+  if (make_parents && err && APR_STATUS_IS_ENOENT(err->apr_err))
+    {
+      svn_error_t *err2;
+
+      err2 = svn_io_make_dir_recursively(svn_dirent_dirname(final_abspath,
+                                                            scratch_pool),
+                                         scratch_pool);
+
+      if (err2)
+        /* Creating directory didn't work: Return all errors */
+        return svn_error_trace(svn_error_compose_create(err, err2));
+      else
+        /* We could create a directory: retry install */
+        svn_error_clear(err);
+
+      SVN_ERR(svn_io_file_rename(ib->tmp_path, final_abspath, scratch_pool));
+    }
+  else
+    SVN_ERR(err);
+
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/wc_db.c?rev=1561502&r1=1561501&r2=1561502&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/wc_db.c Sun Jan 26 15:07:56 2014
@@ -355,13 +355,6 @@ convert_to_working_status(svn_wc__db_sta
                           svn_wc__db_status_t status);
 
 static svn_error_t *
-wclock_owns_lock(svn_boolean_t *own_lock,
-                 svn_wc__db_wcroot_t *wcroot,
-                 const char *local_relpath,
-                 svn_boolean_t exact,
-                 apr_pool_t *scratch_pool);
-
-static svn_error_t *
 db_is_switched(svn_boolean_t *is_switched,
                svn_node_kind_t *kind,
                svn_wc__db_wcroot_t *wcroot,
@@ -1473,12 +1466,12 @@ init_db(/* output values */
   SVN_ERR(svn_sqlite__exec_statements(db, STMT_CREATE_NODES_TRIGGERS));
   SVN_ERR(svn_sqlite__exec_statements(db, STMT_CREATE_EXTERNALS));
 
+  SVN_ERR(svn_wc__db_install_schema_statistics(db, scratch_pool));
+
   /* Insert the repository. */
   SVN_ERR(create_repos_id(repos_id, repos_root_url, repos_uuid,
                           db, scratch_pool));
 
-  SVN_ERR(svn_wc__db_install_schema_statistics(db, scratch_pool));
-
   /* Insert the wcroot. */
   /* ### Right now, this just assumes wc metadata is being stored locally. */
   SVN_ERR(svn_sqlite__get_statement(&stmt, db, STMT_INSERT_WCROOT));
@@ -4648,6 +4641,21 @@ db_op_copy(svn_wc__db_wcroot_t *src_wcro
     }
   else
     {
+      if (copyfrom_relpath)
+        {
+          const char *repos_root_url;
+          const char *repos_uuid;
+
+          /* Pass the right repos-id for the destination db! */
+
+          SVN_ERR(svn_wc__db_fetch_repos_info(&repos_root_url, &repos_uuid,
+                                              src_wcroot->sdb, copyfrom_id,
+                                              scratch_pool));
+
+          SVN_ERR(create_repos_id(&copyfrom_id, repos_root_url, repos_uuid,
+                                  dst_wcroot->sdb, scratch_pool));
+        }
+
       SVN_ERR(cross_db_copy(src_wcroot, src_relpath, dst_wcroot,
                             dst_relpath, dst_presence, dst_op_depth,
                             dst_np_op_depth, kind,
@@ -13885,8 +13893,9 @@ wclock_obtain_cb(svn_wc__db_wcroot_t *wc
 
       /* Check if we are the lock owner, because we should be able to
          extend our lock. */
-      err = wclock_owns_lock(&own_lock, wcroot, lock_relpath,
-                             TRUE, scratch_pool);
+      err = svn_wc__db_wclock_owns_lock_internal(&own_lock, wcroot,
+                                                 lock_relpath,
+                                                 TRUE, scratch_pool);
 
       if (err)
         SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
@@ -14224,12 +14233,12 @@ svn_wc__db_wclock_release(svn_wc__db_t *
 
 /* Like svn_wc__db_wclock_owns_lock() but taking WCROOT+LOCAL_RELPATH instead
    of DB+LOCAL_ABSPATH.  */
-static svn_error_t *
-wclock_owns_lock(svn_boolean_t *own_lock,
-                 svn_wc__db_wcroot_t *wcroot,
-                 const char *local_relpath,
-                 svn_boolean_t exact,
-                 apr_pool_t *scratch_pool)
+svn_error_t *
+svn_wc__db_wclock_owns_lock_internal(svn_boolean_t *own_lock,
+                                     svn_wc__db_wcroot_t *wcroot,
+                                     const char *local_relpath,
+                                     svn_boolean_t exact,
+                                     apr_pool_t *scratch_pool)
 {
   apr_array_header_t *owned_locks;
   int lock_level;
@@ -14296,8 +14305,8 @@ svn_wc__db_wclock_owns_lock(svn_boolean_
 
   VERIFY_USABLE_WCROOT(wcroot);
 
-  SVN_ERR(wclock_owns_lock(own_lock, wcroot, local_relpath, exact,
-                           scratch_pool));
+  SVN_ERR(svn_wc__db_wclock_owns_lock_internal(own_lock, wcroot, local_relpath,
+                                               exact, scratch_pool));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/wc_db_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/wc_db_private.h?rev=1561502&r1=1561501&r2=1561502&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/wc_db_private.h (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/wc_db_private.h Sun Jan 26 15:07:56 2014
@@ -495,6 +495,15 @@ svn_wc__db_read_props_internal(apr_hash_
                                apr_pool_t *result_pool,
                                apr_pool_t *scratch_pool);
 
+/* Like svn_wc__db_wclock_owns_lock() but taking WCROOT+LOCAL_RELPATH instead
+   of DB+LOCAL_ABSPATH.  */
+svn_error_t *
+svn_wc__db_wclock_owns_lock_internal(svn_boolean_t *own_lock,
+                                     svn_wc__db_wcroot_t *wcroot,
+                                     const char *local_relpath,
+                                     svn_boolean_t exact,
+                                     apr_pool_t *scratch_pool);
+
 /* Do a post-drive revision bump for the moved-away destination for
    any move sources under LOCAL_RELPATH.  This is called from within
    the revision bump transaction after the tree at LOCAL_RELPATH has

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/wc_db_update_move.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/wc_db_update_move.c?rev=1561502&r1=1561501&r2=1561502&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/wc_db_update_move.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/wc_db_update_move.c Sun Jan 26 15:07:56 2014
@@ -101,6 +101,31 @@
 #include "workqueue.h"
 #include "token-map.h"
 
+/* Helper functions */
+static svn_error_t *
+verify_write_lock(svn_wc__db_wcroot_t *wcroot,
+                  const char *local_relpath,
+                  apr_pool_t *scratch_pool)
+{
+  svn_boolean_t locked;
+
+  SVN_ERR(svn_wc__db_wclock_owns_lock_internal(&locked, wcroot, local_relpath,
+                                               FALSE, scratch_pool));
+  if (!locked)
+    {
+      return svn_error_createf(SVN_ERR_WC_NOT_LOCKED, NULL,
+                               _("No write-lock in '%s'"),
+                               svn_dirent_local_style(
+                                            svn_dirent_join(wcroot->abspath,
+                                                            local_relpath,
+                                                            scratch_pool),
+                                            scratch_pool));
+    }
+
+  return SVN_NO_ERROR;
+}
+
+
 /*
  * Receiver code.
  *
@@ -2021,6 +2046,9 @@ bump_mark_tree_conflict(svn_wc__db_wcroo
   svn_wc_conflict_version_t *old_version;
   svn_wc_conflict_version_t *new_version;
 
+  SVN_ERR(verify_write_lock(wcroot, move_src_op_root_relpath, scratch_pool));
+  SVN_ERR(verify_write_lock(wcroot, move_dst_op_root_relpath, scratch_pool));
+
   /* Read new (post-update) information from the new move source BASE node. */
   SVN_ERR(svn_wc__db_base_get_info_internal(NULL, &new_kind, &new_rev,
                                             &new_repos_relpath, &repos_id,
@@ -2137,8 +2165,11 @@ bump_moved_layer(svn_boolean_t *recurse,
   svn_boolean_t have_row;
   svn_skel_t *conflict;
   svn_boolean_t can_bump;
+
   const char *src_root_relpath = src_relpath;
 
+  SVN_ERR(verify_write_lock(wcroot, local_relpath, scratch_pool));
+
   *recurse = FALSE;
 
   SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/wc_db_util.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/wc_db_util.c?rev=1561502&r1=1561501&r2=1561502&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/wc_db_util.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/wc_db_util.c Sun Jan 26 15:07:56 2014
@@ -145,6 +145,7 @@ svn_wc__db_util_open_db(svn_sqlite__db_t
     SVN_ERR(svn_sqlite__exec_statements(*sdb, STMT_PRAGMA_LOCKING_MODE));
 
   SVN_ERR(svn_sqlite__create_scalar_function(*sdb, "relpath_depth", 1,
+                                             TRUE /* deterministic */,
                                              relpath_depth_sqlite, NULL));
 
   return SVN_NO_ERROR;

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/workqueue.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/workqueue.c?rev=1561502&r1=1561501&r2=1561502&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/workqueue.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/workqueue.c Sun Jan 26 15:07:56 2014
@@ -38,6 +38,7 @@
 #include "conflicts.h"
 #include "translate.h"
 
+#include "private/svn_io_private.h"
 #include "private/svn_skel.h"
 
 
@@ -469,7 +470,6 @@ run_file_install(work_item_baton_t *wqb,
   apr_hash_t *keywords;
   const char *temp_dir_abspath;
   svn_stream_t *dst_stream;
-  const char *dst_abspath;
   apr_int64_t val;
   const char *wcroot_abspath;
   const char *source_abspath;
@@ -572,10 +572,8 @@ run_file_install(work_item_baton_t *wqb,
   /* Translate to a temporary file. We don't want the user seeing a partial
      file, nor let them muck with it while we translate. We may also need to
      get its TRANSLATED_SIZE before the user can monkey it.  */
-  SVN_ERR(svn_stream_open_unique(&dst_stream, &dst_abspath,
-                                 temp_dir_abspath,
-                                 svn_io_file_del_none,
-                                 scratch_pool, scratch_pool));
+  SVN_ERR(svn_stream__create_for_install(&dst_stream, temp_dir_abspath,
+                                         scratch_pool, scratch_pool));
 
   /* Copy from the source to the dest, translating as we go. This will also
      close both streams.  */
@@ -584,35 +582,11 @@ run_file_install(work_item_baton_t *wqb,
                            scratch_pool));
 
   /* All done. Move the file into place.  */
-
-  {
-    svn_error_t *err;
-
-    err = svn_io_file_rename(dst_abspath, local_abspath, scratch_pool);
-
-    /* With a single db we might want to install files in a missing directory.
-       Simply trying this scenario on error won't do any harm and at least
-       one user reported this problem on IRC. */
-    if (err && APR_STATUS_IS_ENOENT(err->apr_err))
-      {
-        svn_error_t *err2;
-
-        err2 = svn_io_make_dir_recursively(svn_dirent_dirname(local_abspath,
-                                                              scratch_pool),
-                                           scratch_pool);
-
-        if (err2)
-          /* Creating directory didn't work: Return all errors */
-          return svn_error_trace(svn_error_compose_create(err, err2));
-        else
-          /* We could create a directory: retry install */
-          svn_error_clear(err);
-
-        SVN_ERR(svn_io_file_rename(dst_abspath, local_abspath, scratch_pool));
-      }
-    else
-      SVN_ERR(err);
-  }
+  /* With a single db we might want to install files in a missing directory.
+     Simply trying this scenario on error won't do any harm and at least
+     one user reported this problem on IRC. */
+  SVN_ERR(svn_stream__install_stream(dst_stream, local_abspath,
+                                     TRUE /* make_parents*/, scratch_pool));
 
   /* Tweak the on-disk file according to its properties.  */
 #ifndef WIN32

Modified: subversion/branches/fsfs-ucsnorm/subversion/mod_dav_svn/dav_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/mod_dav_svn/dav_svn.h?rev=1561502&r1=1561501&r2=1561502&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/mod_dav_svn/dav_svn.h (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/mod_dav_svn/dav_svn.h Sun Jan 26 15:07:56 2014
@@ -54,7 +54,7 @@ extern "C" {
 
 /* Option values for SVNAllowBulkUpdates.  Note that
    it's important that CONF_BULKUPD_DEFAULT is 0 to make
-   dav_svn_merge_dir_config do the right thing. */
+   merge_dir_config in mod_dav_svn do the right thing. */
 typedef enum dav_svn__bulk_upd_conf {
     CONF_BULKUPD_DEFAULT,
     CONF_BULKUPD_ON,

Modified: subversion/branches/fsfs-ucsnorm/subversion/mod_dav_svn/mod_dav_svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/mod_dav_svn/mod_dav_svn.c?rev=1561502&r1=1561501&r2=1561502&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/mod_dav_svn/mod_dav_svn.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/mod_dav_svn/mod_dav_svn.c Sun Jan 26 15:07:56 2014
@@ -72,7 +72,7 @@ typedef struct server_conf_t {
 
 /* A tri-state enum used for per directory on/off flags.  Note that
    it's important that CONF_FLAG_DEFAULT is 0 to make
-   dav_svn_merge_dir_config do the right thing. */
+   merge_dir_config in mod_dav_svn do the right thing. */
 enum conf_flag {
   CONF_FLAG_DEFAULT,
   CONF_FLAG_ON,

Modified: subversion/branches/fsfs-ucsnorm/subversion/svn/log-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/svn/log-cmd.c?rev=1561502&r1=1561501&r2=1561502&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/svn/log-cmd.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/svn/log-cmd.c Sun Jan 26 15:07:56 2014
@@ -548,8 +548,19 @@ svn_cl__log_entry_receiver_xml(void *bat
 
   revstr = apr_psprintf(pool, "%ld", log_entry->revision);
   /* <logentry revision="xxx"> */
-  svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "logentry",
-                        "revision", revstr, SVN_VA_NULL);
+  if (lb->merge_stack && lb->merge_stack->nelts > 0)
+    {
+      svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "logentry",
+                            "revision", revstr, "reverse-merge",
+                            log_entry->subtractive_merge ? "true" : "false",
+                            SVN_VA_NULL);
+
+    }
+  else
+    {
+        svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "logentry",
+                              "revision", revstr, SVN_VA_NULL);
+    }
 
   /* <author>xxx</author> */
   svn_cl__xml_tagged_cdata(&sb, pool, "author", author);

Modified: subversion/branches/fsfs-ucsnorm/subversion/svnserve/svnserve.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/svnserve/svnserve.c?rev=1561502&r1=1561501&r2=1561502&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/svnserve/svnserve.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/svnserve/svnserve.c Sun Jan 26 15:07:56 2014
@@ -660,7 +660,6 @@ sub_main(int *exit_code, int argc, const
   enum run_mode run_mode = run_mode_unspecified;
   svn_boolean_t foreground = FALSE;
   apr_socket_t *sock;
-  apr_file_t *in_file, *out_file;
   apr_sockaddr_t *sa;
   svn_error_t *err;
   apr_getopt_t *os;
@@ -668,7 +667,9 @@ sub_main(int *exit_code, int argc, const
   serve_params_t params;
   const char *arg;
   apr_status_t status;
+#ifndef WIN32
   apr_proc_t proc;
+#endif
 #if APR_HAS_THREADS && !HAVE_THREADPOOLS
   apr_threadattr_t *tattr;
   apr_thread_t *tid;
@@ -1009,6 +1010,7 @@ sub_main(int *exit_code, int argc, const
     {
       apr_pool_t *connection_pool;
       svn_ra_svn_conn_t *conn;
+      apr_file_t *in_file, *out_file;
 
       params.tunnel = (run_mode == run_mode_tunnel);
       apr_pool_cleanup_register(pool, pool, apr_pool_cleanup_null,

Modified: subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/copy_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/copy_tests.py?rev=1561502&r1=1561501&r2=1561502&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/copy_tests.py (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/copy_tests.py Sun Jan 26 15:07:56 2014
@@ -25,7 +25,7 @@
 ######################################################################
 
 # General modules
-import stat, os, re, shutil, logging
+import stat, os, re, shutil, logging, sys
 
 logger = logging.getLogger()
 
@@ -5787,6 +5787,33 @@ def copy_over_excluded(sbox):
                                        sbox.ospath('A/C'),
                                        sbox.ospath('A/D'))
 
+def copy_relocate(sbox):
+  "copy from a relocated location"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  tmp_dir = sbox.add_wc_path('relocated')
+
+  shutil.copytree(sbox.repo_dir, tmp_dir)
+
+  url = 'file://'
+
+  if sys.platform == 'win32':
+    url += '/'
+
+  url += os.path.abspath(tmp_dir).replace(os.path.sep, '/')
+
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'relocate', url, wc_dir)
+
+  copiedpath = sbox.ospath('AA')
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'cp', url + '/A', copiedpath)
+
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'info', copiedpath)
+
 ########################################################################
 # Run the tests
 
@@ -5904,6 +5931,7 @@ test_list = [ None,
               copy_to_unversioned_parent,
               copy_text_conflict,
               copy_over_excluded,
+              copy_relocate,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/diff_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/diff_tests.py?rev=1561502&r1=1561501&r2=1561502&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/diff_tests.py (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/diff_tests.py Sun Jan 26 15:07:56 2014
@@ -49,6 +49,13 @@ Item = svntest.wc.StateItem
 ######################################################################
 # Generate expected output
 
+def is_absolute_url(target):
+  return (target.startswith('file://')
+          or target.startswith('http://')
+          or target.startswith('https://')
+          or target.startswith('svn://')
+          or target.startswith('svn+ssh://'))
+
 def make_diff_header(path, old_tag, new_tag, src_label=None, dst_label=None):
   """Generate the expected diff header for file PATH, with its old and new
   versions described in parentheses by OLD_TAG and NEW_TAG. SRC_LABEL and
@@ -57,12 +64,16 @@ def make_diff_header(path, old_tag, new_
   Return the header as an array of newline-terminated strings."""
   if src_label:
     src_label = src_label.replace('\\', '/')
-    src_label = '\t(.../' + src_label + ')'
+    if not is_absolute_url(src_label):
+      src_label = '.../' + src_label
+    src_label = '\t(' + src_label + ')'
   else:
     src_label = ''
   if dst_label:
     dst_label = dst_label.replace('\\', '/')
-    dst_label = '\t(.../' + dst_label + ')'
+    if not is_absolute_url(dst_label):
+      dst_label = '.../' + dst_label
+    dst_label = '\t(' + dst_label + ')'
   else:
     dst_label = ''
   path_as_shown = path.replace('\\', '/')
@@ -4667,6 +4678,25 @@ def diff_move_inside_copy(sbox):
   # Bug: Diffing the copied-along parent directory asserts
   svntest.actions.run_and_verify_svn(None, svntest.verify.AnyOutput, [],
                                      'diff', sbox.ospath(h_path))
+@XFail()
+@Issue(4464)
+def diff_repo_wc_copies(sbox):
+  "diff repo to wc of a copy"
+  sbox.build()
+  wc_dir = sbox.wc_dir
+  iota_copy = sbox.ospath('iota_copy')
+  iota_url = sbox.repo_url + '/iota'
+
+  sbox.simple_copy('iota', 'iota_copy')
+  expected_output = make_diff_header(iota_copy, "revision 0", "working copy",
+                                     iota_url, iota_copy) + [
+                                       "@@ -0,0 +1 @@\n",
+                                       "+This is the file 'iota'.\n" ]
+  svntest.actions.run_and_verify_svn(None, expected_output, [], 'diff',
+                                     '--show-copies-as-adds',
+                                     iota_url, iota_copy)
+
+
 
 ########################################################################
 #Run the tests
@@ -4750,6 +4780,7 @@ test_list = [ None,
               diff_missing_tree_conflict_victim,
               diff_local_missing_obstruction,
               diff_move_inside_copy,
+              diff_repo_wc_copies,
               ]
 
 if __name__ == '__main__':

Modified: subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/log_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/log_tests.py?rev=1561502&r1=1561501&r2=1561502&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/log_tests.py (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/log_tests.py Sun Jan 26 15:07:56 2014
@@ -2598,6 +2598,77 @@ def mergeinfo_log(sbox):
   # TODO: Validate the output, the check_log_chain() function assumes it
   # gets the output of the message
 
+@SkipUnless(server_has_mergeinfo)
+@Issue(4463)
+def merge_sensitive_log_xml_reverse_merges(sbox):
+  "log -g --xml differentiates forward/reverse merges"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+  wc_disk, wc_status = set_up_branch(sbox)
+
+  A_path      = os.path.join(wc_dir, 'A')
+  A_COPY_path = os.path.join(wc_dir, 'A_COPY')
+  D_COPY_path = os.path.join(wc_dir, 'A_COPY', 'D')
+
+  # Merge -c3,5 from A to A_COPY, commit as r7
+  svntest.main.run_svn(None, 'up', wc_dir)
+  svntest.main.run_svn(None, 'merge', '-c3,5', A_path, A_COPY_path)
+  sbox.simple_commit(message='Merge -c3,5 from A to A_COPY')
+
+  # Merge -c-3,-5,4,6 from A to A_COPY, commit as r8
+  svntest.main.run_svn(None, 'up', wc_dir)
+  svntest.main.run_svn(None, 'merge', '-c-3,4,-5,6', A_path, A_COPY_path)
+  sbox.simple_commit(message='Merge -c-3,-5,4,6 from A to A_COPY')
+
+  # Update so
+  svntest.main.run_svn(None, 'up', wc_dir)
+
+  # Run log -g --xml on path with explicit mergeinfo (A_COPY).
+  log_attrs = [
+          {
+              u'revision': u'8',
+          },
+          {
+              u'revision': u'6',
+              u'reverse-merge': u'false',
+          },
+          {
+              u'revision': u'5',
+              u'reverse-merge': u'true',
+          },
+          {
+              u'revision': u'4',
+              u'reverse-merge': u'false',
+          },
+          {
+              u'revision': u'3',
+              u'reverse-merge': u'true',
+          }]
+  svntest.actions.run_and_verify_log_xml(expected_log_attrs=log_attrs,
+                                         args=['-g', '-r8', A_COPY_path])
+
+  # Run log -g --xml on path with inherited mergeinfo (A_COPY/D).
+  # r5 only affects A_COPY/B/E/beta so not listed
+  log_attrs = [
+          {
+              u'revision': u'8',
+          },
+          {
+              u'revision': u'6',
+              u'reverse-merge': u'false',
+          },
+          {
+              u'revision': u'4',
+              u'reverse-merge': u'false',
+          },
+          {
+              u'revision': u'3',
+              u'reverse-merge': u'true',
+          }]
+  svntest.actions.run_and_verify_log_xml(expected_log_attrs=log_attrs,
+                                         args=['-g', '-r8', D_COPY_path])
+
 
 ########################################################################
 # Run the tests
@@ -2647,6 +2718,7 @@ test_list = [ None,
               log_multiple_revs_spanning_rename,
               log_auto_move,
               mergeinfo_log,
+              merge_sensitive_log_xml_reverse_merges,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/svnadmin_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/svnadmin_tests.py?rev=1561502&r1=1561501&r2=1561502&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/svnadmin_tests.py (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/svnadmin_tests.py Sun Jan 26 15:07:56 2014
@@ -1540,15 +1540,15 @@ def verify_non_utf8_paths(sbox):
     if line == "A\n":
       # replace 'A' with a latin1 character -- the new path is not valid UTF-8
       fp_new.write("\xE6\n")
-    elif line == "text: 1 279 32 0 d63ecce65d8c428b86f4f8b0920921fe\n":
+    elif line == "text: 1 279 32 32 d63ecce65d8c428b86f4f8b0920921fe\n":
       # phys, PLAIN directories: fix up the representation checksum
-      fp_new.write("text: 1 279 32 0 b50b1d5ed64075b5f632f3b8c30cd6b2\n")
+      fp_new.write("text: 1 279 32 32 b50b1d5ed64075b5f632f3b8c30cd6b2\n")
     elif line == "text: 1 292 44 32 a6be7b4cf075fd39e6a99eb69a31232b\n":
       # phys, deltified directories: fix up the representation checksum
       fp_new.write("text: 1 292 44 32 f2e93e73272cac0f18fccf16f224eb93\n")
-    elif line == "text: 1 6 31 0 90f306aa9bfd72f456072076a2bd94f7\n":
+    elif line == "text: 1 6 31 31 90f306aa9bfd72f456072076a2bd94f7\n":
       # log addressing: fix up the representation checksum
-      fp_new.write("text: 1 6 31 0 db2d4a0bad5dff0aea9a288dec02f1fb\n")
+      fp_new.write("text: 1 6 31 31 db2d4a0bad5dff0aea9a288dec02f1fb\n")
     elif line == "cpath: /A\n":
       # also fix up the 'created path' field
       fp_new.write("cpath: /\xE6\n")
@@ -1941,8 +1941,8 @@ def mergeinfo_race(sbox):
 
 @Issue(4213)
 @Skip(svntest.main.is_fs_type_fsx)
-def recover_old(sbox):
-  "recover --pre-1.4-compatible"
+def recover_old_empty(sbox):
+  "recover empty --compatible-version=1.3"
   svntest.main.safe_rmtree(sbox.repo_dir, 1)
   svntest.main.create_repos(sbox.repo_dir, minor_version=3)
   svntest.actions.run_and_verify_svnadmin(None, None, [],
@@ -2213,6 +2213,35 @@ def verify_denormalized_names(sbox):
     output, errput, exp_out, exp_err)
 
 
+@SkipUnless(svntest.main.is_fs_type_fsfs)
+def fsfs_recover_old_non_empty(sbox):
+  "fsfs recover non-empty --compatible-version=1.3"
+
+  # Around trunk@1560210, 'svnadmin recover' wrongly errored out
+  # for the --compatible-version=1.3 Greek tree repository:
+  # svnadmin: E200002: Serialized hash missing terminator
+
+  sbox.build(create_wc=False, minor_version=3)
+  svntest.actions.run_and_verify_svnadmin(None, None, [], "recover",
+                                          sbox.repo_dir)
+
+
+@SkipUnless(svntest.main.is_fs_type_fsfs)
+def fsfs_hotcopy_old_non_empty(sbox):
+  "fsfs hotcopy non-empty --compatible-version=1.3"
+
+  # Around trunk@1560210, 'svnadmin hotcopy' wrongly errored out
+  # for the --compatible-version=1.3 Greek tree repository:
+  # svnadmin: E160006: No such revision 1
+
+  sbox.build(create_wc=False, minor_version=3)
+  backup_dir, backup_url = sbox.add_repo_path('backup')
+  svntest.actions.run_and_verify_svnadmin(None, None, [], "hotcopy",
+                                          sbox.repo_dir, backup_dir)
+
+  check_hotcopy_fsfs(sbox.repo_dir, backup_dir)
+
+
 ########################################################################
 # Run the tests
 
@@ -2248,10 +2277,12 @@ test_list = [ None,
               hotcopy_incremental_packed,
               locking,
               mergeinfo_race,
-              recover_old,
+              recover_old_empty,
               verify_keep_going,
               verify_invalid_path_changes,
               verify_denormalized_names,
+              fsfs_recover_old_non_empty,
+              fsfs_hotcopy_old_non_empty,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/svntest/actions.py
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/svntest/actions.py?rev=1561502&r1=1561501&r2=1561502&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/svntest/actions.py (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/svntest/actions.py Sun Jan 26 15:07:56 2014
@@ -561,8 +561,13 @@ def run_and_verify_export(URL, export_di
 # run_and_verify_log_xml
 
 class LogEntry:
-  def __init__(self, revision, changed_paths=None, revprops=None):
+  def __init__(self, revision, attributes=None,
+               changed_paths=None, revprops=None):
     self.revision = revision
+    if attributes == None:
+      self.attributes = {}
+    else:
+      self.attributes = attributes
     if changed_paths == None:
       self.changed_paths = {}
     else:
@@ -572,6 +577,15 @@ class LogEntry:
     else:
       self.revprops = revprops
 
+  def assert_log_attrs(self, attributes):
+    """Assert that attributes is the same as this entry's attributes
+    Raises svntest.Failure if not.
+    """
+    if self.attributes != attributes:
+      raise Failure('\n' + '\n'.join(difflib.ndiff(
+            pprint.pformat(attributes).splitlines(),
+            pprint.pformat(self.attributes).splitlines())))
+
   def assert_changed_paths(self, changed_paths):
     """Assert that changed_paths is the same as this entry's changed_paths
     Raises svntest.Failure if not.
@@ -649,7 +663,7 @@ class LogParser:
 
   # element handlers
   def logentry_start(self, attrs):
-    self.entries.append(LogEntry(int(attrs['revision'])))
+    self.entries.append(LogEntry(int(attrs['revision']), attrs))
   def author_end(self):
     self.svn_prop('author')
   def msg_end(self):
@@ -669,9 +683,10 @@ class LogParser:
     self.entries[-1].changed_paths[self.use_cdata()] = [{'kind': self.kind,
                                                          'action': self.action}]
 
-def run_and_verify_log_xml(message=None, expected_paths=None,
-                           expected_revprops=None, expected_stdout=None,
-                           expected_stderr=None, args=[]):
+def run_and_verify_log_xml(message=None, expected_log_attrs=None,
+                           expected_paths=None, expected_revprops=None,
+                           expected_stdout=None, expected_stderr=None,
+                           args=[]):
   """Call run_and_verify_svn with log --xml and args (optional) as command
   arguments, and pass along message, expected_stdout, and expected_stderr.
 
@@ -679,6 +694,10 @@ def run_and_verify_log_xml(message=None,
 
   expected_paths checking is not yet implemented.
 
+  expected_log_attrs is an optional list of dicts, compared to each revisions's
+  logentry attributes.  The list must be in the same order the log entries
+  come in.
+
   expected_revprops is an optional list of dicts, compared to each
   revision's revprops.  The list must be in the same order the log entries
   come in.  Any svn:date revprops in the dicts must be '' in order to
@@ -717,6 +736,8 @@ def run_and_verify_log_xml(message=None,
       entry.assert_revprops(expected_revprops[index])
     if expected_paths != None:
       entry.assert_changed_paths(expected_paths[index])
+    if expected_log_attrs != None:
+      entry.assert_log_attrs(expected_log_attrs[index])
 
 
 def verify_update(actual_output,

Modified: subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/update_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/update_tests.py?rev=1561502&r1=1561501&r2=1561502&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/update_tests.py (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/update_tests.py Sun Jan 26 15:07:56 2014
@@ -6606,6 +6606,7 @@ def windows_update_backslash(sbox):
     expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
     svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
+@XFail() # Tries to modify unlocked part of working copy; found via r1561425
 def update_moved_away(sbox):
   "update subtree of moved away"
 

Propchange: subversion/branches/fsfs-ucsnorm/subversion/tests/libsvn_client/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Sun Jan 26 15:07:56 2014
@@ -1,3 +1,3 @@
 .libs
-client-test
+*-test
 *.lo

Modified: subversion/branches/fsfs-ucsnorm/subversion/tests/libsvn_client/client-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/tests/libsvn_client/client-test.c?rev=1561502&r1=1561501&r2=1561502&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/tests/libsvn_client/client-test.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/tests/libsvn_client/client-test.c Sun Jan 26 15:07:56 2014
@@ -779,7 +779,7 @@ test_suggest_mergesources(const svn_test
   apr_array_header_t *results;
   svn_opt_revision_t peg_rev;
   svn_opt_revision_t head_rev;
-  const char *wc_dir;
+  const char *wc_path;
 
   peg_rev.kind = svn_opt_revision_unspecified;
 
@@ -802,19 +802,20 @@ test_suggest_mergesources(const svn_test
                           svn_path_url_add_component2(repos_url, "A", pool));
 
   /* And now test the same thing with a minimal working copy */
-  wc_dir = svn_test_data_path("mergesources-wc", pool);
-  svn_test_add_dir_cleanup(wc_dir);
+  wc_path = svn_test_data_path("mergesources-wc", pool);
+  svn_test_add_dir_cleanup(wc_path);
+  SVN_ERR(svn_io_remove_dir2(wc_path, TRUE, NULL, NULL, pool));
 
   head_rev.kind = svn_opt_revision_head;
   SVN_ERR(svn_client_checkout3(NULL,
                                svn_path_url_add_component2(repos_url, "AA", pool),
-                               wc_dir,
+                               wc_path,
                                &head_rev, &head_rev, svn_depth_empty,
                                FALSE, FALSE, ctx, pool));
 
 
   SVN_ERR(svn_client_suggest_merge_sources(&results,
-                                           wc_dir,
+                                           wc_path,
                                            &peg_rev, ctx, pool));
   SVN_TEST_ASSERT(results != NULL);
   SVN_TEST_ASSERT(results->nelts >= 1);