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 2013/12/10 07:58:37 UTC

svn commit: r1549771 [1/2] - in /subversion/branches/fsfs-ucsnorm: ./ contrib/server-side/svncutter/ subversion/bindings/swig/include/ subversion/include/ subversion/libsvn_client/ subversion/libsvn_diff/ subversion/libsvn_fs/ subversion/libsvn_fs_fs/ ...

Author: brane
Date: Tue Dec 10 06:58:35 2013
New Revision: 1549771

URL: http://svn.apache.org/r1549771
Log:
On the fsfs-ucsnorm branch: Sync with trunk@r1549770.

Added:
    subversion/branches/fsfs-ucsnorm/subversion/svn/cl-log.h
      - copied unchanged from r1549770, subversion/trunk/subversion/svn/cl-log.h
Modified:
    subversion/branches/fsfs-ucsnorm/   (props changed)
    subversion/branches/fsfs-ucsnorm/configure.ac
    subversion/branches/fsfs-ucsnorm/contrib/server-side/svncutter/svncutter
    subversion/branches/fsfs-ucsnorm/subversion/bindings/swig/include/svn_containers.swg
    subversion/branches/fsfs-ucsnorm/subversion/include/svn_client.h
    subversion/branches/fsfs-ucsnorm/subversion/include/svn_diff.h
    subversion/branches/fsfs-ucsnorm/subversion/include/svn_wc.h
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_client/cleanup.c
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_client/deprecated.c
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_diff/parse-diff.c
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs/fs-loader.c
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/cached_data.c
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/fs.h
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/fs_fs.c
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/id.c
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/recovery.c
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/rep-cache.c
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/tree.c
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/util.h
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/   (props changed)
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/cached_data.c
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/dag.c
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/id.c
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/id.h
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/temp_serializer.c
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/temp_serializer.h
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_repos/config_pool.c
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_subr/io.c
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_subr/path.c
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_subr/sqlite.c
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_subr/sqlite3wrapper.c
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_subr/subst.c
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/cleanup.c
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/deprecated.c
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/externals.c
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/update_editor.c
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/wc-queries.sql
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/wc_db.c
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/wc_db.h
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/wc_db_update_move.c
    subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/wc_db_util.c
    subversion/branches/fsfs-ucsnorm/subversion/mod_dav_svn/dav_svn.h
    subversion/branches/fsfs-ucsnorm/subversion/mod_dav_svn/lock.c
    subversion/branches/fsfs-ucsnorm/subversion/mod_dav_svn/mod_dav_svn.c
    subversion/branches/fsfs-ucsnorm/subversion/svn/cat-cmd.c
    subversion/branches/fsfs-ucsnorm/subversion/svn/cleanup-cmd.c
    subversion/branches/fsfs-ucsnorm/subversion/svn/log-cmd.c
    subversion/branches/fsfs-ucsnorm/subversion/svn/mergeinfo-cmd.c
    subversion/branches/fsfs-ucsnorm/subversion/svn/svn.c
    subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/blame_tests.py
    subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/externals_tests.py
    subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/log_tests.py
    subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/merge_reintegrate_tests.py
    subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/merge_tests.py
    subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/mergeinfo_tests.py
    subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/prop_tests.py
    subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/resolve_tests.py
    subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/revert_tests.py
    subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/svnadmin_tests.py
    subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/svntest/main.py
    subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/svntest/verify.py
    subversion/branches/fsfs-ucsnorm/subversion/tests/cmdline/update_tests.py
    subversion/branches/fsfs-ucsnorm/subversion/tests/libsvn_fs_fs/fs-fs-pack-test.c
    subversion/branches/fsfs-ucsnorm/subversion/tests/libsvn_fs_x/   (props changed)
    subversion/branches/fsfs-ucsnorm/subversion/tests/libsvn_fs_x/fs-x-pack-test.c
    subversion/branches/fsfs-ucsnorm/subversion/tests/libsvn_repos/repos-test.c
    subversion/branches/fsfs-ucsnorm/subversion/tests/libsvn_subr/path-test.c
    subversion/branches/fsfs-ucsnorm/subversion/tests/libsvn_wc/op-depth-test.c
    subversion/branches/fsfs-ucsnorm/subversion/tests/svn_test_main.c
    subversion/branches/fsfs-ucsnorm/tools/dev/which-error.py

Propchange: subversion/branches/fsfs-ucsnorm/
------------------------------------------------------------------------------
  Merged /subversion/trunk:r1547259-1549770

Modified: subversion/branches/fsfs-ucsnorm/configure.ac
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/configure.ac?rev=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/configure.ac (original)
+++ subversion/branches/fsfs-ucsnorm/configure.ac Tue Dec 10 06:58:35 2013
@@ -937,16 +937,6 @@ AC_CHECK_HEADER(termios.h,[
 
 dnl Process some configuration options ----------
 
-AC_ARG_WITH(openssl,
-AS_HELP_STRING([--with-openssl],
-               [This option does NOT affect the Subversion build process in any
-                way. It tells an integrated Serf HTTP client library build
-                process where to locate the OpenSSL library when (and only when)
-                building Serf as an integrated part of the Subversion build
-                process. When linking to a previously installed version of Serf
-                instead, you do not need to use this option.]),
-[])
-
 AC_ARG_ENABLE(debug,
 AS_HELP_STRING([--enable-debug],
                [Turn on debugging]),

Modified: subversion/branches/fsfs-ucsnorm/contrib/server-side/svncutter/svncutter
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/contrib/server-side/svncutter/svncutter?rev=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/contrib/server-side/svncutter/svncutter (original)
+++ subversion/branches/fsfs-ucsnorm/contrib/server-side/svncutter/svncutter Tue Dec 10 06:58:35 2013
@@ -5,7 +5,7 @@
 # under the prevailing license of their project.
 
 """
-svncutter - clique-squash, range-selection, property mutations, and skeletonization on SVN dump files 
+svncutter - stream surgery on SVN dump files 
 general usage: svncutter [-q] [-r SELECTION] SUBCOMMAND
 
 In all commands, the -r (or --range) option limits the selection of revisions
@@ -29,9 +29,10 @@ Available subcommands:
    proprename
    log
    setlog
-   skeleton
+   strip
    expunge
    renumber
+   reduce
 """
 
 oneliners = {
@@ -42,9 +43,10 @@ oneliners = {
     "proprename": "Renaming revision properties",
     "log":        "Extracting log entries",
     "setlog":     "Mutating log entries",
-    "skeleton":   "Replace content with unique cookies, preserving structure",
+    "strip":      "Replace content with unique cookies, preserving structure",
     "expunge":    "Expunge operations by Node-path header",
     "renumber":   "Renumber revisions so they're contiguous",
+    "reduce":     "Topologically reduce a dump.",
     }
 
 helpdict = {
@@ -125,8 +127,8 @@ Replace the log entries in the input dum
 in the LOGFILE, which should be in the format of an svn log output.
 Replacements may be restricted to a specified range.
 """,
-    "skeleton": """\
-skeleton: usage: svncutter [-r SELECTION] skeleton PATTERN...
+    "strip": """\
+strip: usage: svncutter [-r SELECTION] strip PATTERN...
 
 Replace content with unique generated cookies on all node paths
 matching the specified regular expressions; if no expressions are
@@ -146,6 +148,22 @@ renumber: usage: svncutter renumber
 Renumber all revisions, patching Node-copyfrom headers as required.
 Any selection option is ignored. Takes no arguments.
 """,
+    "reduce": """\
+reduce: usage: svncutter reduce INPUT-FILE
+
+Strip revisions out of a dump so the only parts left those likely to
+be relevant to a conversion problem. A revision is interesting if it
+either (a) contains any operation that is not a plain file
+modification - any directory operation, or any add, or any delete, or
+any copy, or any operation on properties - or (b) it is referenced by
+a later copy operation. Any commit that is neither interesting nor
+has interesting neighbors is dropped.
+
+Because the 'interesting' status of a commit is not known for sure
+until all future commits have been checked for copy operations, this
+command requires an input file.  It cannot operate on standard input.
+The reduced dump is emitted to standard output.
+""",
     }
 
 import os, sys, calendar, time, getopt, re
@@ -302,17 +320,20 @@ class DumpfileSource(LineBufferedSource)
             if property_hook:
                 (props.propkeys, props.properties) = property_hook(props.propkeys, props.properties)
             properties = str(props)
-        content = ""
+        # use a list since extending the string gets slow
+        content_list = []
         if "Text-content-length" in header:
             while True:
                 line = self.readline()
                 #print "I see contents line", repr(line)
                 if not line:
                     break
-                if line.startswith("Node-path:") or line.startswith("Revision-number"):
+                if line.startswith(("Node-path:", "Revision-number")):
                     self.push(line)
                     break
-                content += line
+                content_list.append(line)
+        content = "".join(content_list)
+        del content_list
         #print "READ NODE ENDS"
         if property_hook:
             header = DumpfileSource.set_length("Prop-content", header,
@@ -340,9 +361,9 @@ class DumpfileSource(LineBufferedSource)
                     oldrev = line.split()[1]
                     line = line.replace(oldrev, `revmap[int(oldrev)]`) 
                 stash += line
-    def report(self, selection, nodehook, prophook=None):
+    def report(self, selection, nodehook, prophook=None, passthrough=True):
         "Report a filtered portion of content."
-        emit = 0 in selection
+        emit = passthrough and 0 in selection
         stash = self.read_until_next("Revision-number:")
         if emit:
             sys.stdout.write(stash)
@@ -363,12 +384,14 @@ class DumpfileSource(LineBufferedSource)
                 if not line:
                     return
                 elif line == '\n':
-                    sys.stdout.write(line)
+                    if passthrough:
+                        sys.stdout.write(line)
                     continue
                 elif line.startswith("Revision-number:"):
                     self.push(line)
                     if stash and nodecount == 0:
-                        sys.stdout.write(stash)
+                        if passthrough:
+                            sys.stdout.write(stash)
                     break
                 elif line.startswith("Node-path:"):
                     nodecount += 1
@@ -378,7 +401,8 @@ class DumpfileSource(LineBufferedSource)
                     if emit and stash:
                         emit = stash + emit
                         stash = ""
-                    sys.stdout.write(emit)
+                    if passthrough:
+                        sys.stdout.write(emit)
                     continue
                 else:
                     sys.stderr.write("svncutter: parse at %s doesn't look right (%s), aborting!\n" % (self.revision, repr(line)))
@@ -727,9 +751,9 @@ def setlog(source, logpatch, selection):
         return (propkeys, propdict)
     source.apply_property_hook(selection, loghook)
 
-def skeletonize(source, selection, patterns):
-    "Skeletonize a portion of the dump file defined by a revision selection."
-    def __skeletonize(header, properties, content):
+def strip(source, selection, patterns):
+    "Strip a portion of the dump file defined by a revision selection."
+    def __strip(header, properties, content):
         def get_header(hd, name):
             m = re.search(name + ": (.*)", hd)
             return m and m.group(1)
@@ -738,11 +762,13 @@ def skeletonize(source, selection, patte
 
         # first check against the pattern
         ok = True
-        for pattern in patterns:
-            if header.startswith("Node-path: ") and re.search(pattern, header[11:]):
-                #sys.stderr.write("skeletonize skipping: " + header[11:header.index("\n")] +"\n")
-                ok = False
-                break
+        if header.startswith("Node-path: "):
+            filepath = header[11:header.index("\n")]
+            for pattern in patterns:
+                if re.search(pattern, filepath):
+                    #sys.stderr.write("strip skipping: %s\n" % filepath)
+                    ok = False
+                    break
         if not ok:
             return header + properties + content
         del ok
@@ -764,15 +790,35 @@ def skeletonize(source, selection, patte
         header = re.sub("Text-copy-source-md5:.*\n", "", header)
         header = re.sub("Text-copy-source-sha1:.*\n", "", header)
         return header + properties + content
-    source.report(selection, __skeletonize)
+    source.report(selection, __strip)
+
+def doreduce(source):
+    "Topologically reduce a dump, removing spans of plain file modifications."
+    interesting = set([0])
+    def __reduce(header, properties, content):
+        def get_header(name):
+            m = re.search(name + ": (.*)", header)
+            return m and m.group(1)
+        if not (get_header("Node-kind") == "file" and get_header("Node-action") == "change") or properties:
+            interesting.add(source.revision)
+        copysource = get_header("Node-copyfrom-rev")
+        if copysource is not None:
+            interesting.add(int(copysource))
+        return None
+    source.report(SubversionRange("0:HEAD"), __reduce, passthrough=False)
+    selection = SubversionRange(",".join([str(x) for x in interesting or x+1 in interesting or x-1 in interesting]))
+    source.file.seek(0)
+    select(source, selection)
 
 def expunge(source, selection, patterns):
     "Strip out ops defined by a revision selection and a path regexp."
     def __expunge(header, properties, content):
-        for pattern in patterns:
-            if header.startswith("Node-path: ") and re.search(pattern, header[11:]):
-                #sys.stderr.write("expunge skipping: " + header[11:header.index("\n")] +"\n")
-                return ""
+        if header.startswith("Node-path: "):
+            filepath = header[11:header.index("\n")]
+            for pattern in patterns:
+                if re.search(pattern, filepath):
+                    #sys.stderr.write("expunge skipping: " + header[11:header.index("\n")] +"\n")
+                    return ""
         else:
             return header + properties + content
     source.report(selection, __expunge)
@@ -796,6 +842,9 @@ def renumber(source):
         else:
             sys.stdout.write(line)
 
+def patterns_compile(patterns):
+    return [re.compile(pattern) for pattern in patterns]
+
 if __name__ == '__main__':
     try:
         (options, arguments) = getopt.getopt(sys.argv[1:], "ce:fl:m:p:qr:s",
@@ -854,12 +903,14 @@ if __name__ == '__main__':
             if not logpatch:
                 sys.stderr.write("svncutter: setlog requires a log entries file.\n")
             setlog(DumpfileSource(sys.stdin, baton), logpatch, selection)
-        elif arguments[0] == "skeleton":
-            skeletonize(DumpfileSource(sys.stdin, baton), selection, arguments[1:])
+        elif arguments[0] == "strip":
+            strip(DumpfileSource(sys.stdin, baton), selection, patterns_compile(arguments[1:]))
         elif arguments[0] == "expunge":
-            expunge(DumpfileSource(sys.stdin, baton), selection, arguments[1:])
+            expunge(DumpfileSource(sys.stdin, baton), selection, patterns_compile(arguments[1:]))
         elif arguments[0] == "renumber":
             renumber(DumpfileSource(sys.stdin, baton))
+        elif arguments[0] == "reduce":
+            doreduce(DumpfileSource(open(arguments[1]), baton))
         elif arguments[0] == "help":
             if len(arguments) == 1:
                 sys.stdout.write(__doc__)

Modified: subversion/branches/fsfs-ucsnorm/subversion/bindings/swig/include/svn_containers.swg
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/bindings/swig/include/svn_containers.swg?rev=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/bindings/swig/include/svn_containers.swg (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/bindings/swig/include/svn_containers.swg Tue Dec 10 06:58:35 2013
@@ -954,3 +954,16 @@
   %append_output(svn_swig_rb_apr_array_to_array_auth_provider_object(*$1));
 }
 #endif
+
+/* -----------------------------------------------------------------------
+   Output of apr_array_header_t * <svn_diff_hunk_t *>
+*/
+#ifdef SWIGPYTHON
+%typemap(out) apr_array_header_t *hunks {
+  %append_output(svn_swig_py_pointerlist_to_list($1, $descriptor(svn_diff_hunk_t *),
+                                                 _global_py_pool));
+  if (PyErr_Occurred()) {
+    SWIG_fail;
+  }
+}
+#endif

Modified: subversion/branches/fsfs-ucsnorm/subversion/include/svn_client.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/include/svn_client.h?rev=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/include/svn_client.h (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/include/svn_client.h Tue Dec 10 06:58:35 2013
@@ -3990,8 +3990,15 @@ svn_client_mergeinfo_get_merged(apr_hash
  * If a depth other than #svn_depth_empty or #svn_depth_infinity is
  * requested then return a #SVN_ERR_UNSUPPORTED_FEATURE error.
  *
- * @a discover_changed_paths and @a revprops are the same as for
- * svn_client_log5().  Use @a scratch_pool for all temporary allocations.
+ * In addition to the behavior of @a discover_changed_paths described in
+ * svn_client_log5(), if set to TRUE it enables detection of sub-tree
+ * merges that are complete but can't be detected as complete without
+ * access to the changed paths.  Sub-tree merges detected as complete will
+ * be included if @a finding_merged is TRUE or filtered if @a finding_merged
+ * is FALSE.
+ *
+ * @a revprops is the same as for svn_client_log5().  Use @a scratch_pool for
+ * all temporary allocations.
  *
  * @a ctx is a context used for authentication.
  *
@@ -4088,11 +4095,11 @@ svn_client_mergeinfo_log_eligible(const 
  * @{
  */
 
-/** Recursively cleanup a working copy directory @a dir, finishing any
- * incomplete operations, removing lockfiles, etc.
+/** Recursively vacuum a working copy directory @a dir, removing unnecessary
+ * data.
  *
- * If @a include_externals is @c TRUE, recurse into externals and clean
- * them up as well.
+ * If @a include_externals is @c TRUE, recurse into externals and vacuum them
+ * as well.
  *
  * If @a remove_unversioned_items is @c TRUE, remove unversioned items
  * in @a dir after successfull working copy cleanup.
@@ -4100,10 +4107,36 @@ svn_client_mergeinfo_log_eligible(const 
  * in @a dir after successfull working copy cleanup.
  *
  * When asked to remove unversioned or ignored items, and the working copy
- * is already locked via a different client or WC context than @a ctx, return
- * #SVN_ERR_WC_LOCKED. This prevents accidental working copy corruption in
- * case users run the cleanup operation to remove unversioned items while
- * another client is performing some other operation on the working copy.
+ * is already locked, return #SVN_ERR_WC_LOCKED. This prevents accidental
+ * working copy corruption in case users run the cleanup operation to
+ * remove unversioned items while another client is performing some other
+ * operation on the working copy.
+ *
+ * If @a ctx->cancel_func is non-NULL, invoke it with @a
+ * ctx->cancel_baton at various points during the operation.  If it
+ * returns an error (typically #SVN_ERR_CANCELLED), return that error
+ * immediately.
+ *
+ * Use @a scratch_pool for any temporary allocations.
+ *
+ * @since New in 1.9.
+ */
+svn_error_t *
+svn_client_vacuum(const char *dir_abspath,
+                  svn_boolean_t remove_unversioned_items,
+                  svn_boolean_t remove_ignored_items,
+                  svn_boolean_t fix_recorded_timestamps,
+                  svn_boolean_t vacuum_pristines,
+                  svn_boolean_t include_externals,
+                  svn_client_ctx_t *ctx,
+                  apr_pool_t *scratch_pool);
+
+
+/** Recursively cleanup a working copy directory @a dir, finishing any
+ * incomplete operations, removing lockfiles, etc.
+ *
+ * If @a include_externals is @c TRUE, recurse into externals and clean
+ * them up as well.
  *
  * If @a ctx->cancel_func is non-NULL, invoke it with @a
  * ctx->cancel_baton at various points during the operation.  If it
@@ -4115,15 +4148,17 @@ svn_client_mergeinfo_log_eligible(const 
  * @since New in 1.9.
  */
 svn_error_t *
-svn_client_cleanup2(const char *dir,
+svn_client_cleanup2(const char *dir_abspath,
+                    svn_boolean_t break_locks,
+                    svn_boolean_t fix_recorded_timestamps,
+                    svn_boolean_t clear_dav_cache,
+                    svn_boolean_t vacuum_pristines,
                     svn_boolean_t include_externals,
-                    svn_boolean_t remove_unversioned_items,
-                    svn_boolean_t remove_ignored_items,
                     svn_client_ctx_t *ctx,
                     apr_pool_t *scratch_pool);
 
-/* Like svn_client_cleanup2(), but no support for removing unversioned items
- * and cleaning up externals.
+/* Like svn_client_cleanup2(), but no support for not breaking locks and
+ * cleaning up externals and using a potentially non absolute path.
  *
  * @deprecated Provided for limited backwards compatibility with the 1.8 API.
  */

Modified: subversion/branches/fsfs-ucsnorm/subversion/include/svn_diff.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/include/svn_diff.h?rev=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/include/svn_diff.h (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/include/svn_diff.h Tue Dec 10 06:58:35 2013
@@ -911,8 +911,8 @@ typedef struct svn_diff_hunk_t svn_diff_
 
 /**
  * Allocate @a *stringbuf in @a result_pool, and read into it one line
- * of the diff text of @a hunk. The first line returned is the hunk header.
- * Any subsequent lines are unidiff data (starting with '+', '-', or ' ').
+ * of the diff text of @a hunk. The hunk header is not returned only the
+ * unidiff data lines (starting with '+', '-', or ' ') are returned.  
  * If the @a hunk is being interpreted in reverse (i.e. the reverse
  * parameter of svn_diff_parse_next_patch() was @c TRUE), the diff
  * text will be returned in reversed form.
@@ -922,6 +922,13 @@ typedef struct svn_diff_hunk_t svn_diff_
  * hunk does not end with a newline character and @a eol is not NULL.
  * Temporary allocations will be performed in @a scratch_pool.
  *
+ * @note The hunk header information can be retrievied with the following
+ * functions: 
+ * @see svn_diff_hunk_get_original_start()
+ * @see svn_diff_hunk_get_original_length()
+ * @see svn_diff_hunk_get_modified_start()
+ * @see svn_diff_hunk_get_modified_length()
+ *
  * @since New in 1.7.
  */
 svn_error_t *

Modified: subversion/branches/fsfs-ucsnorm/subversion/include/svn_wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/include/svn_wc.h?rev=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/include/svn_wc.h (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/include/svn_wc.h Tue Dec 10 06:58:35 2013
@@ -7324,19 +7324,45 @@ svn_wc_get_pristine_copy_path(const char
 
 
 /**
- * Recurse from @a local_abspath, cleaning up unfinished log business.  Perform
- * any temporary allocations in @a scratch_pool.  Any working copy locks under
- * @a local_abspath will be taken over and then cleared by this function.
+ * Recurse from @a local_abspath, cleaning up unfinished tasks.  Perform
+ * any temporary allocations in @a scratch_pool.  If @a break_locks is TRUE
+ * Any working copy locks under @a local_abspath will be taken over and then
+ * cleared by this function.
+ * WARNING: If @a break_locks is TRUE there is no mechanism that will protect
+ * locks that are still being used.
+ *
+ * If @a fix_recorded_timestamps is TRUE the recorded timestamps of unmodified
+ * files will be updated, which will improve performance of future is-modified
+ * checks.
  *
- * WARNING: there is no mechanism that will protect locks that are still being
- * used.
+ * If @a vacuum_pristines is TRUE, try to remove unreferenced pristines from
+ * the working copy.
  *
  * If @a cancel_func is non-NULL, invoke it with @a cancel_baton at various
  * points during the operation.  If it returns an error (typically
  * #SVN_ERR_CANCELLED), return that error immediately.
  *
+ * @since New in 1.9.
+ */
+svn_error_t *
+svn_wc_cleanup4(svn_wc_context_t *wc_ctx,
+                const char *local_abspath,
+                svn_boolean_t break_locks,
+                svn_boolean_t fix_recorded_timestamps,
+                svn_boolean_t clear_dav_cache,
+                svn_boolean_t vacuum_pristines,
+                svn_cancel_func_t cancel_func,
+                void *cancel_baton,
+                apr_pool_t *scratch_pool);
+
+/**
+ * Similar to svn_wc_cleanup4() but will always break locks, fix recorded
+ * timestamps, clear the dav cache and vacuum pristines.
+ *
  * @since New in 1.7.
+ * @deprecated Provided for backward compatibility with the 1.8 API.
  */
+SVN_DEPRECATED
 svn_error_t *
 svn_wc_cleanup3(svn_wc_context_t *wc_ctx,
                 const char *local_abspath,

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_client/cleanup.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_client/cleanup.c?rev=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_client/cleanup.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_client/cleanup.c Tue Dec 10 06:58:35 2013
@@ -46,9 +46,13 @@
 
 struct cleanup_status_walk_baton
 {
-  svn_boolean_t include_externals;
+  svn_boolean_t break_locks;
+  svn_boolean_t fix_timestamps;
+  svn_boolean_t clear_dav_cache;
+  svn_boolean_t vacuum_pristines;
   svn_boolean_t remove_unversioned_items;
   svn_boolean_t remove_ignored_items;
+  svn_boolean_t include_externals;
   svn_client_ctx_t *ctx;
 };
 
@@ -61,64 +65,46 @@ cleanup_status_walk(void *baton,
 
 static svn_error_t *
 do_cleanup(const char *local_abspath,
-           svn_boolean_t include_externals,
+           svn_boolean_t break_locks,
+           svn_boolean_t fix_timestamps,
+           svn_boolean_t clear_dav_cache,
+           svn_boolean_t vacuum_pristines,
            svn_boolean_t remove_unversioned_items,
            svn_boolean_t remove_ignored_items,
+           svn_boolean_t include_externals,
            svn_client_ctx_t *ctx,
            apr_pool_t *scratch_pool)
 {
-  svn_error_t *err;
-
-  if (remove_unversioned_items || remove_ignored_items)
-    {
-      svn_boolean_t is_locked_here;
-      svn_boolean_t is_locked;
-      svn_boolean_t sqlite_exclusive;
-      svn_config_t *cfg = ctx->config
-                          ? svn_hash_gets(ctx->config,
-                                          SVN_CONFIG_CATEGORY_CONFIG)
-                          : NULL;
-
-      /* Check if someone else owns a lock for LOCAL_ABSPATH. */
-      SVN_ERR(svn_wc_locked2(&is_locked_here, &is_locked, ctx->wc_ctx,
-                             local_abspath, scratch_pool));
-      if (is_locked && !is_locked_here)
-        return svn_error_createf(SVN_ERR_WC_LOCKED, NULL,
-                                 _("Working copy at '%s' is already locked."),
-                                 svn_dirent_local_style(local_abspath,
-                                                        scratch_pool));
-
-      SVN_ERR(svn_config_get_bool(cfg, &sqlite_exclusive,
-                                  SVN_CONFIG_SECTION_WORKING_COPY,
-                                  SVN_CONFIG_OPTION_SQLITE_EXCLUSIVE,
-                                  FALSE));
-      if (sqlite_exclusive)
-        {
-          /* Close the db because svn_wc_cleanup3() will try to open it again,
-           * which doesn't work if exclusive sqlite locking mode is enabled. */
-          SVN_ERR(svn_wc__close_db(local_abspath, ctx->wc_ctx, scratch_pool));
-        }
-    }
+  SVN_ERR(svn_wc_cleanup4(ctx->wc_ctx,
+                          local_abspath,
+                          break_locks,
+                          fix_timestamps,
+                          clear_dav_cache,
+                          vacuum_pristines,
+                          ctx->cancel_func, ctx->cancel_baton,
+                          scratch_pool));
 
-  err = svn_wc_cleanup3(ctx->wc_ctx, local_abspath, ctx->cancel_func,
-                        ctx->cancel_baton, scratch_pool);
-  svn_io_sleep_for_timestamps(local_abspath, scratch_pool);
-  if (err)
-    return svn_error_trace(err);
+  if (fix_timestamps)
+    svn_io_sleep_for_timestamps(local_abspath, scratch_pool);
 
   if (remove_unversioned_items || remove_ignored_items || include_externals)
     {
       struct cleanup_status_walk_baton b;
       apr_array_header_t *ignores;
 
-      b.include_externals = include_externals;
+      b.break_locks = break_locks;
+      b.fix_timestamps = fix_timestamps;
+      b.clear_dav_cache = clear_dav_cache;
+      b.vacuum_pristines = vacuum_pristines;
       b.remove_unversioned_items = remove_unversioned_items;
       b.remove_ignored_items = remove_ignored_items;
       b.include_externals = include_externals;
       b.ctx = ctx;
 
       SVN_ERR(svn_wc_get_default_ignores(&ignores, ctx->config, scratch_pool));
-      SVN_ERR(svn_wc_walk_status(ctx->wc_ctx, local_abspath,
+
+      SVN_WC__CALL_WITH_WRITE_LOCK(
+              svn_wc_walk_status(ctx->wc_ctx, local_abspath,
                                  svn_depth_infinity,
                                  TRUE,  /* get all */
                                  remove_ignored_items,
@@ -127,7 +113,11 @@ do_cleanup(const char *local_abspath,
                                  cleanup_status_walk, &b,
                                  ctx->cancel_func,
                                  ctx->cancel_baton,
-                                 scratch_pool));
+                                 scratch_pool),
+              ctx->wc_ctx,
+              local_abspath,
+              FALSE /* lock_anchor */,
+              scratch_pool);
     }
 
   return SVN_NO_ERROR;
@@ -161,10 +151,15 @@ cleanup_status_walk(void *baton,
                                       scratch_pool);
             }
 
-          err = do_cleanup(local_abspath, b->include_externals,
-                            b->remove_unversioned_items,
-                            b->remove_ignored_items,
-                            b->ctx, scratch_pool);
+          err = do_cleanup(local_abspath,
+                           b->break_locks,
+                           b->fix_timestamps,
+                           b->clear_dav_cache,
+                           b->vacuum_pristines,
+                           b->remove_unversioned_items,
+                           b->remove_ignored_items,
+                           TRUE /* include_externals */,
+                           b->ctx, scratch_pool);
           if (err && err->apr_err == SVN_ERR_WC_NOT_WORKING_COPY)
             {
               svn_error_clear(err);
@@ -219,22 +214,50 @@ cleanup_status_walk(void *baton,
 }
 
 svn_error_t *
-svn_client_cleanup2(const char *path,
+svn_client_cleanup2(const char *dir_abspath,
+                    svn_boolean_t break_locks,
+                    svn_boolean_t fix_recorded_timestamps,
+                    svn_boolean_t clear_dav_cache,
+                    svn_boolean_t vacuum_pristines,
                     svn_boolean_t include_externals,
-                    svn_boolean_t remove_unversioned_items,
-                    svn_boolean_t remove_ignored_items,
                     svn_client_ctx_t *ctx,
                     apr_pool_t *scratch_pool)
 {
-  const char *local_abspath;
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(dir_abspath));
+
+  SVN_ERR(do_cleanup(dir_abspath,
+                     break_locks,
+                     fix_recorded_timestamps,
+                     clear_dav_cache,
+                     vacuum_pristines,
+                     FALSE /* remove_unversioned_items */,
+                     FALSE /* remove_ignored_items */,
+                     include_externals,
+                     ctx, scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client_vacuum(const char *dir_abspath,
+                  svn_boolean_t remove_unversioned_items,
+                  svn_boolean_t remove_ignored_items,
+                  svn_boolean_t fix_recorded_timestamps,
+                  svn_boolean_t vacuum_pristines,
+                  svn_boolean_t include_externals,
+                  svn_client_ctx_t *ctx,
+                  apr_pool_t *scratch_pool)
+{
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(dir_abspath));
 
-  if (svn_path_is_url(path))
-    return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
-                             _("'%s' is not a local path"), path);
-
-  SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool));
-  SVN_ERR(do_cleanup(local_abspath, include_externals,
-                     remove_unversioned_items, remove_ignored_items,
+  SVN_ERR(do_cleanup(dir_abspath,
+                     FALSE /* break_locks */,
+                     fix_recorded_timestamps,
+                     FALSE /* clear_dav_cache */,
+                     vacuum_pristines,
+                     remove_unversioned_items,
+                     remove_ignored_items,
+                     include_externals,
                      ctx, scratch_pool));
 
   return SVN_NO_ERROR;

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_client/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_client/deprecated.c?rev=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_client/deprecated.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_client/deprecated.c Tue Dec 10 06:58:35 2013
@@ -3006,6 +3006,19 @@ svn_client_cleanup(const char *path,
                    svn_client_ctx_t *ctx,
                    apr_pool_t *scratch_pool)
 {
-  return svn_error_trace(svn_client_cleanup2(path, FALSE, FALSE, FALSE, ctx,
-                                             scratch_pool));
+  const char *local_abspath;
+
+  if (svn_path_is_url(path))
+    return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
+                             _("'%s' is not a local path"), path);
+
+  SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool));
+
+  return svn_error_trace(svn_client_cleanup2(local_abspath,
+                                             TRUE /* break_locks */,
+                                             TRUE /* fix_recorded_timestamps */,
+                                             TRUE /* clear_dav_cache */,
+                                             TRUE /* vacuum_pristines */,
+                                             FALSE /* include_externals */,
+                                             ctx, scratch_pool));
 }

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_diff/parse-diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_diff/parse-diff.c?rev=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_diff/parse-diff.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_diff/parse-diff.c Tue Dec 10 06:58:35 2013
@@ -386,7 +386,6 @@ svn_diff_hunk_readline_diff_text(svn_dif
                                  apr_pool_t *result_pool,
                                  apr_pool_t *scratch_pool)
 {
-  svn_diff_hunk_t dummy;
   svn_stringbuf_t *line;
   apr_size_t max_len;
   apr_off_t pos;
@@ -416,33 +415,10 @@ svn_diff_hunk_readline_diff_text(svn_dif
 
   if (hunk->patch->reverse)
     {
-      if (parse_hunk_header(line->data, &dummy, "@@", scratch_pool))
-        {
-          /* Line is a hunk header, reverse it. */
-          line = svn_stringbuf_createf(result_pool,
-                                       "@@ -%lu,%lu +%lu,%lu @@",
-                                       hunk->modified_start,
-                                       hunk->modified_length,
-                                       hunk->original_start,
-                                       hunk->original_length);
-        }
-      else if (parse_hunk_header(line->data, &dummy, "##", scratch_pool))
-        {
-          /* Line is a hunk header, reverse it. */
-          line = svn_stringbuf_createf(result_pool,
-                                       "## -%lu,%lu +%lu,%lu ##",
-                                       hunk->modified_start,
-                                       hunk->modified_length,
-                                       hunk->original_start,
-                                       hunk->original_length);
-        }
-      else
-        {
-          if (line->data[0] == '+')
-            line->data[0] = '-';
-          else if (line->data[0] == '-')
-            line->data[0] = '+';
-        }
+      if (line->data[0] == '+')
+        line->data[0] = '-';
+      else if (line->data[0] == '-')
+        line->data[0] = '+';
     }
 
   *stringbuf = line;

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs/fs-loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs/fs-loader.c?rev=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs/fs-loader.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs/fs-loader.c Tue Dec 10 06:58:35 2013
@@ -1527,10 +1527,10 @@ svn_fs_lock(svn_lock_t **lock, svn_fs_t 
                                  token, "opaquelocktoken");
 
       for (c = token; *c; c++)
-        if (! svn_ctype_isascii(*c))
+        if (! svn_ctype_isascii(*c) || svn_ctype_iscntrl(*c))
           return svn_error_createf(SVN_ERR_FS_BAD_LOCK_TOKEN, NULL,
-                                   _("Lock token '%s' is not ASCII "
-                                     "at byte %u"),
+                                   _("Lock token '%s' is not ASCII or is a "
+                                     "control character at byte %u"),
                                    token, (unsigned)(c - token));
 
       /* strlen(token) == c - token. */

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/cached_data.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/cached_data.c?rev=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/cached_data.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/cached_data.c Tue Dec 10 06:58:35 2013
@@ -2177,8 +2177,14 @@ svn_fs_fs__get_changes(apr_array_header_
   /* try cache lookup first */
 
   if (ffd->changes_cache)
-    SVN_ERR(svn_cache__get((void **) changes, &found, ffd->changes_cache,
-                           &rev, pool));
+    {
+      SVN_ERR(svn_cache__get((void **) changes, &found, ffd->changes_cache,
+                             &rev, pool));
+    }
+  else
+    {
+      found = FALSE;
+    }
 
   if (!found)
     {

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/fs.h?rev=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/fs.h (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/fs.h Tue Dec 10 06:58:35 2013
@@ -285,6 +285,23 @@ typedef struct window_cache_key_t
   apr_uint64_t item_index;
 } window_cache_key_t;
 
+/* Structure used to propagate paths throught the FSFS implementation. */
+typedef struct fs_fs_path_t
+{
+  /* The original path, as found on disk or received by the API. */
+  const char *path;
+
+  /* The representation of PATH used for cache keys and
+     lookups. Depending on whether normalized lookups are enabled,
+     this will either be exactly the same pointer as PATH (i.e.,
+     normalization is disabled), or it will be a normalized
+     representation of PATH. The invariant is:
+
+         (path == keypath) ==> (normalized_lookup == false)
+  */
+  const char *keypath;
+}; fs_fs_path_t;
+
 /* Private (non-shared) FSFS-specific data for each svn_fs_t object.
    Any caches in here may be NULL. */
 typedef struct fs_fs_data_t

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/fs_fs.c?rev=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/fs_fs.c Tue Dec 10 06:58:35 2013
@@ -890,7 +890,7 @@ upgrade_body(void *baton, apr_pool_t *po
   if (format == SVN_FS_FS__FORMAT_NUMBER)
     return SVN_NO_ERROR;
 
-  /* If our filesystem predates the existance of the 'txn-current
+  /* If our filesystem predates the existence of the 'txn-current
      file', make that file and its corresponding lock file. */
   if (format < SVN_FS_FS__MIN_TXN_CURRENT_FORMAT)
     {
@@ -902,7 +902,7 @@ upgrade_body(void *baton, apr_pool_t *po
                            pool));
     }
 
-  /* If our filesystem predates the existance of the 'txn-protorevs'
+  /* If our filesystem predates the existence of the 'txn-protorevs'
      dir, make that directory.  */
   if (format < SVN_FS_FS__MIN_PROTOREVS_DIR_FORMAT)
     {
@@ -1291,7 +1291,12 @@ svn_fs_fs__create(svn_fs_t *fs,
 
   SVN_ERR(write_revision_zero(fs));
 
-  SVN_ERR(write_config(fs, pool));
+  /* Create the fsfs.conf file if supported.  Older server versions would
+     simply ignore the file but that might result in a different behavior
+     than with the later releases.  Also, hotcopy would ignore, i.e. not
+     copy, a fsfs.conf with old formats. */
+  if (ffd->format >= SVN_FS_FS__MIN_CONFIG_FILE)
+    SVN_ERR(write_config(fs, pool));
 
   SVN_ERR(read_config(ffd, fs->path, pool));
 

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/id.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/id.c?rev=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/id.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/id.c Tue Dec 10 06:58:35 2013
@@ -359,7 +359,7 @@ svn_fs_fs__id_txn_create_root(const svn_
   id->private_id.rev_item.revision = SVN_INVALID_REVNUM;
 
   id->generic_id.vtable = &id_vtable;
-  id->generic_id.fsap_data = &id;
+  id->generic_id.fsap_data = id;
 
   return (svn_fs_id_t *)id;
 }
@@ -374,7 +374,7 @@ svn_fs_id_t *svn_fs_fs__id_create_root(c
   id->private_id.rev_item.number = SVN_FS_FS__ITEM_INDEX_ROOT_NODE;
 
   id->generic_id.vtable = &id_vtable;
-  id->generic_id.fsap_data = &id;
+  id->generic_id.fsap_data = id;
 
   return (svn_fs_id_t *)id;
 }
@@ -393,7 +393,7 @@ svn_fs_fs__id_txn_create(const svn_fs_fs
   id->private_id.rev_item.revision = SVN_INVALID_REVNUM;
 
   id->generic_id.vtable = &id_vtable;
-  id->generic_id.fsap_data = &id;
+  id->generic_id.fsap_data = id;
 
   return (svn_fs_id_t *)id;
 }
@@ -413,7 +413,7 @@ svn_fs_fs__id_rev_create(const svn_fs_fs
   id->private_id.rev_item = *rev_item;
 
   id->generic_id.vtable = &id_vtable;
-  id->generic_id.fsap_data = &id;
+  id->generic_id.fsap_data = id;
 
   return (svn_fs_id_t *)id;
 }
@@ -447,7 +447,7 @@ svn_fs_fs__id_parse(const char *data,
   /* Alloc a new svn_fs_id_t structure. */
   id = apr_pcalloc(pool, sizeof(*id));
   id->generic_id.vtable = &id_vtable;
-  id->generic_id.fsap_data = &id;
+  id->generic_id.fsap_data = id;
 
   /* Now, we basically just need to "split" this data on `.'
      characters.  We will use svn_cstring_tokenize, which will put

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/recovery.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/recovery.c?rev=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/recovery.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/recovery.c Tue Dec 10 06:58:35 2013
@@ -56,7 +56,6 @@ recover_get_largest_revision(svn_fs_t *f
       svn_error_t *err;
       svn_fs_fs__revision_file_t *file;
       svn_pool_clear(iterpool);
-      svn_pool_clear(iterpool);
 
       err = svn_fs_fs__open_pack_or_rev_file(&file, fs, right, iterpool);
       if (err && err->apr_err == SVN_ERR_FS_NO_SUCH_REVISION)
@@ -80,7 +79,6 @@ recover_get_largest_revision(svn_fs_t *f
       svn_error_t *err;
       svn_fs_fs__revision_file_t *file;
       svn_pool_clear(iterpool);
-      svn_pool_clear(iterpool);
 
       err = svn_fs_fs__open_pack_or_rev_file(&file, fs, probe, iterpool);
       if (err && err->apr_err == SVN_ERR_FS_NO_SUCH_REVISION)
@@ -290,10 +288,10 @@ svn_fs_fs__find_max_ids(svn_fs_t *fs,
   SVN_ERR_ASSERT(ffd->format < SVN_FS_FS__MIN_NO_GLOBAL_IDS_FORMAT);
 
   SVN_ERR(svn_fs_fs__rev_get_root(&root_id, fs, youngest, pool));
+  SVN_ERR(svn_fs_fs__open_pack_or_rev_file(&rev_file, fs, youngest, pool));
   SVN_ERR(svn_fs_fs__item_offset(&root_offset, fs, rev_file, youngest, NULL,
                                  svn_fs_fs__id_item(root_id), pool));
 
-  SVN_ERR(svn_fs_fs__open_pack_or_rev_file(&rev_file, fs, youngest, pool));
   SVN_ERR(recover_find_max_ids(fs, youngest, rev_file, root_offset,
                                max_node_id, max_copy_id, pool));
   SVN_ERR(svn_fs_fs__close_revision_file(rev_file));

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/rep-cache.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/rep-cache.c?rev=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/rep-cache.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/rep-cache.c Tue Dec 10 06:58:35 2013
@@ -81,8 +81,33 @@ open_rep_cache(void *baton,
   int version;
 
   /* Open (or create) the sqlite database.  It will be automatically
-     closed when fs->pool is destoyed. */
+     closed when fs->pool is destoyed.  */
   db_path = path_rep_cache_db(fs->path, pool);
+#ifndef WIN32
+  {
+    /* We want to extend the permissions that apply to the repository
+       as a whole when creating a new rep cache and not simply default
+       to umask. */
+    svn_boolean_t exists;
+
+    SVN_ERR(svn_fs_fs__exists_rep_cache(&exists, fs, pool));
+    if (!exists)
+      {
+        const char *current = svn_fs_fs__path_current(fs, pool);
+        svn_error_t *err = svn_io_file_create_empty(db_path, pool);
+
+        if (err && !APR_STATUS_IS_EEXIST(err->apr_err))
+          /* A real error. */
+          return svn_error_trace(err);
+        else if (err)
+          /* Some other thread/process created the file. */
+          svn_error_clear(err);
+        else
+          /* We created the file. */
+          SVN_ERR(svn_io_copy_perms(current, db_path, pool));
+      }
+  }
+#endif
   SVN_ERR(svn_sqlite__open(&sdb, db_path,
                            svn_sqlite__mode_rwcreate, statements,
                            0, NULL,

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=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/tree.c Tue Dec 10 06:58:35 2013
@@ -66,6 +66,7 @@
 #include "private/svn_subr_private.h"
 #include "private/svn_fs_util.h"
 #include "private/svn_fspath.h"
+#include "private/svn_utf_private.h"
 #include "../libsvn_fs/fs-loader.h"
 
 
@@ -613,6 +614,28 @@ dag_node_cache_invalidate(svn_fs_root_t 
 }
 
 
+/* Create a key for path lookup. The path in the key struct will
+   always be canonical. */
+static svn_error_t *
+create_path_key(fs_fs_path_t *result,
+                const char *path,
+                svn_boolean_t normalize,
+                apr_pool_t *result_pool)
+{
+  result->path = svn_fs__canonicalize_abspath(path, result_pool);
+  if (normalize)
+    {
+      svn_membuf_t buffer;
+      svn_membuf__create(&buffer, 0, result_pool);
+      SVN_ERR(svn_utf__normalize(&result->keypath, result->path,
+                                 SVN_UTF__UNKNOWN_LENGTH, &buffer));
+    }
+  else
+    result->keypath = result->path;
+  return SVN_NO_ERROR;
+}
+
+
 
 /* Creating transaction and revision root nodes.  */
 
@@ -1477,12 +1500,14 @@ fs_change_node_prop(svn_fs_root_t *root,
 {
   parent_path_t *parent_path;
   apr_hash_t *proplist;
+  fs_fs_path_t path_key;
   const svn_fs_fs__id_part_t *txn_id;
 
   if (! root->is_txn_root)
     return SVN_FS__NOT_TXN(root);
   txn_id = root_txn_id(root);
 
+  SVN_ERR(create_path_key(&path_key, path, XXXXX
   path = svn_fs__canonicalize_abspath(path, pool);
   SVN_ERR(open_path(&parent_path, root, path, 0, TRUE, pool));
 

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/util.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/util.h?rev=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/util.h (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_fs/util.h Tue Dec 10 06:58:35 2013
@@ -389,4 +389,4 @@ svn_fs_fs__use_log_addressing(svn_fs_t *
 svn_boolean_t
 svn_fs_fs__supports_move(svn_fs_t *fs);
 
-#endif
\ No newline at end of file
+#endif

Propchange: subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/
------------------------------------------------------------------------------
  Merged /subversion/trunk/subversion/libsvn_fs_x:r1547044-1549770

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/cached_data.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/cached_data.c?rev=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/cached_data.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/cached_data.c Tue Dec 10 06:58:35 2013
@@ -2335,6 +2335,10 @@ svn_fs_x__get_changes(apr_array_header_t
       SVN_ERR(svn_cache__get((void **) changes, &found, ffd->changes_cache,
                              &rev, pool));
     }
+  else
+    {
+      found = FALSE;
+    }
 
   if (!found)
     {

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/dag.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/dag.c?rev=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/dag.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/dag.c Tue Dec 10 06:58:35 2013
@@ -1152,10 +1152,11 @@ svn_fs_x__dag_deserialize(void **out,
   node->fs = NULL;
 
   /* fixup all references to sub-structures */
-  svn_fs_x__id_deserialize(node, &node->id);
+  svn_fs_x__id_deserialize(node, &node->id, pool);
   svn_fs_x__id_deserialize(node,
-                            (svn_fs_id_t **)&node->fresh_root_predecessor_id);
-  svn_fs_x__noderev_deserialize(node, &node->node_revision);
+                           (svn_fs_id_t **)&node->fresh_root_predecessor_id,
+                           pool);
+  svn_fs_x__noderev_deserialize(node, &node->node_revision, pool);
   node->node_pool = pool;
 
   svn_temp_deserializer__resolve(node, (void**)&node->created_path);

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/id.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/id.c?rev=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/id.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/id.c Tue Dec 10 06:58:35 2013
@@ -41,6 +41,8 @@ typedef struct fs_x__id_t
   svn_fs_x__id_part_t copy_id;
   svn_fs_x__id_part_t txn_id;
   svn_fs_x__id_part_t rev_item;
+
+  apr_pool_t *pool; /* pool that was used to allocate this struct */
 } fs_x__id_t;
 
 
@@ -286,7 +288,7 @@ svn_fs_x__id_eq(const svn_fs_id_t *a,
     return TRUE;
 
   return memcmp(&id_a->node_id, &id_b->node_id,
-                sizeof(*id_a) - sizeof(id_a->generic_id)) == 0;
+                4 * sizeof(svn_fs_x__id_part_t)) == 0;
 }
 
 
@@ -355,7 +357,8 @@ svn_fs_x__id_txn_create_root(const svn_f
   id->rev_item.revision = SVN_INVALID_REVNUM;
 
   id->generic_id.vtable = &id_vtable;
-  id->generic_id.fsap_data = &id;
+  id->generic_id.fsap_data = id;
+  id->pool = pool;
 
   return (svn_fs_id_t *)id;
 }
@@ -370,7 +373,8 @@ svn_fs_id_t *svn_fs_x__id_create_root(co
   id->rev_item.number = SVN_FS_X__ITEM_INDEX_ROOT_NODE;
 
   id->generic_id.vtable = &id_vtable;
-  id->generic_id.fsap_data = &id;
+  id->generic_id.fsap_data = id;
+  id->pool = pool;
 
   return (svn_fs_id_t *)id;
 }
@@ -389,7 +393,8 @@ svn_fs_x__id_txn_create(const svn_fs_x__
   id->rev_item.revision = SVN_INVALID_REVNUM;
 
   id->generic_id.vtable = &id_vtable;
-  id->generic_id.fsap_data = &id;
+  id->generic_id.fsap_data = id;
+  id->pool = pool;
 
   return (svn_fs_id_t *)id;
 }
@@ -409,7 +414,8 @@ svn_fs_x__id_rev_create(const svn_fs_x__
   id->rev_item = *rev_item;
 
   id->generic_id.vtable = &id_vtable;
-  id->generic_id.fsap_data = &id;
+  id->generic_id.fsap_data = id;
+  id->pool = pool;
 
   return (svn_fs_id_t *)id;
 }
@@ -419,10 +425,10 @@ svn_fs_id_t *
 svn_fs_x__id_copy(const svn_fs_id_t *source, apr_pool_t *pool)
 {
   fs_x__id_t *id = (fs_x__id_t *)source;
-  fs_x__id_t *new_id = apr_palloc(pool, sizeof(*new_id));
+  fs_x__id_t *new_id = apr_pmemdup(pool, id, sizeof(*id));
 
-  *new_id = *id;
   new_id->generic_id.fsap_data = new_id;
+  new_id->pool = pool;
 
   return (svn_fs_id_t *)new_id;
 }
@@ -443,7 +449,8 @@ svn_fs_x__id_parse(const char *data,
   /* Alloc a new svn_fs_id_t structure. */
   id = apr_pcalloc(pool, sizeof(*id));
   id->generic_id.vtable = &id_vtable;
-  id->generic_id.fsap_data = &id;
+  id->generic_id.fsap_data = id;
+  id->pool = pool;
 
   /* Now, we basically just need to "split" this data on `.'
      characters.  We will use svn_cstring_tokenize, which will put
@@ -531,7 +538,9 @@ svn_fs_x__id_serialize(svn_temp_serializ
 /* Deserialize an ID inside the BUFFER.
  */
 void
-svn_fs_x__id_deserialize(void *buffer, svn_fs_id_t **in_out)
+svn_fs_x__id_deserialize(void *buffer,
+                         svn_fs_id_t **in_out,
+                         apr_pool_t *pool)
 {
     fs_x__id_t *id;
 
@@ -549,5 +558,6 @@ svn_fs_x__id_deserialize(void *buffer, s
   /* the stored vtable is bogus at best -> set the right one */
   id->generic_id.vtable = &id_vtable;
   id->generic_id.fsap_data = id;
+  id->pool = pool;
 }
 

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/id.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/id.h?rev=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/id.h (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/id.h Tue Dec 10 06:58:35 2013
@@ -161,11 +161,12 @@ svn_fs_x__id_serialize(struct svn_temp_s
                         const svn_fs_id_t * const *id);
 
 /**
- * Deserialize an @a id within the @a buffer.
+ * Deserialize an @a id within the @a buffer and associate it with @a pool.
  */
 void
 svn_fs_x__id_deserialize(void *buffer,
-                          svn_fs_id_t **id);
+                         svn_fs_id_t **id,
+                         apr_pool_t *pool);
 
 #ifdef __cplusplus
 }

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/temp_serializer.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/temp_serializer.c?rev=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/temp_serializer.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/temp_serializer.c Tue Dec 10 06:58:35 2013
@@ -324,7 +324,7 @@ deserialize_dir(void *buffer, hash_data_
 
       /* pointer fixup */
       svn_temp_deserializer__resolve(entry, (void **)&entry->name);
-      svn_fs_x__id_deserialize(entry, (svn_fs_id_t **)&entry->id);
+      svn_fs_x__id_deserialize(entry, (svn_fs_id_t **)&entry->id, pool);
 
       /* add the entry to the hash */
       svn_hash_sets(result, entry->name, entry);
@@ -364,7 +364,8 @@ svn_fs_x__noderev_serialize(svn_temp_ser
 
 void
 svn_fs_x__noderev_deserialize(void *buffer,
-                              node_revision_t **noderev_p)
+                              node_revision_t **noderev_p,
+                              apr_pool_t *pool)
 {
   node_revision_t *noderev;
 
@@ -378,8 +379,10 @@ svn_fs_x__noderev_deserialize(void *buff
     return;
 
   /* fixup of sub-structures */
-  svn_fs_x__id_deserialize(noderev, (svn_fs_id_t **)&noderev->id);
-  svn_fs_x__id_deserialize(noderev, (svn_fs_id_t **)&noderev->predecessor_id);
+  svn_fs_x__id_deserialize(noderev, (svn_fs_id_t **)&noderev->id, pool);
+  svn_fs_x__id_deserialize(noderev,
+                           (svn_fs_id_t **)&noderev->predecessor_id,
+                           pool);
   svn_temp_deserializer__resolve(noderev, (void **)&noderev->prop_rep);
   svn_temp_deserializer__resolve(noderev, (void **)&noderev->data_rep);
 
@@ -687,7 +690,7 @@ svn_fs_x__deserialize_id(void **out,
   svn_fs_id_t *id = (svn_fs_id_t *)data;
 
   /* fixup of all pointers etc. */
-  svn_fs_x__id_deserialize(id, &id);
+  svn_fs_x__id_deserialize(id, &id, pool);
 
   /* done */
   *out = id;
@@ -733,7 +736,7 @@ svn_fs_x__deserialize_node_revision(void
   node_revision_t *noderev = (node_revision_t *)buffer;
 
   /* fixup of all pointers etc. */
-  svn_fs_x__noderev_deserialize(noderev, &noderev);
+  svn_fs_x__noderev_deserialize(noderev, &noderev, pool);
 
   /* done */
   *item = noderev;
@@ -891,7 +894,8 @@ svn_fs_x__extract_dir_entry(void **out,
       memcpy(new_entry, source, size);
 
       svn_temp_deserializer__resolve(new_entry, (void **)&new_entry->name);
-      svn_fs_x__id_deserialize(new_entry, (svn_fs_id_t **)&new_entry->id);
+      svn_fs_x__id_deserialize(new_entry, (svn_fs_id_t **)&new_entry->id,
+                               pool);
       *(svn_fs_dirent_t **)out = new_entry;
     }
 
@@ -1085,7 +1089,9 @@ serialize_change(svn_temp_serializer__co
  * serialization CONTEXT.
  */
 static void
-deserialize_change(void *buffer, change_t **change_p)
+deserialize_change(void *buffer,
+                   change_t **change_p,
+                   apr_pool_t *pool)
 {
   change_t * change;
 
@@ -1097,7 +1103,9 @@ deserialize_change(void *buffer, change_
     return;
 
   /* fix-up of sub-structures */
-  svn_fs_x__id_deserialize(change, (svn_fs_id_t **)&change->info.node_rev_id);
+  svn_fs_x__id_deserialize(change,
+                           (svn_fs_id_t **)&change->info.node_rev_id,
+                           pool);
 
   svn_temp_deserializer__resolve(change, (void **)&change->path.data);
   svn_temp_deserializer__resolve(change, (void **)&change->info.copyfrom_path);
@@ -1177,7 +1185,8 @@ svn_fs_x__deserialize_changes(void **out
   for (i = 0; i < changes->count; ++i)
     {
       deserialize_change((void*)changes->changes,
-                         (change_t **)&changes->changes[i]);
+                         (change_t **)&changes->changes[i],
+                         pool);
       APR_ARRAY_PUSH(array, change_t *) = changes->changes[i];
     }
 

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/temp_serializer.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/temp_serializer.h?rev=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/temp_serializer.h (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/temp_serializer.h Tue Dec 10 06:58:35 2013
@@ -43,11 +43,13 @@ svn_fs_x__noderev_serialize(struct svn_t
                             node_revision_t * const *noderev_p);
 
 /**
- * Deserialize a @a noderev_p within the @a buffer.
+ * Deserialize a @a noderev_p within the @a buffer and associate it with
+ * @a pool.
  */
 void
 svn_fs_x__noderev_deserialize(void *buffer,
-                              node_revision_t **noderev_p);
+                              node_revision_t **noderev_p,
+                              apr_pool_t *pool);
 
 /**
  * Serialize APR array @a *a within the serialization @a context.

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_repos/config_pool.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_repos/config_pool.c?rev=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_repos/config_pool.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_repos/config_pool.c Tue Dec 10 06:58:35 2013
@@ -380,7 +380,7 @@ find_repos_config(svn_config_t **cfg,
     }
 
   /* store the (path,rev) -> checksum mapping as well */
-  if (*cfg)
+  if (*cfg && checksum)
     SVN_MUTEX__WITH_LOCK(svn_object_pool__mutex(config_pool->object_pool),
                          add_checksum(config_pool, url, repos_root_dirent,
                                       youngest_rev, checksum));

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=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_subr/io.c Tue Dec 10 06:58:35 2013
@@ -4566,7 +4566,6 @@ contents_three_identical_p(svn_boolean_t
                            apr_pool_t *scratch_pool)
 {
   svn_error_t *err;
-  apr_size_t bytes_read1, bytes_read2, bytes_read3;
   char *buf1 = apr_palloc(scratch_pool, SVN__STREAM_CHUNK_SIZE);
   char *buf2 = apr_palloc(scratch_pool, SVN__STREAM_CHUNK_SIZE);
   char *buf3 = apr_palloc(scratch_pool, SVN__STREAM_CHUNK_SIZE);
@@ -4576,7 +4575,6 @@ contents_three_identical_p(svn_boolean_t
   svn_boolean_t eof1 = FALSE;
   svn_boolean_t eof2 = FALSE;
   svn_boolean_t eof3 = FALSE;
-  svn_boolean_t read_1, read_2, read_3;
 
   SVN_ERR(svn_io_file_open(&file1_h, file1, APR_READ, APR_OS_DEFAULT,
                            scratch_pool));
@@ -4610,11 +4608,14 @@ contents_three_identical_p(svn_boolean_t
             || (*identical_p23 && !eof2 && !eof3)
             || (*identical_p13 && !eof1 && !eof3)))
     {
+      apr_size_t bytes_read1, bytes_read2, bytes_read3;
+      svn_boolean_t read_1, read_2, read_3;
+
       read_1 = read_2 = read_3 = FALSE;
 
       /* As long as a file is not at the end yet, and it is still
        * potentially identical to another file, we read the next chunk.*/
-      if (!eof1 && (identical_p12 || identical_p13))
+      if (!eof1 && (*identical_p12 || *identical_p13))
         {
           err = svn_io_file_read_full2(file1_h, buf1,
                                    SVN__STREAM_CHUNK_SIZE, &bytes_read1,
@@ -4624,7 +4625,7 @@ contents_three_identical_p(svn_boolean_t
           read_1 = TRUE;
         }
 
-      if (!eof2 && (identical_p12 || identical_p23))
+      if (!eof2 && (*identical_p12 || *identical_p23))
         {
           err = svn_io_file_read_full2(file2_h, buf2,
                                    SVN__STREAM_CHUNK_SIZE, &bytes_read2,
@@ -4634,7 +4635,7 @@ contents_three_identical_p(svn_boolean_t
           read_2 = TRUE;
         }
 
-      if (!eof3 && (identical_p13 || identical_p23))
+      if (!eof3 && (*identical_p13 || *identical_p23))
         {
           err = svn_io_file_read_full2(file3_h, buf3,
                                    SVN__STREAM_CHUNK_SIZE, &bytes_read3,

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_subr/path.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_subr/path.c?rev=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_subr/path.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_subr/path.c Tue Dec 10 06:58:35 2013
@@ -1252,7 +1252,7 @@ svn_path_splitext(const char **path_root
      anything after it?  We look for the "rightmost" period in the
      string. */
   last_dot = strrchr(path, '.');
-  if (last_dot && (last_dot + 1 != '\0'))
+  if (last_dot && (*(last_dot + 1) != '\0'))
     {
       /* If we have a period, we need to make sure it occurs in the
          final path component -- that there's no path separator

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=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_subr/sqlite.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_subr/sqlite.c Tue Dec 10 06:58:35 2013
@@ -808,6 +808,27 @@ internal_open(sqlite3 **db3, const char 
        somebody initialized SQLite before us it is needed anyway.  */
     flags |= SQLITE_OPEN_NOMUTEX;
 
+#if !defined(WIN32) && !defined(SVN_SQLITE_INLINE)
+    if (mode == svn_sqlite__mode_rwcreate)
+      {
+        svn_node_kind_t kind;
+
+        /* Create the file before SQLite to avoid any permissions
+           problems with an SQLite build that uses the default
+           SQLITE_DEFAULT_FILE_PERMISSIONS of 644 modified by umask.
+           We simply want umask permissions. */
+        SVN_ERR(svn_io_check_path(path, &kind, scratch_pool));
+        if (kind == svn_node_none)
+          {
+            /* Another thread may have created the file, that's OK. */
+            svn_error_t *err = svn_io_file_create_empty(path, scratch_pool);
+            if (err && !APR_STATUS_IS_EEXIST(err->apr_err))
+              return svn_error_trace(err);
+            svn_error_clear(err);
+          }
+      }
+#endif
+
     /* Open the database. Note that a handle is returned, even when an error
        occurs (except for out-of-memory); thus, we can safely use it to
        extract an error message and construct an svn_error_t. */
@@ -1348,6 +1369,8 @@ svn_sqlite__hotcopy(const char *src_path
 
   SVN_ERR(svn_sqlite__close(src_db));
 
+  SVN_ERR(svn_io_copy_perms(src_path, dst_path, scratch_pool));
+
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_subr/sqlite3wrapper.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_subr/sqlite3wrapper.c?rev=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_subr/sqlite3wrapper.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_subr/sqlite3wrapper.c Tue Dec 10 06:58:35 2013
@@ -50,6 +50,7 @@
 #      undef inline
 #    endif
 #  endif
+#  define SQLITE_DEFAULT_FILE_PERMISSIONS 0666
 #  include <sqlite3.c>
 #  if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ >= 6))
 #    pragma GCC diagnostic pop

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_subr/subst.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_subr/subst.c?rev=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_subr/subst.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_subr/subst.c Tue Dec 10 06:58:35 2013
@@ -1716,9 +1716,19 @@ create_special_file_from_stream(svn_stre
      ### this only writes the first line!
   */
   if (create_using_internal_representation)
-    SVN_ERR(svn_io_write_unique(&dst_tmp, svn_dirent_dirname(dst, pool),
-                                contents->data, contents->len,
-                                svn_io_file_del_none, pool));
+    {
+      apr_file_t *new_file;
+      SVN_ERR(svn_io_open_unique_file3(&new_file, &dst_tmp,
+                                       svn_dirent_dirname(dst, pool),
+                                       svn_io_file_del_none,
+                                       pool, pool));
+
+      SVN_ERR(svn_io_file_write_full(new_file,
+                                     contents->data, contents->len, NULL,
+                                     pool));
+
+      SVN_ERR(svn_io_file_close(new_file, pool));
+    }
 
   /* Do the atomic rename from our temporary location. */
   return svn_error_trace(svn_io_file_rename(dst_tmp, dst, pool));

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/cleanup.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/cleanup.c?rev=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/cleanup.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/cleanup.c Tue Dec 10 06:58:35 2013
@@ -137,6 +137,9 @@ repair_timestamps(svn_wc__db_t *db,
 static svn_error_t *
 cleanup_internal(svn_wc__db_t *db,
                  const char *dir_abspath,
+                 svn_boolean_t break_locks,
+                 svn_boolean_t fix_recorded_timestamps,
+                 svn_boolean_t vacuum_pristines,
                  svn_cancel_func_t cancel_func,
                  void *cancel_baton,
                  apr_pool_t *scratch_pool)
@@ -154,7 +157,7 @@ cleanup_internal(svn_wc__db_t *db,
                                       scratch_pool, scratch_pool));
   if (lock_abspath)
     dir_abspath = lock_abspath;
-  SVN_ERR(svn_wc__db_wclock_obtain(db, dir_abspath, -1, TRUE, scratch_pool));
+  SVN_ERR(svn_wc__db_wclock_obtain(db, dir_abspath, -1, break_locks, scratch_pool));
 
   /* Run our changes before the subdirectories. We may not have to recurse
      if we blow away a subdir.  */
@@ -173,7 +176,7 @@ cleanup_internal(svn_wc__db_t *db,
      svn_wc__check_wcroot() as that function, will just return true
      once we start sharing databases with externals.
    */
-  if (is_wcroot)
+  if (is_wcroot && vacuum_pristines)
     {
     /* Cleanup the tmp area of the admin subdir, if running the log has not
        removed it!  The logs have been run, so anything left here has no hope
@@ -184,8 +187,9 @@ cleanup_internal(svn_wc__db_t *db,
       SVN_ERR(svn_wc__db_pristine_cleanup(db, dir_abspath, scratch_pool));
     }
 
-  SVN_ERR(repair_timestamps(db, dir_abspath, cancel_func, cancel_baton,
-                            scratch_pool));
+  if (fix_recorded_timestamps)
+    SVN_ERR(repair_timestamps(db, dir_abspath, cancel_func, cancel_baton,
+                              scratch_pool));
 
   /* All done, toss the lock */
   SVN_ERR(svn_wc__db_wclock_release(db, dir_abspath, scratch_pool));
@@ -193,13 +197,13 @@ cleanup_internal(svn_wc__db_t *db,
   return SVN_NO_ERROR;
 }
 
-
-/* ### possibly eliminate the WC_CTX parameter? callers really shouldn't
-   ### be doing anything *but* running a cleanup, and we need a special
-   ### DB anyway. ... *shrug* ... consider later.  */
 svn_error_t *
-svn_wc_cleanup3(svn_wc_context_t *wc_ctx,
+svn_wc_cleanup4(svn_wc_context_t *wc_ctx,
                 const char *local_abspath,
+                svn_boolean_t break_locks,
+                svn_boolean_t fix_recorded_timestamps,
+                svn_boolean_t clear_dav_cache,
+                svn_boolean_t vacuum_pristines,
                 svn_cancel_func_t cancel_func,
                 void *cancel_baton,
                 apr_pool_t *scratch_pool)
@@ -207,25 +211,43 @@ svn_wc_cleanup3(svn_wc_context_t *wc_ctx
   svn_wc__db_t *db;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+  SVN_ERR_ASSERT(wc_ctx != NULL);
+
+  if (break_locks)
+    {
+      /* We'll handle everything manually.  */
 
-  /* We need a DB that allows a non-empty work queue (though it *will*
-     auto-upgrade). We'll handle everything manually.  */
-  SVN_ERR(svn_wc__db_open(&db,
-                          NULL /* ### config */, FALSE, FALSE,
-                          scratch_pool, scratch_pool));
+      /* Close the existing database (if any) to avoid problems with
+         exclusive database usage */
+      SVN_ERR(svn_wc__db_drop_root(wc_ctx->db, local_abspath,
+                                   scratch_pool));
+
+      SVN_ERR(svn_wc__db_open(&db,
+                              NULL /* ### config */, FALSE, FALSE,
+                              scratch_pool, scratch_pool));
+    }
+  else
+    db = wc_ctx->db;
 
-  SVN_ERR(cleanup_internal(db, local_abspath, cancel_func, cancel_baton,
+  SVN_ERR(cleanup_internal(db, local_abspath,
+                           break_locks,
+                           fix_recorded_timestamps,
+                           vacuum_pristines,
+                           cancel_func, cancel_baton,
                            scratch_pool));
 
   /* The DAV cache suffers from flakiness from time to time, and the
      pre-1.7 prescribed workarounds aren't as user-friendly in WC-NG. */
-  SVN_ERR(svn_wc__db_base_clear_dav_cache_recursive(db, local_abspath,
-                                                    scratch_pool));
+  if (clear_dav_cache)
+    SVN_ERR(svn_wc__db_base_clear_dav_cache_recursive(db, local_abspath,
+                                                      scratch_pool));
 
-  SVN_ERR(svn_wc__db_vacuum(db, local_abspath, scratch_pool));
+  if (vacuum_pristines)
+    SVN_ERR(svn_wc__db_vacuum(db, local_abspath, scratch_pool));
 
   /* We're done with this DB, so proactively close it.  */
-  SVN_ERR(svn_wc__db_close(db));
+  if (break_locks)
+    SVN_ERR(svn_wc__db_close(db));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/deprecated.c?rev=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/deprecated.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/deprecated.c Tue Dec 10 06:58:35 2013
@@ -4185,7 +4185,25 @@ svn_wc_relocate(const char *path,
 }
 
 
-/*** From log.c ***/
+/*** From log.c / cleanup.c ***/
+
+svn_error_t *
+svn_wc_cleanup3(svn_wc_context_t *wc_ctx,
+                const char *local_abspath,
+                svn_cancel_func_t cancel_func,
+                void *cancel_baton,
+                apr_pool_t *scratch_pool)
+{
+  return svn_error_trace(
+            svn_wc_cleanup4(wc_ctx,
+                            local_abspath,
+                            TRUE /* break_locks */,
+                            TRUE /* fix_recorded_timestamps */,
+                            TRUE /* clear_dav_cache */,
+                            TRUE /* clean_pristines */,
+                            cancel_func, cancel_baton,
+                            scratch_pool));
+}
 
 svn_error_t *
 svn_wc_cleanup2(const char *path,

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/externals.c?rev=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/externals.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/externals.c Tue Dec 10 06:58:35 2013
@@ -963,6 +963,7 @@ close_edit(void *edit_baton,
                                                        *eb->target_revision,
                                                        apr_hash_make(pool),
                                                        wcroot_iprops,
+                                                       TRUE /* empty update */,
                                                        eb->notify_func,
                                                        eb->notify_baton,
                                                        pool));

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/update_editor.c?rev=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/update_editor.c Tue Dec 10 06:58:35 2013
@@ -258,6 +258,9 @@ struct edit_baton
   /* Absolute path of the working copy root or NULL if not initialized yet */
   const char *wcroot_abspath;
 
+  /* After closing the root directory a copy of its edited value */
+  svn_boolean_t edited;
+
   apr_pool_t *pool;
 };
 
@@ -2960,6 +2963,9 @@ close_directory(void *dir_baton,
       eb->notify_func(eb->notify_baton, notify, scratch_pool);
     }
 
+  if (db->edited)
+    eb->edited = db->edited;
+
   /* We're done with this directory, so remove one reference from the
      bump information. */
   SVN_ERR(maybe_release_dir_info(db));
@@ -4733,6 +4739,7 @@ close_edit(void *edit_baton,
                                                        *(eb->target_revision),
                                                        eb->skipped_trees,
                                                        eb->wcroot_iprops,
+                                                       ! eb->edited,
                                                        eb->notify_func,
                                                        eb->notify_baton,
                                                        eb->pool));

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/wc-queries.sql?rev=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/wc-queries.sql Tue Dec 10 06:58:35 2013
@@ -250,7 +250,7 @@ WHERE wc_id = ?1 
   AND op_depth > ?3
 
 -- STMT_SELECT_LOCAL_RELPATH_OP_DEPTH
-SELECT local_relpath
+SELECT local_relpath, kind
 FROM nodes
 WHERE wc_id = ?1
   AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))

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=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/wc_db.c Tue Dec 10 06:58:35 2013
@@ -11625,6 +11625,7 @@ bump_revisions_post_update(svn_wc__db_wc
                            svn_revnum_t new_revision,
                            apr_hash_t *exclude_relpaths,
                            apr_hash_t *wcroot_iprops,
+                           svn_boolean_t empty_update,
                            svn_wc_notify_func2_t notify_func,
                            void *notify_baton,
                            apr_pool_t *scratch_pool)
@@ -11676,6 +11677,7 @@ bump_revisions_post_update(svn_wc__db_wc
                              TRUE /* is_root */, FALSE, db,
                              scratch_pool));
 
+  /* ### TODO: Use empty_update flag for change knowledge */
   SVN_ERR(svn_wc__db_bump_moved_away(wcroot, local_relpath, depth, db,
                                      scratch_pool));
 
@@ -11696,6 +11698,7 @@ svn_wc__db_op_bump_revisions_post_update
                                          svn_revnum_t new_revision,
                                          apr_hash_t *exclude_relpaths,
                                          apr_hash_t *wcroot_iprops,
+                                         svn_boolean_t empty_update,
                                          svn_wc_notify_func2_t notify_func,
                                          void *notify_baton,
                                          apr_pool_t *scratch_pool)
@@ -11718,7 +11721,7 @@ svn_wc__db_op_bump_revisions_post_update
     bump_revisions_post_update(wcroot, local_relpath, db,
                                depth, new_repos_relpath, new_repos_root_url,
                                new_repos_uuid, new_revision,
-                               exclude_relpaths, wcroot_iprops,
+                               exclude_relpaths, wcroot_iprops, empty_update,
                                notify_func, notify_baton, scratch_pool),
     wcroot);
 

Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/wc_db.h?rev=1549771&r1=1549770&r2=1549771&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_wc/wc_db.h Tue Dec 10 06:58:35 2013
@@ -2539,6 +2539,9 @@ svn_wc__db_global_update(svn_wc__db_t *d
    for pathnames contained in EXCLUDE_RELPATHS are not touched by this
    function.  These pathnames should be paths relative to the wcroot.
 
+   If EMPTY_UPDATE is TRUE then no nodes at or below LOCAL_ABSPATH have been
+   affected by the update/switch yet.
+
    If WCROOT_IPROPS is not NULL it is a hash mapping const char * absolute
    working copy paths to depth-first ordered arrays of
    svn_prop_inherited_item_t * structures.  If LOCAL_ABSPATH exists in
@@ -2555,6 +2558,7 @@ svn_wc__db_op_bump_revisions_post_update
                                          svn_revnum_t new_revision,
                                          apr_hash_t *exclude_relpaths,
                                          apr_hash_t *wcroot_iprops,
+                                         svn_boolean_t empty_update,
                                          svn_wc_notify_func2_t notify_func,
                                          void *notify_baton,
                                          apr_pool_t *scratch_pool);

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=1549771&r1=1549770&r2=1549771&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 Tue Dec 10 06:58:35 2013
@@ -1627,6 +1627,7 @@ replace_moved_layer(const char *src_relp
       svn_error_t *err;
       svn_sqlite__stmt_t *stmt2;
       const char *src_cp_relpath = svn_sqlite__column_text(stmt, 0, NULL);
+      svn_node_kind_t kind = svn_sqlite__column_token(stmt, 1, kind_map);
       const char *dst_cp_relpath
         = svn_relpath_join(dst_relpath,
                            svn_relpath_skip_ancestor(src_relpath,
@@ -1643,6 +1644,11 @@ replace_moved_layer(const char *src_relp
                                                     scratch_pool));
       if (!err)
         err = svn_sqlite__step_done(stmt2);
+
+      if (!err && strlen(dst_cp_relpath) > strlen(dst_relpath))
+        err = svn_wc__db_extend_parent_delete(wcroot, dst_cp_relpath, kind,
+                                              dst_op_depth, scratch_pool);
+
       if (err)
         return svn_error_compose_create(err, svn_sqlite__reset(stmt));
 

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=1549771&r1=1549770&r2=1549771&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 Tue Dec 10 06:58:35 2013
@@ -136,22 +136,6 @@ svn_wc__db_util_open_db(svn_sqlite__db_t
                                  svn_dirent_local_style(sdb_abspath,
                                                         scratch_pool));
     }
-#ifndef WIN32
-  else
-    {
-      apr_file_t *f;
-
-      /* A standard SQLite build creates a DB with mode 644 ^ !umask
-         which means the file doesn't have group/world write access
-         even when umask allows it. By ensuring the file exists before
-         SQLite gets involved we give it the permissions allowed by
-         umask. */
-      SVN_ERR(svn_io_file_open(&f, sdb_abspath,
-                               (APR_READ | APR_WRITE | APR_CREATE),
-                               APR_OS_DEFAULT, scratch_pool));
-      SVN_ERR(svn_io_file_close(f, scratch_pool));
-    }
-#endif
 
   SVN_ERR(svn_sqlite__open(sdb, sdb_abspath, smode,
                            my_statements ? my_statements : statements,