subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From julianf...@apache.org
Subject svn commit: r1614348 - in /subversion/branches/move-tracking-2: ./ subversion/include/ subversion/include/private/ subversion/libsvn_delta/ subversion/libsvn_fs/ subversion/libsvn_fs_base/ subversion/libsvn_fs_fs/ subversion/libsvn_fs_x/ subversion/lib...
Date Tue, 29 Jul 2014 13:46:04 GMT
Author: julianfoad
Date: Tue Jul 29 13:46:03 2014
New Revision: 1614348

URL: http://svn.apache.org/r1614348
Log:
On the 'move-tracking-2' branch: catch up with trunk@1614347.

Modified:
    subversion/branches/move-tracking-2/   (props changed)
    subversion/branches/move-tracking-2/LICENSE
    subversion/branches/move-tracking-2/NOTICE
    subversion/branches/move-tracking-2/subversion/include/private/svn_io_private.h
    subversion/branches/move-tracking-2/subversion/include/private/svn_named_atomic.h
    subversion/branches/move-tracking-2/subversion/include/svn_fs.h
    subversion/branches/move-tracking-2/subversion/include/svn_repos.h
    subversion/branches/move-tracking-2/subversion/include/svn_string.h
    subversion/branches/move-tracking-2/subversion/libsvn_delta/debug_editor.c
    subversion/branches/move-tracking-2/subversion/libsvn_delta/debug_editor.h
    subversion/branches/move-tracking-2/subversion/libsvn_fs/fs-loader.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs/fs-loader.h
    subversion/branches/move-tracking-2/subversion/libsvn_fs_base/fs.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/hotcopy.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/hotcopy.h
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/   (props changed)
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/transaction.c
    subversion/branches/move-tracking-2/subversion/libsvn_repos/authz_pool.c
    subversion/branches/move-tracking-2/subversion/libsvn_repos/repos.c
    subversion/branches/move-tracking-2/subversion/libsvn_subr/io.c
    subversion/branches/move-tracking-2/subversion/libsvn_subr/named_atomic.c
    subversion/branches/move-tracking-2/subversion/libsvn_subr/string.c
    subversion/branches/move-tracking-2/subversion/svnadmin/svnadmin.c
    subversion/branches/move-tracking-2/subversion/tests/cmdline/svnadmin_tests.py
    subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/string-test.c

Propchange: subversion/branches/move-tracking-2/
------------------------------------------------------------------------------
  Merged /subversion/trunk:r1612334-1614347

Modified: subversion/branches/move-tracking-2/LICENSE
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/LICENSE?rev=1614348&r1=1614347&r2=1614348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/LICENSE (original)
+++ subversion/branches/move-tracking-2/LICENSE Tue Jul 29 13:46:03 2014
@@ -268,3 +268,67 @@ For the file subversion/libsvn_subr/utf_
  * Permission to use, copy, modify, and distribute this software
  * for any purpose and without fee is hereby granted. The author
  * disclaims all warranties with regard to this software.
+
+For the (modified) utf8proc library in subversion/libsvn_subr/utf8proc
+
+  Copyright (c) 2009 Public Software Group e. V., Berlin, Germany
+
+  Permission is hereby granted, free of charge, to any person obtaining a
+  copy of this software and associated documentation files (the "Software"),
+  to deal in the Software without restriction, including without limitation
+  the rights to use, copy, modify, merge, publish, distribute, sublicense,
+  and/or sell copies of the Software, and to permit persons to whom the
+  Software is furnished to do so, subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be included in
+  all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+  DEALINGS IN THE SOFTWARE.
+
+
+  This software distribution contains derived data from a modified version of
+  the Unicode data files. The following license applies to that data:
+
+  COPYRIGHT AND PERMISSION NOTICE
+
+  Copyright (c) 1991-2007 Unicode, Inc. All rights reserved. Distributed
+  under the Terms of Use in http://www.unicode.org/copyright.html.
+
+  Permission is hereby granted, free of charge, to any person obtaining a
+  copy of the Unicode data files and any associated documentation (the "Data
+  Files") or Unicode software and any associated documentation (the
+  "Software") to deal in the Data Files or Software without restriction,
+  including without limitation the rights to use, copy, modify, merge,
+  publish, distribute, and/or sell copies of the Data Files or Software, and
+  to permit persons to whom the Data Files or Software are furnished to do
+  so, provided that (a) the above copyright notice(s) and this permission
+  notice appear with all copies of the Data Files or Software, (b) both the
+  above copyright notice(s) and this permission notice appear in associated
+  documentation, and (c) there is clear notice in each modified Data File or
+  in the Software as well as in the documentation associated with the Data
+  File(s) or Software that the data or software has been modified.
+
+  THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+  KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
+  THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
+  INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR
+  CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+  TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+  PERFORMANCE OF THE DATA FILES OR SOFTWARE.
+
+  Except as contained in this notice, the name of a copyright holder shall
+  not be used in advertising or otherwise to promote the sale, use or other
+  dealings in these Data Files or Software without prior written
+  authorization of the copyright holder.
+
+  Unicode and the Unicode logo are trademarks of Unicode, Inc., and may be
+  registered in some jurisdictions. All other trademarks and registered
+  trademarks mentioned herein are the property of their respective owners.

Modified: subversion/branches/move-tracking-2/NOTICE
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/NOTICE?rev=1614348&r1=1614347&r2=1614348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/NOTICE (original)
+++ subversion/branches/move-tracking-2/NOTICE Tue Jul 29 13:46:03 2014
@@ -21,3 +21,5 @@ Inc. MD5 Message-Digest Algorithm, inclu
 modifications by Spyglass Inc., Carnegie Mellon University, and
 Bell Communications Research, Inc (Bellcore).
 
+This product includes software developed by Public Software Group e. V.
+under a permissive license, see LICENSE.
\ No newline at end of file

Modified: subversion/branches/move-tracking-2/subversion/include/private/svn_io_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/private/svn_io_private.h?rev=1614348&r1=1614347&r2=1614348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/private/svn_io_private.h (original)
+++ subversion/branches/move-tracking-2/subversion/include/private/svn_io_private.h Tue Jul 29 13:46:03 2014
@@ -73,6 +73,18 @@ svn_io__is_finfo_read_only(svn_boolean_t
                            apr_pool_t *pool);
 
 
+/**
+ * Lock file at @a lock_file. If that file does not exist, create an empty
+ * file.
+ *
+ * Lock will be automatically released when @a pool is cleared or destroyed.
+ * Use @a pool for memory allocations.
+ */
+svn_error_t *
+svn_io__file_lock_autocreate(const char *lock_file,
+                             apr_pool_t *pool);
+
+
 /** Buffer test handler function for a generic stream. @see svn_stream_t
  * and svn_stream__is_buffered().
  *

Modified: subversion/branches/move-tracking-2/subversion/include/private/svn_named_atomic.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/private/svn_named_atomic.h?rev=1614348&r1=1614347&r2=1614348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/private/svn_named_atomic.h (original)
+++ subversion/branches/move-tracking-2/subversion/include/private/svn_named_atomic.h Tue Jul 29 13:46:03 2014
@@ -77,6 +77,9 @@ svn_named_atomic__is_efficient(void);
  *
  * The access object will be allocated in @a result_pool and atomics gotten
  * from this object will become invalid when the pool is being cleared.
+ *
+ * @note Although we use shared memory here, the management around it will
+ * take up a few kB of memory per call (until @a result_pool gets cleared).
  */
 svn_error_t *
 svn_atomic_namespace__create(svn_atomic_namespace__t **ns,

Modified: subversion/branches/move-tracking-2/subversion/include/svn_fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/svn_fs.h?rev=1614348&r1=1614347&r2=1614348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/svn_fs.h (original)
+++ subversion/branches/move-tracking-2/subversion/include/svn_fs.h Tue Jul 29 13:46:03 2014
@@ -452,6 +452,16 @@ svn_error_t *
 svn_fs_delete_fs(const char *path,
                  apr_pool_t *pool);
 
+/** The type of a hotcopy notification function.  @a start_revision and
+ * @a end_revision indicate the copied revision range.  @a baton is the
+ * corresponding baton for the notification function, and @a pool can be
+ * used for temporary allocations, but will be cleared between invocations.
+ */
+typedef void (*svn_fs_hotcopy_notify_t)(void *baton,
+                                        svn_revnum_t start_revision,
+                                        svn_revnum_t end_revision,
+                                        apr_pool_t *pool);
+
 /**
  * Copy a possibly live Subversion filesystem from @a src_path to
  * @a dest_path.  If @a clean is @c TRUE, perform cleanup on the
@@ -464,10 +474,35 @@ svn_fs_delete_fs(const char *path,
  * incremental hotcopy is not implemented, raise
  * #SVN_ERR_UNSUPPORTED_FEATURE.
  *
+ * For each revision range copied, @a notify_func will be called with
+ * staring and ending revision numbers (both inclusive and not necessarily
+ * different) and with the @a notify_baton.  Currently, this notification
+ * is only supported in the FSFS backend.  @a notify_func may be @c NULL
+ * if this notification is not required.
+ *
  * Use @a scratch_pool for temporary allocations.
  *
+ * @since New in 1.9.
+ */
+svn_error_t *
+svn_fs_hotcopy3(const char *src_path,
+                const char *dest_path,
+                svn_boolean_t clean,
+                svn_boolean_t incremental,
+                svn_fs_hotcopy_notify_t notify_func,
+                void *notify_baton,
+                svn_cancel_func_t cancel_func,
+                void *cancel_baton,
+                apr_pool_t *scratch_pool);
+
+/**
+ * Like svn_fs_hotcopy3(), but with @a notify_func and @a notify_baton
+ * always passed as @c NULL.
+ *
+ * @deprecated Provided for backward compatibility with the 1.8 API.
  * @since New in 1.8.
  */
+SVN_DEPRECATED
 svn_error_t *
 svn_fs_hotcopy2(const char *src_path,
                 const char *dest_path,

Modified: subversion/branches/move-tracking-2/subversion/include/svn_repos.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/svn_repos.h?rev=1614348&r1=1614347&r2=1614348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/svn_repos.h (original)
+++ subversion/branches/move-tracking-2/subversion/include/svn_repos.h Tue Jul 29 13:46:03 2014
@@ -244,7 +244,10 @@ typedef enum svn_repos_notify_action_t
   svn_repos_notify_cleanup_revprops,
 
   /** The repository format got bumped. @since New in 1.9. */
-  svn_repos_notify_format_bumped
+  svn_repos_notify_format_bumped,
+
+  /** A revision range was copied. @since New in 1.9. */
+  svn_repos_notify_hotcopy_rev_range
 } svn_repos_notify_action_t;
 
 /** The type of error occurring.
@@ -343,6 +346,16 @@ typedef struct svn_repos_notify_t
       @since New in 1.9. */
   svn_error_t *err;
 
+  /** For #svn_repos_notify_hotcopy_rev_range, the start of the copied
+      revision range.
+      @since New in 1.9. */
+  svn_revnum_t start_revision;
+
+  /** For #svn_repos_notify_hotcopy_rev_range, the end of the copied
+      revision range (might be the same as @a start_revision).
+      @since New in 1.9. */
+  svn_revnum_t end_revision;
+
   /* NOTE: Add new fields at the end to preserve binary compatibility.
      Also, if you add fields here, you have to update
      svn_repos_notify_create(). */
@@ -626,8 +639,35 @@ svn_repos_fs_type(svn_repos_t *repos, ap
  * already present in the destination. If incremental hotcopy is not
  * implemented by the filesystem backend, raise SVN_ERR_UNSUPPORTED_FEATURE.
  *
+ * For each revision range copied, the @a notify_func function will be
+ * called with the @a notify_baton and a notification structure containing
+ * appropriate values in @c start_revision and @c end_revision (both
+ * inclusive). @c start_revision might be equal to @c end_revision in
+ * case the copied range consists of a single revision. Currently, this
+ * notification is only supported for FSFS repositories. @a notify_func
+ * may be @c NULL if this notification is not required.
+ *
+ * @since New in 1.9.
+ */
+svn_error_t *
+svn_repos_hotcopy3(const char *src_path,
+                   const char *dst_path,
+                   svn_boolean_t clean_logs,
+                   svn_boolean_t incremental,
+                   svn_repos_notify_func_t notify_func,
+                   void *notify_baton,
+                   svn_cancel_func_t cancel_func,
+                   void *cancel_baton,
+                   apr_pool_t *pool);
+
+/**
+ * Like svn_repos_hotcopy3(), but with @a notify_func and @a notify_baton
+ * always passed as @c NULL.
+ *
  * @since New in 1.8.
+ * @deprecated Provided for backward compatibility with the 1.8 API.
  */
+SVN_DEPRECATED
 svn_error_t *
 svn_repos_hotcopy2(const char *src_path,
                    const char *dst_path,

Modified: subversion/branches/move-tracking-2/subversion/include/svn_string.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/svn_string.h?rev=1614348&r1=1614347&r2=1614348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/svn_string.h (original)
+++ subversion/branches/move-tracking-2/subversion/include/svn_string.h Tue Jul 29 13:46:03 2014
@@ -586,6 +586,16 @@ svn_cstring_atoui64(apr_uint64_t *n, con
 svn_error_t *
 svn_cstring_atoui(unsigned int *n, const char *str);
 
+/**
+ * Skip the common prefix @a prefix from the C string @a str, and return
+ * a pointer to the next character after the prefix.
+ * Return @c NULL if @a str does not start with @a prefix.
+ *
+ * @since New in 1.9.
+ */
+const char *
+svn_cstring_skip_prefix(const char *str, const char *prefix);
+
 /** @} */
 
 /** @} */

Modified: subversion/branches/move-tracking-2/subversion/libsvn_delta/debug_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_delta/debug_editor.c?rev=1614348&r1=1614347&r2=1614348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_delta/debug_editor.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_delta/debug_editor.c Tue Jul 29 13:46:03 2014
@@ -33,6 +33,7 @@ struct edit_baton
   int indent_level;
 
   svn_stream_t *out;
+  const char *prefix;
 };
 
 struct dir_baton
@@ -52,8 +53,7 @@ write_indent(struct edit_baton *eb, apr_
 {
   int i;
 
-  /* This is DBG_FLAG from ../libsvn_subr/debug.c */
-  SVN_ERR(svn_stream_puts(eb->out, "DBG:"));
+  SVN_ERR(svn_stream_puts(eb->out, eb->prefix));
   for (i = 0; i < eb->indent_level; ++i)
     SVN_ERR(svn_stream_puts(eb->out, " "));
 
@@ -391,19 +391,34 @@ close_edit(void *edit_baton,
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+abort_edit(void *edit_baton,
+           apr_pool_t *pool)
+{
+  struct edit_baton *eb = edit_baton;
+
+  SVN_ERR(write_indent(eb, pool));
+  SVN_ERR(svn_stream_printf(eb->out, pool, "abort_edit\n"));
+
+  SVN_ERR(eb->wrapped_editor->abort_edit(eb->wrapped_edit_baton, pool));
+
+  return SVN_NO_ERROR;
+}
+
 svn_error_t *
 svn_delta__get_debug_editor(const svn_delta_editor_t **editor,
                             void **edit_baton,
                             const svn_delta_editor_t *wrapped_editor,
                             void *wrapped_edit_baton,
+                            const char *prefix,
                             apr_pool_t *pool)
 {
-  svn_delta_editor_t *tree_editor = svn_delta_default_editor(pool);
+  svn_delta_editor_t *tree_editor = apr_palloc(pool, sizeof(*tree_editor));
   struct edit_baton *eb = apr_palloc(pool, sizeof(*eb));
   apr_file_t *errfp;
   svn_stream_t *out;
 
-  apr_status_t apr_err = apr_file_open_stderr(&errfp, pool);
+  apr_status_t apr_err = apr_file_open_stdout(&errfp, pool);
   if (apr_err)
     return svn_error_wrap_apr(apr_err, "Problem opening stderr");
 
@@ -424,11 +439,14 @@ svn_delta__get_debug_editor(const svn_de
   tree_editor->close_file = close_file;
   tree_editor->absent_file = absent_file;
   tree_editor->close_edit = close_edit;
+  tree_editor->abort_edit = abort_edit;
 
   eb->wrapped_editor = wrapped_editor;
   eb->wrapped_edit_baton = wrapped_edit_baton;
   eb->out = out;
   eb->indent_level = 0;
+  /* This is DBG_FLAG from ../libsvn_subr/debug.c */
+  eb->prefix = apr_pstrcat(pool, "DBG: ", prefix, SVN_VA_NULL);
 
   *editor = tree_editor;
   *edit_baton = eb;

Modified: subversion/branches/move-tracking-2/subversion/libsvn_delta/debug_editor.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_delta/debug_editor.h?rev=1614348&r1=1614347&r2=1614348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_delta/debug_editor.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_delta/debug_editor.h Tue Jul 29 13:46:03 2014
@@ -32,14 +32,19 @@ extern "C" {
 /* Return a debug editor that wraps @a wrapped_editor.
  *
  * The debug editor simply prints an indication of what callbacks are being
- * called to @c stderr, and is only intended for use in debugging subversion
+ * called to @c stdout, and is only intended for use in debugging subversion
  * editors.
+ *
+ * @a prefix, if non-null, is printed between "DBG: " and each indication.
+ *
+ * Note: Our test suite generally ignores stdout lines starting with "DBG:".
  */
 svn_error_t *
 svn_delta__get_debug_editor(const svn_delta_editor_t **editor,
                             void **edit_baton,
                             const svn_delta_editor_t *wrapped_editor,
                             void *wrapped_baton,
+                            const char *prefix,
                             apr_pool_t *pool);
 
 #ifdef __cplusplus

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs/fs-loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs/fs-loader.c?rev=1614348&r1=1614347&r2=1614348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs/fs-loader.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs/fs-loader.c Tue Jul 29 13:46:03 2014
@@ -614,9 +614,12 @@ svn_fs_delete_fs(const char *path, apr_p
 }
 
 svn_error_t *
-svn_fs_hotcopy2(const char *src_path, const char *dst_path,
+svn_fs_hotcopy3(const char *src_path, const char *dst_path,
                 svn_boolean_t clean, svn_boolean_t incremental,
-                svn_cancel_func_t cancel_func, void *cancel_baton,
+                svn_fs_hotcopy_notify_t notify_func,
+                void *notify_baton,
+                svn_cancel_func_t cancel_func,
+                void *cancel_baton,
                 apr_pool_t *scratch_pool)
 {
   fs_library_vtable_t *vtable;
@@ -669,12 +672,25 @@ svn_fs_hotcopy2(const char *src_path, co
     }
 
   SVN_ERR(vtable->hotcopy(src_fs, dst_fs, src_path, dst_path, clean,
-                          incremental, cancel_func, cancel_baton,
-                          common_pool_lock, scratch_pool, common_pool));
+                          incremental, notify_func, notify_baton,
+                          cancel_func, cancel_baton, common_pool_lock,
+                          scratch_pool, common_pool));
   return svn_error_trace(write_fs_type(dst_path, src_fs_type, scratch_pool));
 }
 
 svn_error_t *
+svn_fs_hotcopy2(const char *src_path, const char *dest_path,
+                svn_boolean_t clean, svn_boolean_t incremental,
+                svn_cancel_func_t cancel_func, void *cancel_baton,
+                apr_pool_t *scratch_pool)
+{
+  return svn_error_trace(svn_fs_hotcopy3(src_path, dest_path, clean,
+                                         incremental, NULL, NULL,
+                                         cancel_func, cancel_baton,
+                                         scratch_pool));
+}
+
+svn_error_t *
 svn_fs_hotcopy(const char *src_path, const char *dest_path,
                svn_boolean_t clean, apr_pool_t *pool)
 {
@@ -789,8 +805,9 @@ svn_error_t *
 svn_fs_hotcopy_berkeley(const char *src_path, const char *dest_path,
                         svn_boolean_t clean_logs, apr_pool_t *pool)
 {
-  return svn_error_trace(svn_fs_hotcopy2(src_path, dest_path, clean_logs,
-                                         FALSE, NULL, NULL, pool));
+  return svn_error_trace(svn_fs_hotcopy3(src_path, dest_path, clean_logs,
+                                         FALSE, NULL, NULL, NULL, NULL,
+                                         pool));
 }
 
 svn_error_t *

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs/fs-loader.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs/fs-loader.h?rev=1614348&r1=1614347&r2=1614348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs/fs-loader.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs/fs-loader.h Tue Jul 29 13:46:03 2014
@@ -118,6 +118,8 @@ typedef struct fs_library_vtable_t
                           const char *dst_path,
                           svn_boolean_t clean,
                           svn_boolean_t incremental,
+                          svn_fs_hotcopy_notify_t notify_func,
+                          void *notify_baton,
                           svn_cancel_func_t cancel_func,
                           void *cancel_baton,
                           svn_mutex__t *common_pool_lock,

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_base/fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_base/fs.c?rev=1614348&r1=1614347&r2=1614348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_base/fs.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_base/fs.c Tue Jul 29 13:46:03 2014
@@ -1291,6 +1291,8 @@ base_hotcopy(svn_fs_t *src_fs,
              const char *dest_path,
              svn_boolean_t clean_logs,
              svn_boolean_t incremental,
+             svn_fs_hotcopy_notify_t notify_func,
+             void *notify_baton,
              svn_cancel_func_t cancel_func,
              void *cancel_baton,
              svn_mutex__t *common_pool_lock,

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.c?rev=1614348&r1=1614347&r2=1614348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.c Tue Jul 29 13:46:03 2014
@@ -376,7 +376,8 @@ fs_pack(svn_fs_t *fs,
    DST_FS at DEST_PATH. If INCREMENTAL is TRUE, make an effort not to
    re-copy data which already exists in DST_FS.
    The CLEAN_LOGS argument is ignored and included for Subversion
-   1.0.x compatibility.  Perform all temporary allocations in POOL. */
+   1.0.x compatibility.  Indicate progress via the optional NOTIFY_FUNC
+   callback using NOTIFY_BATON.  Perform all temporary allocations in POOL. */
 static svn_error_t *
 fs_hotcopy(svn_fs_t *src_fs,
            svn_fs_t *dst_fs,
@@ -384,6 +385,8 @@ fs_hotcopy(svn_fs_t *src_fs,
            const char *dst_path,
            svn_boolean_t clean_logs,
            svn_boolean_t incremental,
+           svn_fs_hotcopy_notify_t notify_func,
+           void *notify_baton,
            svn_cancel_func_t cancel_func,
            void *cancel_baton,
            svn_mutex__t *common_pool_lock,
@@ -407,8 +410,9 @@ fs_hotcopy(svn_fs_t *src_fs,
     SVN_ERR(cancel_func(cancel_baton));
 
   /* Now, we may copy data as needed ... */
-  return svn_fs_fs__hotcopy(src_fs, dst_fs,
-                            incremental, cancel_func, cancel_baton, pool);
+  return svn_fs_fs__hotcopy(src_fs, dst_fs, incremental,
+                            notify_func, notify_baton,
+                            cancel_func, cancel_baton, pool);
 }
 
 

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.c?rev=1614348&r1=1614347&r2=1614348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.c Tue Jul 29 13:46:03 2014
@@ -43,6 +43,7 @@
 #include "util.h"
 
 #include "private/svn_fs_util.h"
+#include "private/svn_io_private.h"
 #include "private/svn_string_private.h"
 #include "private/svn_subr_private.h"
 #include "../libsvn_fs/fs-loader.h"
@@ -114,20 +115,7 @@ static svn_error_t *
 get_lock_on_filesystem(const char *lock_filename,
                        apr_pool_t *pool)
 {
-  svn_error_t *err = svn_io_file_lock2(lock_filename, TRUE, FALSE, pool);
-
-  if (err && APR_STATUS_IS_ENOENT(err->apr_err))
-    {
-      /* No lock file?  No big deal; these are just empty files
-         anyway.  Create it and try again. */
-      svn_error_clear(err);
-      err = NULL;
-
-      SVN_ERR(svn_io_file_create_empty(lock_filename, pool));
-      SVN_ERR(svn_io_file_lock2(lock_filename, TRUE, FALSE, pool));
-    }
-
-  return svn_error_trace(err);
+  return svn_error_trace(svn_io__file_lock_autocreate(lock_filename, pool));
 }
 
 /* Reset the HAS_WRITE_LOCK member in the FFD given as BATON_VOID.

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/hotcopy.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/hotcopy.c?rev=1614348&r1=1614347&r2=1614348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/hotcopy.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/hotcopy.c Tue Jul 29 13:46:03 2014
@@ -35,9 +35,13 @@
 #include "svn_private_config.h"
 
 /* Like svn_io_dir_file_copy(), but doesn't copy files that exist at
- * the destination and do not differ in terms of kind, size, and mtime. */
+ * the destination and do not differ in terms of kind, size, and mtime.
+ * Set *SKIPPED_P to FALSE only if the file was copied, do not change
+ * the value in *SKIPPED_P otherwise. SKIPPED_P may be NULL if not
+ * required. */
 static svn_error_t *
-hotcopy_io_dir_file_copy(const char *src_path,
+hotcopy_io_dir_file_copy(svn_boolean_t *skipped_p,
+                         const char *src_path,
                          const char *dst_path,
                          const char *file,
                          apr_pool_t *scratch_pool)
@@ -65,6 +69,9 @@ hotcopy_io_dir_file_copy(const char *src
         return SVN_NO_ERROR;
     }
 
+  if (skipped_p)
+    *skipped_p = FALSE;
+
   return svn_error_trace(svn_io_dir_file_copy(src_path, dst_path, file,
                                               scratch_pool));
 }
@@ -106,9 +113,12 @@ entry_name_to_utf8(const char **name_p,
 
 /* Like svn_io_copy_dir_recursively() but doesn't copy regular files that
  * exist in the destination and do not differ from the source in terms of
- * kind, size, and mtime. */
+ * kind, size, and mtime. Set *SKIPPED_P to FALSE only if at least one
+ * file was copied, do not change the value in *SKIPPED_P otherwise.
+ * SKIPPED_P may be NULL if not required. */
 static svn_error_t *
-hotcopy_io_copy_dir_recursively(const char *src,
+hotcopy_io_copy_dir_recursively(svn_boolean_t *skipped_p,
+                                const char *src,
                                 const char *dst_parent,
                                 const char *dst_basename,
                                 svn_boolean_t copy_perms,
@@ -174,8 +184,8 @@ hotcopy_io_copy_dir_recursively(const ch
                                      src, subpool));
           if (this_entry.filetype == APR_REG) /* regular file */
             {
-              SVN_ERR(hotcopy_io_dir_file_copy(src, dst_path, entryname_utf8,
-                                               subpool));
+              SVN_ERR(hotcopy_io_dir_file_copy(skipped_p, src, dst_path,
+                                               entryname_utf8, subpool));
             }
           else if (this_entry.filetype == APR_LNK) /* symlink */
             {
@@ -198,7 +208,8 @@ hotcopy_io_copy_dir_recursively(const ch
                 continue;
 
               src_target = svn_dirent_join(src, entryname_utf8, subpool);
-              SVN_ERR(hotcopy_io_copy_dir_recursively(src_target,
+              SVN_ERR(hotcopy_io_copy_dir_recursively(skipped_p,
+                                                      src_target,
                                                       dst_path,
                                                       entryname_utf8,
                                                       copy_perms,
@@ -228,9 +239,12 @@ hotcopy_io_copy_dir_recursively(const ch
 
 /* Copy an un-packed revision or revprop file for revision REV from SRC_SUBDIR
  * to DST_SUBDIR. Assume a sharding layout based on MAX_FILES_PER_DIR.
+ * Set *SKIPPED_P to FALSE only if the file was copied, do not change the
+ * value in *SKIPPED_P otherwise. SKIPPED_P may be NULL if not required.
  * Use SCRATCH_POOL for temporary allocations. */
 static svn_error_t *
-hotcopy_copy_shard_file(const char *src_subdir,
+hotcopy_copy_shard_file(svn_boolean_t *skipped_p,
+                        const char *src_subdir,
                         const char *dst_subdir,
                         svn_revnum_t rev,
                         int max_files_per_dir,
@@ -254,7 +268,8 @@ hotcopy_copy_shard_file(const char *src_
         }
     }
 
-  SVN_ERR(hotcopy_io_dir_file_copy(src_subdir_shard, dst_subdir_shard,
+  SVN_ERR(hotcopy_io_dir_file_copy(skipped_p,
+                                   src_subdir_shard, dst_subdir_shard,
                                    apr_psprintf(scratch_pool, "%ld", rev),
                                    scratch_pool));
 
@@ -266,9 +281,13 @@ hotcopy_copy_shard_file(const char *src_
  * MAX_FILES_PER_DIR revisions, from SRC_FS to DST_FS.
  * Update *DST_MIN_UNPACKED_REV in case the shard is new in DST_FS.
  * Do not re-copy data which already exists in DST_FS.
+ * Set *SKIPPED_P to FALSE only if at least one part of the shard
+ * was copied, do not change the value in *SKIPPED_P otherwise.
+ * SKIPPED_P may be NULL if not required.
  * Use SCRATCH_POOL for temporary allocations. */
 static svn_error_t *
-hotcopy_copy_packed_shard(svn_revnum_t *dst_min_unpacked_rev,
+hotcopy_copy_packed_shard(svn_boolean_t *skipped_p,
+                          svn_revnum_t *dst_min_unpacked_rev,
                           svn_fs_t *src_fs,
                           svn_fs_t *dst_fs,
                           svn_revnum_t rev,
@@ -290,7 +309,7 @@ hotcopy_copy_packed_shard(svn_revnum_t *
                               rev / max_files_per_dir);
   src_subdir_packed_shard = svn_dirent_join(src_subdir, packed_shard,
                                             scratch_pool);
-  SVN_ERR(hotcopy_io_copy_dir_recursively(src_subdir_packed_shard,
+  SVN_ERR(hotcopy_io_copy_dir_recursively(skipped_p, src_subdir_packed_shard,
                                           dst_subdir, packed_shard,
                                           TRUE /* copy_perms */,
                                           NULL /* cancel_func */, NULL,
@@ -311,7 +330,7 @@ hotcopy_copy_packed_shard(svn_revnum_t *
         {
           svn_pool_clear(iterpool);
 
-          SVN_ERR(hotcopy_copy_shard_file(src_subdir, dst_subdir,
+          SVN_ERR(hotcopy_copy_shard_file(skipped_p, src_subdir, dst_subdir,
                                           revprop_rev, max_files_per_dir,
                                           iterpool));
         }
@@ -321,7 +340,7 @@ hotcopy_copy_packed_shard(svn_revnum_t *
     {
       /* revprop for revision 0 will never be packed */
       if (rev == 0)
-        SVN_ERR(hotcopy_copy_shard_file(src_subdir, dst_subdir,
+        SVN_ERR(hotcopy_copy_shard_file(skipped_p, src_subdir, dst_subdir,
                                         0, max_files_per_dir,
                                         scratch_pool));
 
@@ -330,7 +349,8 @@ hotcopy_copy_packed_shard(svn_revnum_t *
                                   rev / max_files_per_dir);
       src_subdir_packed_shard = svn_dirent_join(src_subdir, packed_shard,
                                                 scratch_pool);
-      SVN_ERR(hotcopy_io_copy_dir_recursively(src_subdir_packed_shard,
+      SVN_ERR(hotcopy_io_copy_dir_recursively(skipped_p,
+                                              src_subdir_packed_shard,
                                               dst_subdir, packed_shard,
                                               TRUE /* copy_perms */,
                                               NULL /* cancel_func */, NULL,
@@ -349,58 +369,6 @@ hotcopy_copy_packed_shard(svn_revnum_t *
   return SVN_NO_ERROR;
 }
 
-/* If NEW_YOUNGEST is younger than *DST_YOUNGEST, update the 'current' file
- * in DST_FS and set *DST_YOUNGEST to NEW_YOUNGEST.  DST_FS is expected to
- * be in a new format, i.e. storing only the youngest revision number in
- * the 'current' file.  Use SCRATCH_POOL for temporary allocations. */
-static svn_error_t *
-hotcopy_update_current(svn_revnum_t *dst_youngest,
-                       svn_fs_t *dst_fs,
-                       svn_revnum_t new_youngest,
-                       apr_pool_t *scratch_pool)
-{
-  fs_fs_data_t *dst_ffd = dst_fs->fsap_data;
-
-  SVN_ERR_ASSERT(dst_ffd->format >= SVN_FS_FS__MIN_NO_GLOBAL_IDS_FORMAT);
-
-  if (*dst_youngest < new_youngest)
-    {
-      SVN_ERR(svn_fs_fs__write_current(dst_fs, new_youngest,
-                                       0, 0, scratch_pool));
-      *dst_youngest = new_youngest;
-    }
-
-  return SVN_NO_ERROR;
-}
-
-/* If NEW_YOUNGEST is younger than *DST_YOUNGEST, update the 'current' file
- * in DST_FS and set *DST_YOUNGEST to NEW_YOUNGEST.  DST_FS is expected to
- * be in an old format, i.e. storing the youngest revision and the two next-ID
- * parameters.  Those are updated with NEW_YOUNGEST, NEXT_NODE_ID and
- * NEXT_COPY_ID respectively.  Use SCRATCH_POOL for temporary allocations. */
-static svn_error_t *
-hotcopy_update_current_old(svn_revnum_t *dst_youngest,
-                           svn_fs_t *dst_fs,
-                           svn_revnum_t new_youngest,
-                           apr_uint64_t next_node_id,
-                           apr_uint64_t next_copy_id,
-                           apr_pool_t *scratch_pool)
-{
-  fs_fs_data_t *dst_ffd = dst_fs->fsap_data;
-
-  SVN_ERR_ASSERT(dst_ffd->format < SVN_FS_FS__MIN_NO_GLOBAL_IDS_FORMAT);
-
-  if (*dst_youngest < new_youngest)
-    {
-      SVN_ERR(svn_fs_fs__write_current(dst_fs, new_youngest,
-                                       next_node_id, next_copy_id,
-                                       scratch_pool));
-      *dst_youngest = new_youngest;
-    }
-
-  return SVN_NO_ERROR;
-}
-
 /* Remove FILE in SHARD folder.  Use POOL for temporary allocations. */
 static svn_error_t *
 hotcopy_remove_file(const char *shard,
@@ -579,18 +547,21 @@ remove_folder(const char *path,
  * When copying packed or unpacked shards, checkpoint the result in DST_FS
  * for every shard by updating the 'current' file if necessary.  Assume
  * the >= SVN_FS_FS__MIN_NO_GLOBAL_IDS_FORMAT filesystem format without
- * global next-ID counters.  Use POOL for temporary allocations.
+ * global next-ID counters.  Indicate progress via the optional NOTIFY_FUNC
+ * callback using NOTIFY_BATON.  Use POOL for temporary allocations.
  */
 static svn_error_t *
-hotcopy_revisions(svn_revnum_t *dst_youngest,
-                  svn_fs_t *src_fs,
+hotcopy_revisions(svn_fs_t *src_fs,
                   svn_fs_t *dst_fs,
                   svn_revnum_t src_youngest,
+                  svn_revnum_t dst_youngest,
                   svn_boolean_t incremental,
                   const char *src_revs_dir,
                   const char *dst_revs_dir,
                   const char *src_revprops_dir,
                   const char *dst_revprops_dir,
+                  svn_fs_hotcopy_notify_t notify_func,
+                  void* notify_baton,
                   svn_cancel_func_t cancel_func,
                   void* cancel_baton,
                   apr_pool_t *pool)
@@ -643,22 +614,38 @@ hotcopy_revisions(svn_revnum_t *dst_youn
   /* First, copy packed shards. */
   for (rev = 0; rev < src_min_unpacked_rev; rev += max_files_per_dir)
     {
+      svn_boolean_t skipped = TRUE;
+      svn_revnum_t pack_end_rev;
+
       svn_pool_clear(iterpool);
 
       if (cancel_func)
         SVN_ERR(cancel_func(cancel_baton));
 
       /* Copy the packed shard. */
-      SVN_ERR(hotcopy_copy_packed_shard(&dst_min_unpacked_rev,
+      SVN_ERR(hotcopy_copy_packed_shard(&skipped, &dst_min_unpacked_rev,
                                         src_fs, dst_fs,
                                         rev, max_files_per_dir,
                                         iterpool));
 
-      /* If necessary, update 'current' to the most recent packed rev,
-       * so readers can see new revisions which arrived in this pack. */
-      SVN_ERR(hotcopy_update_current(dst_youngest, dst_fs,
-                                     rev + max_files_per_dir - 1,
-                                     iterpool));
+      pack_end_rev = rev + max_files_per_dir - 1;
+
+      /* Whenever this pack did not previously exist in the destination,
+       * update 'current' to the most recent packed rev (so readers can see
+       * new revisions which arrived in this pack). */
+      if (pack_end_rev > dst_youngest)
+        {
+          SVN_ERR(svn_fs_fs__write_current(dst_fs, pack_end_rev, 0, 0,
+                                           iterpool));
+        }
+
+      /* When notifying about packed shards, make things simpler by either
+       * reporting a full revision range, i.e [pack start, pack end] or
+       * reporting nothing. There is one case when this approach might not
+       * be exact (incremental hotcopy with a pack replacing last unpacked
+       * revisions), but generally this is good enough. */
+      if (notify_func && !skipped)
+        notify_func(notify_baton, rev, pack_end_rev, iterpool);
 
       /* Remove revision files which are now packed. */
       if (incremental)
@@ -693,6 +680,8 @@ hotcopy_revisions(svn_revnum_t *dst_youn
    * If necessary, update 'current' after copying all files from a shard. */
   for (; rev <= src_youngest; rev++)
     {
+      svn_boolean_t skipped = TRUE;
+
       svn_pool_clear(iterpool);
 
       if (cancel_func)
@@ -712,18 +701,30 @@ hotcopy_revisions(svn_revnum_t *dst_youn
        * longer where we expect it to be). */
 
       /* Copy the rev file. */
-      SVN_ERR(hotcopy_copy_shard_file(src_revs_dir, dst_revs_dir,
-                                      rev, max_files_per_dir,
+      SVN_ERR(hotcopy_copy_shard_file(&skipped,
+                                      src_revs_dir, dst_revs_dir, rev,
+                                      max_files_per_dir,
                                       iterpool));
       /* Copy the revprop file. */
-      SVN_ERR(hotcopy_copy_shard_file(src_revprops_dir,
-                                      dst_revprops_dir,
-                                      rev, max_files_per_dir, 
+      SVN_ERR(hotcopy_copy_shard_file(&skipped,
+                                      src_revprops_dir, dst_revprops_dir,
+                                      rev, max_files_per_dir,
                                       iterpool));
 
-      /* After completing a full shard, update 'current'. */
-      if (max_files_per_dir && rev % max_files_per_dir == 0)
-        SVN_ERR(hotcopy_update_current(dst_youngest, dst_fs, rev, iterpool));
+      /* Whenever this revision did not previously exist in the destination,
+       * checkpoint the progress via 'current' (do that once per full shard
+       * in order not to slow things down). */
+      if (rev > dst_youngest)
+        {
+          if (max_files_per_dir && (rev % max_files_per_dir == 0))
+            {
+              SVN_ERR(svn_fs_fs__write_current(dst_fs, rev, 0, 0,
+                                               iterpool));
+            }
+        }
+
+      if (notify_func && !skipped)
+        notify_func(notify_baton, rev, rev, iterpool);
     }
   svn_pool_destroy(iterpool);
 
@@ -738,8 +739,9 @@ hotcopy_revisions(svn_revnum_t *dst_youn
  * filesystems without sharding and packing.  Copy the non-sharded revision
  * and revprop files from SRC_FS to DST_FS.  Do not re-copy data which
  * already exists in DST_FS.  Do not somehow checkpoint the results in
- * the 'current' file in DST_FS.  Use POOL for temporary allocations.
- * Also see hotcopy_revisions().
+ * the 'current' file in DST_FS.  Indicate progress via the optional
+ * NOTIFY_FUNC callback using NOTIFY_BATON.  Use POOL for temporary
+ * allocations.  Also see hotcopy_revisions().
  */
 static svn_error_t *
 hotcopy_revisions_old(svn_fs_t *src_fs,
@@ -749,6 +751,8 @@ hotcopy_revisions_old(svn_fs_t *src_fs,
                       const char *dst_revs_dir,
                       const char *src_revprops_dir,
                       const char *dst_revprops_dir,
+                      svn_fs_hotcopy_notify_t notify_func,
+                      void* notify_baton,
                       svn_cancel_func_t cancel_func,
                       void* cancel_baton,
                       apr_pool_t *pool)
@@ -758,17 +762,23 @@ hotcopy_revisions_old(svn_fs_t *src_fs,
 
   for (rev = 0; rev <= src_youngest; rev++)
     {
+      svn_boolean_t skipped = TRUE;
+
       svn_pool_clear(iterpool);
 
       if (cancel_func)
         SVN_ERR(cancel_func(cancel_baton));
 
-      SVN_ERR(hotcopy_io_dir_file_copy(src_revs_dir, dst_revs_dir,
+      SVN_ERR(hotcopy_io_dir_file_copy(&skipped, src_revs_dir, dst_revs_dir,
                                        apr_psprintf(iterpool, "%ld", rev),
                                        iterpool));
-      SVN_ERR(hotcopy_io_dir_file_copy(src_revprops_dir, dst_revprops_dir,
+      SVN_ERR(hotcopy_io_dir_file_copy(&skipped, src_revprops_dir,
+                                       dst_revprops_dir,
                                        apr_psprintf(iterpool, "%ld", rev),
                                        iterpool));
+
+      if (notify_func && !skipped)
+        notify_func(notify_baton, rev, rev, iterpool);
     }
     svn_pool_destroy(iterpool);
 
@@ -780,6 +790,8 @@ struct hotcopy_body_baton {
   svn_fs_t *src_fs;
   svn_fs_t *dst_fs;
   svn_boolean_t incremental;
+  svn_fs_hotcopy_notify_t notify_func;
+  void *notify_baton;
   svn_cancel_func_t cancel_func;
   void *cancel_baton;
 };
@@ -811,6 +823,8 @@ hotcopy_body(void *baton, apr_pool_t *po
   svn_fs_t *dst_fs = hbb->dst_fs;
   fs_fs_data_t *dst_ffd = dst_fs->fsap_data;
   svn_boolean_t incremental = hbb->incremental;
+  svn_fs_hotcopy_notify_t notify_func = hbb->notify_func;
+  void* notify_baton = hbb->notify_baton;
   svn_cancel_func_t cancel_func = hbb->cancel_func;
   void* cancel_baton = hbb->cancel_baton;
   svn_revnum_t src_youngest;
@@ -925,22 +939,22 @@ hotcopy_body(void *baton, apr_pool_t *po
    * revision number, but also the next-ID counters). */
   if (src_ffd->format >= SVN_FS_FS__MIN_NO_GLOBAL_IDS_FORMAT)
     {
-      SVN_ERR(hotcopy_revisions(&dst_youngest, src_fs, dst_fs, src_youngest,
+      SVN_ERR(hotcopy_revisions(src_fs, dst_fs, src_youngest, dst_youngest,
                                 incremental, src_revs_dir, dst_revs_dir,
                                 src_revprops_dir, dst_revprops_dir,
+                                notify_func, notify_baton,
                                 cancel_func, cancel_baton, pool));
-      SVN_ERR(hotcopy_update_current(&dst_youngest, dst_fs, src_youngest,
-                                     pool));
+      SVN_ERR(svn_fs_fs__write_current(dst_fs, src_youngest, 0, 0, pool));
     }
   else
     {
       SVN_ERR(hotcopy_revisions_old(src_fs, dst_fs, src_youngest,
                                     src_revs_dir, dst_revs_dir,
                                     src_revprops_dir, dst_revprops_dir,
+                                    notify_func, notify_baton,
                                     cancel_func, cancel_baton, pool));
-      SVN_ERR(hotcopy_update_current_old(&dst_youngest, dst_fs, src_youngest,
-                                         src_next_node_id, src_next_copy_id,
-                                         pool));
+      SVN_ERR(svn_fs_fs__write_current(dst_fs, src_youngest, src_next_node_id,
+                                       src_next_copy_id, pool));
     }
 
   /* Replace the locks tree.
@@ -961,7 +975,7 @@ hotcopy_body(void *baton, apr_pool_t *po
   src_subdir = svn_dirent_join(src_fs->path, PATH_NODE_ORIGINS_DIR, pool);
   SVN_ERR(svn_io_check_path(src_subdir, &kind, pool));
   if (kind == svn_node_dir)
-    SVN_ERR(hotcopy_io_copy_dir_recursively(src_subdir, dst_fs->path,
+    SVN_ERR(hotcopy_io_copy_dir_recursively(NULL, src_subdir, dst_fs->path,
                                             PATH_NODE_ORIGINS_DIR, TRUE,
                                             cancel_func, cancel_baton, pool));
 
@@ -973,14 +987,14 @@ hotcopy_body(void *baton, apr_pool_t *po
   if (dst_ffd->format >= SVN_FS_FS__MIN_REP_SHARING_FORMAT)
     {
       /* Copy the rep cache and then remove entries for revisions
-       * younger than the destination's youngest revision. */
+       * that did not make it into the destination. */
       src_subdir = svn_dirent_join(src_fs->path, REP_CACHE_DB_NAME, pool);
       dst_subdir = svn_dirent_join(dst_fs->path, REP_CACHE_DB_NAME, pool);
       SVN_ERR(svn_io_check_path(src_subdir, &kind, pool));
       if (kind == svn_node_file)
         {
           SVN_ERR(svn_sqlite__hotcopy(src_subdir, dst_subdir, pool));
-          SVN_ERR(svn_fs_fs__del_rep_reference(dst_fs, dst_youngest, pool));
+          SVN_ERR(svn_fs_fs__del_rep_reference(dst_fs, src_youngest, pool));
         }
     }
 
@@ -1144,6 +1158,8 @@ svn_error_t *
 svn_fs_fs__hotcopy(svn_fs_t *src_fs,
                    svn_fs_t *dst_fs,
                    svn_boolean_t incremental,
+                   svn_fs_hotcopy_notify_t notify_func,
+                   void *notify_baton,
                    svn_cancel_func_t cancel_func,
                    void *cancel_baton,
                    apr_pool_t *pool)
@@ -1153,6 +1169,8 @@ svn_fs_fs__hotcopy(svn_fs_t *src_fs,
   hbb.src_fs = src_fs;
   hbb.dst_fs = dst_fs;
   hbb.incremental = incremental;
+  hbb.notify_func = notify_func;
+  hbb.notify_baton = notify_baton;
   hbb.cancel_func = cancel_func;
   hbb.cancel_baton = cancel_baton;
   SVN_ERR(svn_fs_fs__with_write_lock(dst_fs, hotcopy_locking_src_body, &hbb,

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/hotcopy.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/hotcopy.h?rev=1614348&r1=1614347&r2=1614348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/hotcopy.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/hotcopy.h Tue Jul 29 13:46:03 2014
@@ -36,11 +36,14 @@ svn_fs_fs__hotcopy_prepare_target(svn_fs
                                   apr_pool_t *pool);
 
 /* Copy the fsfs filesystem SRC_FS into DST_FS. If INCREMENTAL is TRUE, do
- * not re-copy data which already exists in DST_FS. Use POOL for temporary
- * allocations. */
+ * not re-copy data which already exists in DST_FS.  Indicate progress via
+ * the optional NOTIFY_FUNC callback using NOTIFY_BATON.  Use POOL for
+ * temporary allocations. */
 svn_error_t * svn_fs_fs__hotcopy(svn_fs_t *src_fs,
                                  svn_fs_t *dst_fs,
                                  svn_boolean_t incremental,
+                                 svn_fs_hotcopy_notify_t notify_func,
+                                 void *notify_baton,
                                  svn_cancel_func_t cancel_func,
                                  void *cancel_baton,
                                  apr_pool_t *pool);

Propchange: subversion/branches/move-tracking-2/subversion/libsvn_fs_x/
------------------------------------------------------------------------------
  Merged /subversion/trunk/subversion/libsvn_fs_x:r1612334-1614346

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs.c?rev=1614348&r1=1614347&r2=1614348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs.c Tue Jul 29 13:46:03 2014
@@ -382,7 +382,8 @@ x_pack(svn_fs_t *fs,
    DST_FS at DEST_PATH. If INCREMENTAL is TRUE, make an effort not to
    re-copy data which already exists in DST_FS.
    The CLEAN_LOGS argument is ignored and included for Subversion
-   1.0.x compatibility.  Perform all temporary allocations in POOL. */
+   1.0.x compatibility.  The NOTIFY_FUNC and NOTIFY_BATON arguments
+   are also currently ignored.  Perform all temporary allocations in POOL. */
 static svn_error_t *
 x_hotcopy(svn_fs_t *src_fs,
           svn_fs_t *dst_fs,
@@ -390,6 +391,8 @@ x_hotcopy(svn_fs_t *src_fs,
           const char *dst_path,
           svn_boolean_t clean_logs,
           svn_boolean_t incremental,
+          svn_fs_hotcopy_notify_t notify_func,
+          void *notify_baton,
           svn_cancel_func_t cancel_func,
           void *cancel_baton,
           svn_mutex__t *common_pool_lock,

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_x/transaction.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_x/transaction.c?rev=1614348&r1=1614347&r2=1614348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_x/transaction.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_x/transaction.c Tue Jul 29 13:46:03 2014
@@ -46,6 +46,7 @@
 #include "private/svn_sorts_private.h"
 #include "private/svn_string_private.h"
 #include "private/svn_subr_private.h"
+#include "private/svn_io_private.h"
 #include "../libsvn_fs/fs-loader.h"
 
 #include "svn_private_config.h"
@@ -185,20 +186,7 @@ static svn_error_t *
 get_lock_on_filesystem(const char *lock_filename,
                        apr_pool_t *pool)
 {
-  svn_error_t *err = svn_io_file_lock2(lock_filename, TRUE, FALSE, pool);
-
-  if (err && APR_STATUS_IS_ENOENT(err->apr_err))
-    {
-      /* No lock file?  No big deal; these are just empty files
-         anyway.  Create it and try again. */
-      svn_error_clear(err);
-      err = NULL;
-
-      SVN_ERR(svn_io_file_create_empty(lock_filename, pool));
-      SVN_ERR(svn_io_file_lock2(lock_filename, TRUE, FALSE, pool));
-    }
-
-  return svn_error_trace(err);
+  return svn_error_trace(svn_io__file_lock_autocreate(lock_filename, pool));
 }
 
 /* Reset the HAS_WRITE_LOCK member in the FFD given as BATON_VOID.

Modified: subversion/branches/move-tracking-2/subversion/libsvn_repos/authz_pool.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_repos/authz_pool.c?rev=1614348&r1=1614347&r2=1614348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_repos/authz_pool.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_repos/authz_pool.c Tue Jul 29 13:46:03 2014
@@ -34,8 +34,7 @@
 #include "private/svn_subr_private.h"
 #include "private/svn_repos_private.h"
 #include "private/svn_string_private.h"
-
-#include "../libsvn_subr/config_impl.h"
+#include "private/svn_subr_private.h"
 
 #include "repos.h"
 

Modified: subversion/branches/move-tracking-2/subversion/libsvn_repos/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_repos/repos.c?rev=1614348&r1=1614347&r2=1614348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_repos/repos.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_repos/repos.c Tue Jul 29 13:46:03 2014
@@ -2119,22 +2119,54 @@ lock_db_logs_file(svn_repos_t *repos,
 }
 
 
+/* Baton used with fs_hotcopy_notify(), specifying the svn_repos layer
+ * notification parameters.
+ */
+struct fs_hotcopy_notify_baton_t
+{
+  svn_repos_notify_func_t notify_func;
+  void *notify_baton;
+};
+
+/* Implements svn_fs_hotcopy_notify_t as forwarding to a
+ * svn_repos_notify_func_t passed in a fs_hotcopy_notify_baton_t* BATON.
+ */
+static void
+fs_hotcopy_notify(void *baton,
+                  svn_revnum_t start_revision,
+                  svn_revnum_t end_revision,
+                  apr_pool_t *pool)
+{
+  struct fs_hotcopy_notify_baton_t *fs_baton = baton;
+  svn_repos_notify_t *notify;
+
+  notify = svn_repos_notify_create(svn_repos_notify_hotcopy_rev_range, pool);
+  notify->start_revision = start_revision;
+  notify->end_revision = end_revision;
+
+  fs_baton->notify_func(fs_baton->notify_baton, notify, pool);
+}
+
 /* Make a copy of a repository with hot backup of fs. */
 svn_error_t *
-svn_repos_hotcopy2(const char *src_path,
+svn_repos_hotcopy3(const char *src_path,
                    const char *dst_path,
                    svn_boolean_t clean_logs,
                    svn_boolean_t incremental,
+                   svn_repos_notify_func_t notify_func,
+                   void *notify_baton,
                    svn_cancel_func_t cancel_func,
                    void *cancel_baton,
                    apr_pool_t *pool)
 {
-  svn_repos_t *src_repos;
-  svn_repos_t *dst_repos;
+  svn_fs_hotcopy_notify_t fs_notify_func;
+  struct fs_hotcopy_notify_baton_t fs_notify_baton;
   struct hotcopy_ctx_t hotcopy_context;
-  svn_error_t *err;
   const char *src_abspath;
   const char *dst_abspath;
+  svn_repos_t *src_repos;
+  svn_repos_t *dst_repos;
+  svn_error_t *err;
 
   SVN_ERR(svn_dirent_get_absolute(&src_abspath, src_path, pool));
   SVN_ERR(svn_dirent_get_absolute(&dst_abspath, dst_path, pool));
@@ -2200,8 +2232,13 @@ svn_repos_hotcopy2(const char *src_path,
      No one should be accessing it at the moment */
   SVN_ERR(lock_repos(dst_repos, TRUE, FALSE, pool));
 
-  SVN_ERR(svn_fs_hotcopy2(src_repos->db_path, dst_repos->db_path,
+  fs_notify_func = notify_func ? fs_hotcopy_notify : NULL;
+  fs_notify_baton.notify_func = notify_func;
+  fs_notify_baton.notify_baton = notify_baton;
+
+  SVN_ERR(svn_fs_hotcopy3(src_repos->db_path, dst_repos->db_path,
                           clean_logs, incremental,
+                          fs_notify_func, &fs_notify_baton,
                           cancel_func, cancel_baton, pool));
 
   /* Destination repository is ready.  Stamp it with a format number. */
@@ -2211,6 +2248,20 @@ svn_repos_hotcopy2(const char *src_path,
 }
 
 svn_error_t *
+svn_repos_hotcopy2(const char *src_path,
+                   const char *dst_path,
+                   svn_boolean_t clean_logs,
+                   svn_boolean_t incremental,
+                   svn_cancel_func_t cancel_func,
+                   void *cancel_baton,
+                   apr_pool_t *pool)
+{
+  return svn_error_trace(svn_repos_hotcopy3(src_path, dst_path, clean_logs,
+                                            incremental, NULL, NULL,
+                                            cancel_func, cancel_baton, pool));
+}
+
+svn_error_t *
 svn_repos_hotcopy(const char *src_path,
                   const char *dst_path,
                   svn_boolean_t clean_logs,

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/io.c?rev=1614348&r1=1614347&r2=1614348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/io.c Tue Jul 29 13:46:03 2014
@@ -2238,6 +2238,35 @@ svn_io_file_lock2(const char *lock_file,
   return svn_io_lock_open_file(lockfile_handle, exclusive, nonblocking, pool);
 }
 
+svn_error_t *
+svn_io__file_lock_autocreate(const char *lock_file,
+                             apr_pool_t *pool)
+{
+  svn_error_t *err
+    = svn_io_file_lock2(lock_file, TRUE, FALSE, pool);
+  if (err && APR_STATUS_IS_ENOENT(err->apr_err))
+    {
+      /* No lock file?  No big deal; these are just empty files anyway.
+         Create it and try again. */
+      svn_error_clear(err);
+
+      /* This file creation is racy.
+         We don't care as long as file gets created at all. */
+      err = svn_io_file_create_empty(lock_file, pool);
+      if (err && APR_STATUS_IS_EEXIST(err->apr_err))
+        {
+          svn_error_clear(err);
+          err = NULL;
+        }
+
+      /* Finally, lock the file - if it exists */
+      if (!err)
+        err = svn_io_file_lock2(lock_file, TRUE, FALSE, pool);
+    }
+
+  return svn_error_trace(err);
+}
+
 
 
 /* Data consistency/coherency operations. */

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/named_atomic.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/named_atomic.c?rev=1614348&r1=1614347&r2=1614348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/named_atomic.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/named_atomic.c Tue Jul 29 13:46:03 2014
@@ -32,6 +32,7 @@
 #include "svn_pools.h"
 #include "svn_dirent_uri.h"
 #include "svn_io.h"
+#include "private/svn_io_private.h"
 
 /* Implementation aspects.
  *
@@ -274,28 +275,10 @@ init_thread_mutex(void *baton, apr_pool_
 static svn_error_t *
 lock(struct mutex_t *mutex)
 {
-  svn_error_t *err;
-
-  /* Intra-process lock */
-  SVN_ERR(svn_mutex__lock(thread_mutex));
-
-  /* Inter-process lock. */
-  err = svn_io_file_lock2(mutex->lock_name, TRUE, FALSE, mutex->pool);
-  if (err && APR_STATUS_IS_ENOENT(err->apr_err))
-    {
-      /* No lock file?  No big deal; these are just empty files anyway.
-         Create it and try again. */
-      svn_error_clear(err);
-      err = NULL;
-
-      SVN_ERR(svn_io_file_create_empty(mutex->lock_name, mutex->pool));
-      SVN_ERR(svn_io_file_lock2(mutex->lock_name, TRUE, FALSE, mutex->pool));
-    }
-
-  /* Don't leave us in a semi-locked state ... */
-  return err
-    ? svn_mutex__unlock(thread_mutex, err)
-    : err;
+  SVN_MUTEX__WITH_LOCK(thread_mutex,
+                       svn_io__file_lock_autocreate(mutex->lock_name,
+                                                    mutex->pool));
+  return SVN_NO_ERROR;
 }
 
 /* Utility that releases the lock previously acquired via lock().  If the

Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/string.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/string.c?rev=1614348&r1=1614347&r2=1614348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/string.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/string.c Tue Jul 29 13:46:03 2014
@@ -1465,4 +1465,17 @@ svn_cstring__reverse_match_length(const 
   return max_len;
 }
 
+const char *
+svn_cstring_skip_prefix(const char *str, const char *prefix)
+{
+  apr_size_t len = strlen(prefix);
 
+  if (strncmp(str, prefix, len) == 0)
+    {
+      return str + len;
+    }
+  else
+    {
+      return NULL;
+    }
+}

Modified: subversion/branches/move-tracking-2/subversion/svnadmin/svnadmin.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnadmin/svnadmin.c?rev=1614348&r1=1614347&r2=1614348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnadmin/svnadmin.c (original)
+++ subversion/branches/move-tracking-2/subversion/svnadmin/svnadmin.c Tue Jul 29 13:46:03 2014
@@ -410,7 +410,7 @@ static const svn_opt_subcommand_desc2_t 
     "Make a hot copy of a repository.\n"
     "If --incremental is passed, data which already exists at the destination\n"
     "is not copied again.  Incremental mode is implemented for FSFS repositories.\n"),
-   {svnadmin__clean_logs, svnadmin__incremental} },
+   {svnadmin__clean_logs, svnadmin__incremental, 'q'} },
 
   {"info", subcommand_info, {0}, N_
    ("usage: svnadmin info REPOS_PATH\n\n"
@@ -872,7 +872,8 @@ struct repos_notify_handler_baton {
 };
 
 /* Implementation of svn_repos_notify_func_t to wrap the output to a
-   response stream for svn_repos_dump_fs2() and svn_repos_verify_fs() */
+   response stream for svn_repos_dump_fs2(), svn_repos_verify_fs(),
+   svn_repos_hotcopy3() and others. */
 static void
 repos_notify_handler(void *baton,
                      const svn_repos_notify_t *notify,
@@ -1088,6 +1089,21 @@ repos_notify_handler(void *baton,
       svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
                             _("Bumped repository format to %ld\n"),
                             notify->revision));
+      return;
+
+    case svn_repos_notify_hotcopy_rev_range:
+      if (notify->start_revision == notify->end_revision)
+        {
+          svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+                                            _("* Copied revision %ld.\n"),
+                                            notify->start_revision));
+        }
+      else
+        {
+          svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+                               _("* Copied revisions from %ld to %ld.\n"),
+                               notify->start_revision, notify->end_revision));
+        }
 
     default:
       return;
@@ -1872,6 +1888,7 @@ svn_error_t *
 subcommand_hotcopy(apr_getopt_t *os, void *baton, apr_pool_t *pool)
 {
   struct svnadmin_opt_state *opt_state = baton;
+  struct repos_notify_handler_baton notify_baton = { 0 };
   apr_array_header_t *targets;
   const char *new_repos_path;
 
@@ -1880,9 +1897,14 @@ subcommand_hotcopy(apr_getopt_t *os, voi
   new_repos_path = APR_ARRAY_IDX(targets, 0, const char *);
   SVN_ERR(target_arg_to_dirent(&new_repos_path, new_repos_path, pool));
 
-  return svn_repos_hotcopy2(opt_state->repository_path, new_repos_path,
+  /* Progress feedback goes to STDOUT, unless they asked to suppress it. */
+  if (! opt_state->quiet)
+    notify_baton.feedback_stream = recode_stream_create(stdout, pool);
+
+  return svn_repos_hotcopy3(opt_state->repository_path, new_repos_path,
                             opt_state->clean_logs, opt_state->incremental,
-                            check_cancel, NULL, pool);
+                            !opt_state->quiet ? repos_notify_handler : NULL,
+                            &notify_baton, check_cancel, NULL, pool);
 }
 
 svn_error_t *

Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/svnadmin_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/svnadmin_tests.py?rev=1614348&r1=1614347&r2=1614348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/cmdline/svnadmin_tests.py (original)
+++ subversion/branches/move-tracking-2/subversion/tests/cmdline/svnadmin_tests.py Tue Jul 29 13:46:03 2014
@@ -2647,6 +2647,240 @@ def verify_quickly(sbox):
     raise svntest.Failure
 
 
+@SkipUnless(svntest.main.is_fs_type_fsfs)
+@SkipUnless(svntest.main.fs_has_pack)
+def fsfs_hotcopy_progress(sbox):
+  "hotcopy progress reporting"
+
+  # Check how 'svnadmin hotcopy' reports progress for non-incremental
+  # and incremental scenarios.  The progress output can be affected by
+  # the --fsfs-packing option, so skip the test if that is the case.
+  if svntest.main.options.fsfs_packing:
+    raise svntest.Skip
+
+  # Create an empty repository, configure three files per shard.
+  sbox.build(create_wc=False)
+  svntest.main.safe_rmtree(sbox.repo_dir, True)
+  svntest.main.create_repos(sbox.repo_dir)
+
+  if svntest.main.options.server_minor_version >= 9:
+    format = "7\nlayout sharded 3\naddressing logical 0\n"
+  elif svntest.main.options.server_minor_version < 9:
+    format = "6\nlayout sharded 3\n"
+  else:
+    raise svntest.Failure
+
+  format_file = open(os.path.join(sbox.repo_dir, 'db', 'format'), 'wb')
+  format_file.write(format)
+  format_file.close()
+
+  inc_backup_dir, inc_backup_url = sbox.add_repo_path('incremental-backup')
+
+  # Nothing really exciting for the empty repository.
+  expected_full = [
+    "* Copied revision 0.\n"
+    ]
+  expected_incremental = [
+    "* Copied revision 0.\n",
+    ]
+
+  backup_dir, backup_url = sbox.add_repo_path('backup-0')
+  svntest.actions.run_and_verify_svnadmin(None, expected_full, [],
+                                          'hotcopy',
+                                          sbox.repo_dir, backup_dir)
+  svntest.actions.run_and_verify_svnadmin(None, expected_incremental, [],
+                                          'hotcopy', '--incremental',
+                                          sbox.repo_dir, inc_backup_dir)
+
+  # Commit three revisions.  After this step we have a full shard
+  # (r0, r1, r2) and the second shard (r3) with a single revision.
+  for i in range(3):
+    svntest.actions.run_and_verify_svn(None, None, [], 'mkdir',
+                                       '-m', svntest.main.make_log_msg(),
+                                       sbox.repo_url + '/dir-%i' % i)
+  expected_full = [
+    "* Copied revision 0.\n",
+    "* Copied revision 1.\n",
+    "* Copied revision 2.\n",
+    "* Copied revision 3.\n",
+    ]
+  expected_incremental = [
+    "* Copied revision 1.\n",
+    "* Copied revision 2.\n",
+    "* Copied revision 3.\n",
+    ]
+
+  backup_dir, backup_url = sbox.add_repo_path('backup-1')
+  svntest.actions.run_and_verify_svnadmin(None, expected_full, [],
+                                          'hotcopy',
+                                          sbox.repo_dir, backup_dir)
+  svntest.actions.run_and_verify_svnadmin(None, expected_incremental, [],
+                                          'hotcopy', '--incremental',
+                                          sbox.repo_dir, inc_backup_dir)
+
+  # Pack everything (r3 is still unpacked) and hotcopy again.  In this case,
+  # the --incremental output should track the incoming (r0, r1, r2) pack and
+  # should not mention r3, because it is already a part of the destination
+  # and is *not* a part of the incoming pack.
+  svntest.actions.run_and_verify_svnadmin(None, None, [], 'pack',
+                                          sbox.repo_dir)
+  expected_full = [
+    "* Copied revisions from 0 to 2.\n",
+    "* Copied revision 3.\n",
+    ]
+  expected_incremental = [
+    "* Copied revisions from 0 to 2.\n",
+    ]
+
+  backup_dir, backup_url = sbox.add_repo_path('backup-2')
+  svntest.actions.run_and_verify_svnadmin(None, expected_full, [],
+                                          'hotcopy',
+                                          sbox.repo_dir, backup_dir)
+  svntest.actions.run_and_verify_svnadmin(None, expected_incremental, [],
+                                          'hotcopy', '--incremental',
+                                          sbox.repo_dir, inc_backup_dir)
+
+  # Fill the second shard, pack again, commit several unpacked revisions
+  # on top of it.  Rerun the hotcopy and check the progress output.
+  for i in range(4, 6):
+    svntest.actions.run_and_verify_svn(None, None, [], 'mkdir',
+                                       '-m', svntest.main.make_log_msg(),
+                                       sbox.repo_url + '/dir-%i' % i)
+
+  svntest.actions.run_and_verify_svnadmin(None, None, [], 'pack',
+                                          sbox.repo_dir)
+
+  for i in range(6, 8):
+    svntest.actions.run_and_verify_svn(None, None, [], 'mkdir',
+                                       '-m', svntest.main.make_log_msg(),
+                                       sbox.repo_url + '/dir-%i' % i)
+  expected_full = [
+    "* Copied revisions from 0 to 2.\n",
+    "* Copied revisions from 3 to 5.\n",
+    "* Copied revision 6.\n",
+    "* Copied revision 7.\n",
+    ]
+  expected_incremental = [
+    "* Copied revisions from 3 to 5.\n",
+    "* Copied revision 6.\n",
+    "* Copied revision 7.\n",
+    ]
+
+  backup_dir, backup_url = sbox.add_repo_path('backup-3')
+  svntest.actions.run_and_verify_svnadmin(None, expected_full, [],
+                                          'hotcopy',
+                                          sbox.repo_dir, backup_dir)
+  svntest.actions.run_and_verify_svnadmin(None, expected_incremental, [],
+                                          'hotcopy', '--incremental',
+                                          sbox.repo_dir, inc_backup_dir)
+
+
+@SkipUnless(svntest.main.is_fs_type_fsfs)
+def fsfs_hotcopy_progress_with_revprop_changes(sbox):
+  "incremental hotcopy progress with changed revprops"
+
+  # The progress output can be affected by the --fsfs-packing
+  # option, so skip the test if that is the case.
+  if svntest.main.options.fsfs_packing:
+    raise svntest.Skip
+
+  # Create an empty repository, commit several revisions and hotcopy it.
+  sbox.build(create_wc=False)
+  svntest.main.safe_rmtree(sbox.repo_dir, True)
+  svntest.main.create_repos(sbox.repo_dir)
+
+  for i in range(6):
+    svntest.actions.run_and_verify_svn(None, None, [], 'mkdir',
+                                       '-m', svntest.main.make_log_msg(),
+                                       sbox.repo_url + '/dir-%i' % i)
+  expected_output = [
+    "* Copied revision 0.\n",
+    "* Copied revision 1.\n",
+    "* Copied revision 2.\n",
+    "* Copied revision 3.\n",
+    "* Copied revision 4.\n",
+    "* Copied revision 5.\n",
+    "* Copied revision 6.\n",
+    ]
+
+  backup_dir, backup_url = sbox.add_repo_path('backup')
+  svntest.actions.run_and_verify_svnadmin(None, expected_output, [],
+                                          'hotcopy',
+                                          sbox.repo_dir, backup_dir)
+
+  # Amend a few log messages in the source, run the --incremental hotcopy.
+  # The progress output should only mention the corresponding revisions.
+  revprop_file = sbox.get_tempname()
+  svntest.main.file_write(revprop_file, "Modified log message.")
+
+  for i in [1, 3, 6]:
+    svntest.actions.run_and_verify_svnadmin(None, None, [],
+                                            'setrevprop',
+                                            sbox.repo_dir, '-r', i,
+                                            'svn:log', revprop_file)
+  expected_output = [
+    "* Copied revision 1.\n",
+    "* Copied revision 3.\n",
+    "* Copied revision 6.\n",
+    ]
+  svntest.actions.run_and_verify_svnadmin(None, expected_output, [],
+                                          'hotcopy', '--incremental',
+                                          sbox.repo_dir, backup_dir)
+
+
+@SkipUnless(svntest.main.is_fs_type_fsfs)
+def fsfs_hotcopy_progress_old(sbox):
+  "hotcopy --compatible-version=1.3 progress"
+
+  sbox.build(create_wc=False)
+  svntest.main.safe_rmtree(sbox.repo_dir, True)
+  svntest.main.create_repos(sbox.repo_dir, minor_version=3)
+
+  inc_backup_dir, inc_backup_url = sbox.add_repo_path('incremental-backup')
+
+  # Nothing really exciting for the empty repository.
+  expected_full = [
+    "* Copied revision 0.\n"
+    ]
+  expected_incremental = [
+    "* Copied revision 0.\n",
+    ]
+
+  backup_dir, backup_url = sbox.add_repo_path('backup-0')
+  svntest.actions.run_and_verify_svnadmin(None, expected_full, [],
+                                          'hotcopy',
+                                          sbox.repo_dir, backup_dir)
+  svntest.actions.run_and_verify_svnadmin(None, expected_incremental, [],
+                                          'hotcopy', '--incremental',
+                                          sbox.repo_dir, inc_backup_dir)
+
+  # Commit three revisions, hotcopy and check the progress output.
+  for i in range(3):
+    svntest.actions.run_and_verify_svn(None, None, [], 'mkdir',
+                                       '-m', svntest.main.make_log_msg(),
+                                       sbox.repo_url + '/dir-%i' % i)
+
+  expected_full = [
+    "* Copied revision 0.\n",
+    "* Copied revision 1.\n",
+    "* Copied revision 2.\n",
+    "* Copied revision 3.\n",
+    ]
+  expected_incremental = [
+    "* Copied revision 1.\n",
+    "* Copied revision 2.\n",
+    "* Copied revision 3.\n",
+    ]
+
+  backup_dir, backup_url = sbox.add_repo_path('backup-1')
+  svntest.actions.run_and_verify_svnadmin(None, expected_full, [],
+                                          'hotcopy',
+                                          sbox.repo_dir, backup_dir)
+  svntest.actions.run_and_verify_svnadmin(None, expected_incremental, [],
+                                          'hotcopy', '--incremental',
+                                          sbox.repo_dir, inc_backup_dir)
+
+
 ########################################################################
 # Run the tests
 
@@ -2695,6 +2929,9 @@ test_list = [ None,
               freeze_freeze,
               verify_metadata_only,
               verify_quickly,
+              fsfs_hotcopy_progress,
+              fsfs_hotcopy_progress_with_revprop_changes,
+              fsfs_hotcopy_progress_old,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/string-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/string-test.c?rev=1614348&r1=1614347&r2=1614348&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/string-test.c (original)
+++ subversion/branches/move-tracking-2/subversion/tests/libsvn_subr/string-test.c Tue Jul 29 13:46:03 2014
@@ -825,6 +825,27 @@ test_string_matching(apr_pool_t *pool)
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+test_string_skip_prefix(apr_pool_t *pool)
+{
+  SVN_TEST_STRING_ASSERT(svn_cstring_skip_prefix("12345", "12345"),
+                         "");
+  SVN_TEST_STRING_ASSERT(svn_cstring_skip_prefix("12345", "123"),
+                         "45");
+  SVN_TEST_STRING_ASSERT(svn_cstring_skip_prefix("12345", ""),
+                         "12345");
+  SVN_TEST_STRING_ASSERT(svn_cstring_skip_prefix("12345", "23"),
+                         NULL);
+  SVN_TEST_STRING_ASSERT(svn_cstring_skip_prefix("1", "12"),
+                         NULL);
+  SVN_TEST_STRING_ASSERT(svn_cstring_skip_prefix("", ""),
+                         "");
+  SVN_TEST_STRING_ASSERT(svn_cstring_skip_prefix("", "12"),
+                         NULL);
+
+  return SVN_NO_ERROR;
+}
+
 /*
    ====================================================================
    If you add a new test to this file, update this array.
@@ -899,6 +920,8 @@ static struct svn_test_descriptor_t test
                    "test string similarity scores"),
     SVN_TEST_PASS2(test_string_matching,
                    "test string matching"),
+    SVN_TEST_PASS2(test_string_skip_prefix,
+                   "test svn_cstring_skip_prefix()"),
     SVN_TEST_NULL
   };
 



Mime
View raw message