You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2015/03/30 20:38:41 UTC

svn commit: r1670172 - in /subversion/branches/move-tracking-2: ./ subversion/ subversion/include/ subversion/libsvn_fs/ subversion/libsvn_fs_base/ subversion/libsvn_fs_fs/ subversion/libsvn_fs_x/ subversion/libsvn_repos/ subversion/mod_dav_svn/ subver...

Author: julianfoad
Date: Mon Mar 30 18:38:40 2015
New Revision: 1670172

URL: http://svn.apache.org/r1670172
Log:
On the 'move-tracking-2' branch: catch up to trunk@1670169.

Added:
    subversion/branches/move-tracking-2/tools/dist/README.backport
      - copied, changed from r1670040, subversion/trunk/tools/dist/README.backport
    subversion/branches/move-tracking-2/tools/dist/backport/
      - copied from r1670040, subversion/trunk/tools/dist/backport/
    subversion/branches/move-tracking-2/tools/dist/backport_tests_pl.py   (contents, props changed)
      - copied, changed from r1670040, subversion/trunk/tools/dist/backport_tests_pl.py
    subversion/branches/move-tracking-2/tools/dist/backport_tests_py.py   (contents, props changed)
      - copied, changed from r1670040, subversion/trunk/tools/dist/backport_tests_py.py
    subversion/branches/move-tracking-2/tools/dist/detect-conflicting-backports.py   (contents, props changed)
      - copied, changed from r1670040, subversion/trunk/tools/dist/detect-conflicting-backports.py
    subversion/branches/move-tracking-2/tools/dist/merge-approved-backports.py   (contents, props changed)
      - copied, changed from r1670040, subversion/trunk/tools/dist/merge-approved-backports.py
Modified:
    subversion/branches/move-tracking-2/   (props changed)
    subversion/branches/move-tracking-2/subversion/   (props changed)
    subversion/branches/move-tracking-2/subversion/include/svn_fs.h
    subversion/branches/move-tracking-2/subversion/include/svn_ra.h
    subversion/branches/move-tracking-2/subversion/include/svn_repos.h
    subversion/branches/move-tracking-2/subversion/libsvn_fs/editor.c
    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/id.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_base/lock.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_base/tree.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/id.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/lock.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/pack.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/pack.h
    subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/transaction.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/tree.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/   (props changed)
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs_id.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/lock.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/pack.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/pack.h
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/tree.c
    subversion/branches/move-tracking-2/subversion/libsvn_repos/delta.c
    subversion/branches/move-tracking-2/subversion/libsvn_repos/reporter.c
    subversion/branches/move-tracking-2/subversion/mod_dav_svn/repos.c
    subversion/branches/move-tracking-2/subversion/mod_dav_svn/util.c
    subversion/branches/move-tracking-2/subversion/mod_dav_svn/version.c
    subversion/branches/move-tracking-2/subversion/svnadmin/svnadmin.c
    subversion/branches/move-tracking-2/subversion/tests/cmdline/log_tests.py
    subversion/branches/move-tracking-2/subversion/tests/libsvn_fs/fs-test.c
    subversion/branches/move-tracking-2/subversion/tests/libsvn_fs_fs/fs-fs-pack-test.c
    subversion/branches/move-tracking-2/tools/   (props changed)
    subversion/branches/move-tracking-2/tools/dist/backport.pl
    subversion/branches/move-tracking-2/tools/dist/backport/merger.py
    subversion/branches/move-tracking-2/tools/dist/backport/status.py
    subversion/branches/move-tracking-2/tools/dist/backport_tests.py   (contents, props changed)

Propchange: subversion/branches/move-tracking-2/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Mar 30 18:38:40 2015
@@ -88,4 +88,4 @@
 /subversion/branches/verify-at-commit:1462039-1462408
 /subversion/branches/verify-keep-going:1439280-1546110
 /subversion/branches/wc-collate-path:1402685-1480384
-/subversion/trunk:1606692-1668666
+/subversion/trunk:1606692-1670169

Propchange: subversion/branches/move-tracking-2/subversion/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Mar 30 18:38:40 2015
@@ -82,4 +82,4 @@
 /subversion/branches/verify-at-commit/subversion:1462039-1462408
 /subversion/branches/verify-keep-going/subversion:1439280-1546110
 /subversion/branches/wc-collate-path/subversion:1402685-1480384
-/subversion/trunk/subversion:1606692-1668666
+/subversion/trunk/subversion:1606692-1670169

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=1670172&r1=1670171&r2=1670172&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/svn_fs.h (original)
+++ subversion/branches/move-tracking-2/subversion/include/svn_fs.h Mon Mar 30 18:38:40 2015
@@ -888,27 +888,39 @@ svn_fs_access_add_lock_token(svn_fs_acce
  * @{
  */
 
-/** Defines the possible ways two arbitrary node-revisions may be related.
+/** Defines the possible ways two arbitrary (root, path)-pairs may be
+ * related.
  *
  * @since New in 1.9.
  */
 typedef enum svn_fs_node_relation_t
 {
-  /** The node-revisions are not related.
-   * Node-revisions from different repositories are always unrelated.
-   * #svn_fs_compare_ids would return the value -1 in this case.
+  /** The (root, path)-pairs are not related, i.e. none of the other cases
+   * apply.  If the roots refer to different @c svn_fs_t instances, then
+   * they are always considered unrelated - even if the underlying
+   * repository is the same.
    */
   svn_fs_node_unrelated = 0,
 
-  /** They are the same node-revision, i.e. there is no intervening change.
-   * However, due to lazy copying, there may be part of different parent
-   * copies.  #svn_fs_compare_ids would return the value 0 in this case.
+  /** No changes have been made between the (root, path)-pairs, i.e. they
+   * have the same (relative) nodes in their sub-trees, corresponding sub-
+   * tree nodes have the same contents as well as properties and report the
+   * same "created-path" and "created-rev" data.  This implies having a
+   * common ancestor.
+   *
+   * However, due to efficiency considerations, the FS implementation may
+   * report some combinations as merely having a common ancestor
+   * (@a svn_fs_node_common_ancestor) instead of actually being unchanged.
    */
-  svn_fs_node_same,
+  svn_fs_node_unchanged,
 
-  /** The node-revisions have a common ancestor (which may be one of them)
-   * but are not the same.
-   * #svn_fs_compare_ids would return the value 1 in this case.
+  /** The (root, path)-pairs have a common ancestor (which may be one of
+   * them) but there are changes between them, i.e. they don't fall into
+   * the @c svn_fs_node_unchanged category.
+   *
+   * Due to efficiency considerations, the FS implementation may falsely
+   * classify some combinations as merely having a common ancestor that
+   * are, in fact, unchanged (@a svn_fs_node_unchanged).
    */
   svn_fs_node_common_ancestor
 
@@ -2083,7 +2095,8 @@ svn_fs_dir_entries(apr_hash_t **entries_
  * #svn_fs_dir_entries for @a root and determine an optimized ordering
  * in which data access would most likely be efficient.  Set @a *ordered_p
  * to a newly allocated APR array of pointers to these #svn_fs_dirent_t
- * structures.  Allocate the array (but not its contents) in @a pool.
+ * structures.  Allocate the array (but not its contents) in @a result_pool
+ * and use @a scratch_pool for temporaries.
  *
  * @since New in 1.9.
  */
@@ -2091,7 +2104,8 @@ svn_error_t *
 svn_fs_dir_optimal_order(apr_array_header_t **ordered_p,
                          svn_fs_root_t *root,
                          apr_hash_t *entries,
-                         apr_pool_t *pool);
+                         apr_pool_t *result_pool,
+                         apr_pool_t *scratch_pool);
 
 /** Create a new directory named @a path in @a root.  The new directory has
  * no entries, and no properties.  @a root must be the root of a transaction,
@@ -2635,8 +2649,8 @@ svn_fs_set_uuid(svn_fs_t *fs,
  */
 typedef struct svn_fs_lock_target_t svn_fs_lock_target_t;
 
-/** Create an <tt>svn_fs_lock_target_t</tt> allocated in @a pool. @a
- * token can be NULL and @a current_rev can be SVN_INVALID_REVNUM.
+/** Create an <tt>svn_fs_lock_target_t</tt> allocated in @a result_pool.
+ * @a token can be NULL and @a current_rev can be SVN_INVALID_REVNUM.
  *
  * The @a token is not duplicated and so must have a lifetime at least as
  * long as the returned target object.
@@ -2645,7 +2659,7 @@ typedef struct svn_fs_lock_target_t svn_
  */
 svn_fs_lock_target_t *svn_fs_lock_target_create(const char *token,
                                                 svn_revnum_t current_rev,
-                                                apr_pool_t *pool);
+                                                apr_pool_t *result_pool);
 
 /** Update @a target changing the token to @a token, @a token can be NULL.
  *
@@ -2665,7 +2679,12 @@ void svn_fs_lock_target_set_token(svn_fs
  * returns, use svn_error_dup() to preserve the error.
  *
  * If the callback returns an error no further callbacks will be made
- * and svn_fs_lock_many/svn_fs_unlock_many will return an error.
+ * and svn_fs_lock_many/svn_fs_unlock_many will return an error.  The
+ * caller cannot rely on any particular order for these callbacks and
+ * cannot rely on interrupting the underlying operation by returning
+ * an error.  Returning an error stops the callbacks but any locks
+ * that would have been reported in further callbacks may, or may not,
+ * still be created/released.
  *
  * @since New in 1.9.
  */
@@ -2673,7 +2692,7 @@ typedef svn_error_t *(*svn_fs_lock_callb
                                                const char *path,
                                                const svn_lock_t *lock,
                                                svn_error_t *fs_err,
-                                               apr_pool_t *pool);
+                                               apr_pool_t *scratch_pool);
 
 /** Lock the paths in @a lock_targets in @a fs.
  *
@@ -2713,7 +2732,8 @@ typedef svn_error_t *(*svn_fs_lock_callb
  *
  * For each path in @a lock_targets @a lock_callback will be invoked
  * passing @a lock_baton and the lock and error that apply to path.
- * @a lock_callback can be NULL in which case it is not called.
+ * @a lock_callback can be NULL in which case it is not called and any
+ * errors that would have been passed to the callback are not reported.
  *
  * The lock and path passed to @a lock_callback will be allocated in
  * @a result_pool.  Use @a scratch_pool for temporary allocations.
@@ -2787,7 +2807,8 @@ svn_fs_generate_lock_token(const char **
  * For each path in @a unlock_targets @a lock_callback will be invoked
  * passing @a lock_baton and error that apply to path.  The @a lock
  * passed to the callback will be NULL.  @a lock_callback can be NULL
- * in which case it is not called.
+ * in which case it is not called and any errors that would have been
+ * passed to the callback are not reported.
  *
  * The path passed to lock_callback will be allocated in @a result_pool.
  * Use @a scratch_pool for temporary allocations.

Modified: subversion/branches/move-tracking-2/subversion/include/svn_ra.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/include/svn_ra.h?rev=1670172&r1=1670171&r2=1670172&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/svn_ra.h (original)
+++ subversion/branches/move-tracking-2/subversion/include/svn_ra.h Mon Mar 30 18:38:40 2015
@@ -1551,7 +1551,7 @@ svn_ra_do_diff(svn_ra_session_t *session
  * revisions in which at least one of @a paths was changed (i.e., if
  * file, text or props changed; if dir, props changed or an entry
  * was added or deleted).  Each path is an <tt>const char *</tt>, relative
- * to the @a session's common parent.
+ * to the repository root of @a session.
  *
  * If @a limit is greater than zero only invoke @a receiver on the first
  * @a limit logs.

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=1670172&r1=1670171&r2=1670172&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/svn_repos.h (original)
+++ subversion/branches/move-tracking-2/subversion/include/svn_repos.h Mon Mar 30 18:38:40 2015
@@ -2265,10 +2265,12 @@ svn_repos_fs_begin_txn_for_update(svn_fs
  * The pre-lock is run for every path in @a targets. Those targets for
  * which the pre-lock is successful are passed to svn_fs_lock_many and
  * the post-lock is run for those that are successfully locked.
+ * Pre-lock hook errors are passed to @a lock_callback.
  *
  * For each path in @a targets @a lock_callback will be invoked
  * passing @a lock_baton and the lock and error that apply to path.
- * @a lock_callback can be NULL in which case it is not called.
+ * @a lock_callback can be NULL in which case it is not called and any
+ * errors that would have been passed to the callback are not reported.
  *
  * If an error occurs when running the post-lock hook the error is
  * returned wrapped with #SVN_ERR_REPOS_POST_LOCK_HOOK_FAILED.  If the
@@ -2320,12 +2322,14 @@ svn_repos_fs_lock(svn_lock_t **lock,
  * The pre-unlock hook is run for every path in @a targets. Those
  * targets for which the pre-unlock is successful are passed to
  * svn_fs_unlock_many and the post-unlock is run for those that are
- * successfully unlocked.
+ * successfully unlocked. Pre-unlock hook errors are passed to @a
+ * lock_callback.
  *
  * For each path in @a targets @a lock_callback will be invoked
  * passing @a lock_baton and error that apply to path.  The lock
  * passed to the callback will be NULL.  @a lock_callback can be NULL
- * in which case it is not called.
+ * in which case it is not called and any errors that would have been
+ * passed to the callback are not reported.
  *
  * If an error occurs when running the post-unlock hook, return the
  * original error wrapped with #SVN_ERR_REPOS_POST_UNLOCK_HOOK_FAILED.

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs/editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs/editor.c?rev=1670172&r1=1670171&r2=1670172&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs/editor.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs/editor.c Mon Mar 30 18:38:40 2015
@@ -249,7 +249,7 @@ can_modify(svn_fs_root_t *txn_root,
       svn_fs_close_root(rev_root);
 
       /* Has the target node changed in the future?  */
-      if (relation != svn_fs_node_same)
+      if (relation != svn_fs_node_unchanged)
         {
           /* Restarting the commit will base the txn on the future/new
              revision, allowing the modification at REVISION.  */

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=1670172&r1=1670171&r2=1670172&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 Mon Mar 30 18:38:40 2015
@@ -1321,10 +1321,13 @@ svn_error_t *
 svn_fs_dir_optimal_order(apr_array_header_t **ordered_p,
                          svn_fs_root_t *root,
                          apr_hash_t *entries,
-                         apr_pool_t *pool)
+                         apr_pool_t *result_pool,
+                         apr_pool_t *scratch_pool)
 {
   return svn_error_trace(root->vtable->dir_optimal_order(ordered_p, root,
-                                                         entries, pool));
+                                                         entries,
+                                                         result_pool,
+                                                         scratch_pool));
 }
 
 svn_error_t *
@@ -1759,9 +1762,10 @@ svn_fs_generate_lock_token(const char **
 svn_fs_lock_target_t *
 svn_fs_lock_target_create(const char *token,
                           svn_revnum_t current_rev,
-                          apr_pool_t *pool)
+                          apr_pool_t *result_pool)
 {
-  svn_fs_lock_target_t *target = apr_palloc(pool, sizeof(svn_fs_lock_target_t));
+  svn_fs_lock_target_t *target = apr_palloc(result_pool,
+                                            sizeof(svn_fs_lock_target_t));
 
   target->token = token;
   target->current_rev = current_rev;
@@ -1899,7 +1903,7 @@ svn_fs_compare_ids(const svn_fs_id_t *a,
 {
   switch (a->vtable->compare(a, b))
     {
-    case svn_fs_node_same:
+    case svn_fs_node_unchanged:
       return 0;
     case svn_fs_node_common_ancestor:
       return 1;

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=1670172&r1=1670171&r2=1670172&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 Mon Mar 30 18:38:40 2015
@@ -361,7 +361,8 @@ typedef struct root_vtable_t
   svn_error_t *(*dir_optimal_order)(apr_array_header_t **ordered_p,
                                     svn_fs_root_t *root,
                                     apr_hash_t *entries,
-                                    apr_pool_t *pool);
+                                    apr_pool_t *result_pool,
+                                    apr_pool_t *scratch_pool);
   svn_error_t *(*make_dir)(svn_fs_root_t *root, const char *path,
                            apr_pool_t *pool);
 

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_base/id.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_base/id.c?rev=1670172&r1=1670171&r2=1670172&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_base/id.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_base/id.c Mon Mar 30 18:38:40 2015
@@ -113,7 +113,7 @@ svn_fs_base__id_compare(const svn_fs_id_
                         const svn_fs_id_t *b)
 {
   if (svn_fs_base__id_eq(a, b))
-    return svn_fs_node_same;
+    return svn_fs_node_unchanged;
   return (svn_fs_base__id_check_related(a, b) ? svn_fs_node_common_ancestor
                                               : svn_fs_node_unrelated);
 }

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_base/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_base/lock.c?rev=1670172&r1=1670171&r2=1670172&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_base/lock.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_base/lock.c Mon Mar 30 18:38:40 2015
@@ -243,6 +243,7 @@ svn_fs_base__lock(svn_fs_t *fs,
   apr_hash_index_t *hi;
   svn_error_t *cb_err = SVN_NO_ERROR;
   svn_revnum_t youngest_rev = SVN_INVALID_REVNUM;
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
 
   SVN_ERR(svn_fs__check_fs(fs, TRUE));
   SVN_ERR(svn_fs_base__youngest_rev(&youngest_rev, fs, scratch_pool));
@@ -255,6 +256,7 @@ svn_fs_base__lock(svn_fs_t *fs,
       svn_lock_t *lock;
       svn_error_t *err = NULL;
 
+      svn_pool_clear(iterpool);
       args.lock_p = &lock;
       args.path = svn_fs__canonicalize_abspath(path, result_pool);
       args.token = target->token;
@@ -275,11 +277,12 @@ svn_fs_base__lock(svn_fs_t *fs,
 
       if (!err)
         err = svn_fs_base__retry_txn(fs, txn_body_lock, &args, TRUE,
-                                     scratch_pool);
+                                     iterpool);
       if (!cb_err && lock_callback)
-        cb_err = lock_callback(lock_baton, args.path, lock, err, scratch_pool);
+        cb_err = lock_callback(lock_baton, args.path, lock, err, iterpool);
       svn_error_clear(err);
     }
+  svn_pool_destroy(iterpool);
 
   return svn_error_trace(cb_err);
 }
@@ -368,6 +371,7 @@ svn_fs_base__unlock(svn_fs_t *fs,
 {
   apr_hash_index_t *hi;
   svn_error_t *cb_err = SVN_NO_ERROR;
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
 
   SVN_ERR(svn_fs__check_fs(fs, TRUE));
 
@@ -378,16 +382,18 @@ svn_fs_base__unlock(svn_fs_t *fs,
       const char *token = apr_hash_this_val(hi);
       svn_error_t *err;
 
+      svn_pool_clear(iterpool);
       args.path = svn_fs__canonicalize_abspath(path, result_pool);
       args.token = token;
       args.break_lock = break_lock;
 
       err = svn_fs_base__retry_txn(fs, txn_body_unlock, &args, TRUE,
-                                   scratch_pool);
+                                   iterpool);
       if (!cb_err && lock_callback)
-        cb_err = lock_callback(lock_baton, path, NULL, err, scratch_pool);
+        cb_err = lock_callback(lock_baton, path, NULL, err, iterpool);
       svn_error_clear(err);
     }
+  svn_pool_destroy(iterpool);
 
   return svn_error_trace(cb_err);
 }

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_base/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_base/tree.c?rev=1670172&r1=1670171&r2=1670172&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_base/tree.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_base/tree.c Mon Mar 30 18:38:40 2015
@@ -1608,13 +1608,15 @@ static svn_error_t *
 base_dir_optimal_order(apr_array_header_t **ordered_p,
                        svn_fs_root_t *root,
                        apr_hash_t *entries,
-                       apr_pool_t *pool)
+                       apr_pool_t *result_pool,
+                       apr_pool_t *scratch_pool)
 {
   /* 1:1 copy of entries with no differnce in ordering */
   apr_hash_index_t *hi;
-  apr_array_header_t *result = apr_array_make(pool, apr_hash_count(entries),
-                                              sizeof(svn_fs_dirent_t *));
-  for (hi = apr_hash_first(pool, entries); hi; hi = apr_hash_next(hi))
+  apr_array_header_t *result
+    = apr_array_make(result_pool, apr_hash_count(entries),
+                     sizeof(svn_fs_dirent_t *));
+  for (hi = apr_hash_first(scratch_pool, entries); hi; hi = apr_hash_next(hi))
     APR_ARRAY_PUSH(result, svn_fs_dirent_t *) = apr_hash_this_val(hi);
 
   *ordered_p = result;
@@ -3164,7 +3166,8 @@ txn_body_copy(void *baton,
   if ((to_parent_path->node)
       && (svn_fs_base__id_compare(svn_fs_base__dag_get_id(from_node),
                                   svn_fs_base__dag_get_id
-                                  (to_parent_path->node)) == svn_fs_node_same))
+                                  (to_parent_path->node))
+          == svn_fs_node_unchanged))
     return SVN_NO_ERROR;
 
   if (! from_root->is_txn_root)

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/id.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/id.c?rev=1670172&r1=1670171&r2=1670172&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/id.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/id.c Mon Mar 30 18:38:40 2015
@@ -392,7 +392,7 @@ svn_fs_fs__id_compare(const svn_fs_id_t
                       const svn_fs_id_t *b)
 {
   if (svn_fs_fs__id_eq(a, b))
-    return svn_fs_node_same;
+    return svn_fs_node_unchanged;
   return (svn_fs_fs__id_check_related(a, b) ? svn_fs_node_common_ancestor
                                             : svn_fs_node_unrelated);
 }

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/lock.c?rev=1670172&r1=1670171&r2=1670172&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/lock.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/lock.c Mon Mar 30 18:38:40 2015
@@ -1109,6 +1109,7 @@ svn_fs_fs__lock(svn_fs_t *fs,
   apr_array_header_t *sorted_targets;
   apr_hash_t *canonical_targets = apr_hash_make(scratch_pool);
   apr_hash_index_t *hi;
+  apr_pool_t *iterpool;
   svn_error_t *err, *cb_err = SVN_NO_ERROR;
   int i;
 
@@ -1149,11 +1150,13 @@ svn_fs_fs__lock(svn_fs_t *fs,
   lb.steal_lock = steal_lock;
   lb.result_pool = result_pool;
 
-  err = svn_fs_fs__with_write_lock(fs, lock_body, &lb, scratch_pool);
+  iterpool = svn_pool_create(scratch_pool);
+  err = svn_fs_fs__with_write_lock(fs, lock_body, &lb, iterpool);
   for (i = 0; i < lb.infos->nelts; ++i)
     {
       struct lock_info_t *info = &APR_ARRAY_IDX(lb.infos, i,
                                                 struct lock_info_t);
+      svn_pool_clear(iterpool);
       if (!cb_err && lock_callback)
         {
           if (!info->lock && !info->fs_err)
@@ -1162,10 +1165,11 @@ svn_fs_fs__lock(svn_fs_t *fs,
                                              info->path);
 
           cb_err = lock_callback(lock_baton, info->path, info->lock,
-                                 info->fs_err, scratch_pool);
+                                 info->fs_err, iterpool);
         }
       svn_error_clear(info->fs_err);
     }
+  svn_pool_destroy(iterpool);
 
   if (err && cb_err)
     svn_error_compose(err, cb_err);
@@ -1205,6 +1209,7 @@ svn_fs_fs__unlock(svn_fs_t *fs,
   apr_array_header_t *sorted_targets;
   apr_hash_t *canonical_targets = apr_hash_make(scratch_pool);
   apr_hash_index_t *hi;
+  apr_pool_t *iterpool;
   svn_error_t *err, *cb_err = SVN_NO_ERROR;
   int i;
 
@@ -1239,11 +1244,13 @@ svn_fs_fs__unlock(svn_fs_t *fs,
   ub.break_lock = break_lock;
   ub.result_pool = result_pool;
 
-  err = svn_fs_fs__with_write_lock(fs, unlock_body, &ub, scratch_pool);
+  iterpool = svn_pool_create(scratch_pool);
+  err = svn_fs_fs__with_write_lock(fs, unlock_body, &ub, iterpool);
   for (i = 0; i < ub.infos->nelts; ++i)
     {
       struct unlock_info_t *info = &APR_ARRAY_IDX(ub.infos, i,
                                                   struct unlock_info_t);
+      svn_pool_clear(iterpool);
       if (!cb_err && lock_callback)
         {
           if (!info->done && !info->fs_err)
@@ -1251,10 +1258,11 @@ svn_fs_fs__unlock(svn_fs_t *fs,
                                              0, _("Failed to unlock '%s'"),
                                              info->path);
           cb_err = lock_callback(lock_baton, info->path, NULL, info->fs_err,
-                                 scratch_pool);
+                                 iterpool);
         }
       svn_error_clear(info->fs_err);
     }
+  svn_pool_destroy(iterpool);
 
   if (err && cb_err)
     svn_error_compose(err, cb_err);

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/pack.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/pack.c?rev=1670172&r1=1670171&r2=1670172&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/pack.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/pack.c Mon Mar 30 18:38:40 2015
@@ -643,17 +643,18 @@ compare_dir_entries_format6(const svn_so
 apr_array_header_t *
 svn_fs_fs__order_dir_entries(svn_fs_t *fs,
                              apr_hash_t *directory,
-                             apr_pool_t *pool)
+                             apr_pool_t *result_pool,
+                             apr_pool_t *scratch_pool)
 {
   apr_array_header_t *ordered
     = svn_sort__hash(directory,
                      svn_fs_fs__use_log_addressing(fs)
                        ? compare_dir_entries_format7
                        : compare_dir_entries_format6,
-                     pool);
+                     scratch_pool);
 
   apr_array_header_t *result
-    = apr_array_make(pool, ordered->nelts, sizeof(svn_fs_dirent_t *));
+    = apr_array_make(result_pool, ordered->nelts, sizeof(svn_fs_dirent_t *));
 
   int i;
   for (i = 0; i < ordered->nelts; ++i)

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/pack.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/pack.h?rev=1670172&r1=1670171&r2=1670172&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/pack.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/pack.h Mon Mar 30 18:38:40 2015
@@ -51,13 +51,14 @@ svn_fs_fs__get_packed_offset(apr_off_t *
                              apr_pool_t *pool);
 
 /* Return the svn_dir_entry_t* objects of DIRECTORY in an APR array
- * allocated in POOL with entries added in storage (on-disk) order.
- * FS format will be used to pick the optimal ordering strategy.
+ * allocated in RESULT_POOL with entries added in storage (on-disk) order.
+ * FS' format will be used to pick the optimal ordering strategy.  Use
+ * SCRATCH_POOL for temporary allocations.
  */
 apr_array_header_t *
 svn_fs_fs__order_dir_entries(svn_fs_t *fs,
                              apr_hash_t *directory,
-                             apr_pool_t *pool);
-
+                             apr_pool_t *result_pool,
+                             apr_pool_t *scratch_pool);
 
 #endif

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/transaction.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/transaction.c?rev=1670172&r1=1670171&r2=1670172&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/transaction.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/transaction.c Mon Mar 30 18:38:40 2015
@@ -2214,10 +2214,11 @@ get_shared_rep(representation_t **old_re
     return SVN_NO_ERROR;
 
   /* We don't want 0-length PLAIN representations to replace non-0-length
-     ones (see issue #4554).  Also, this doubles as a simple guard against
-     general rep-cache induced corruption. */
+     ones (see issue #4554).  Take into account that EXPANDED_SIZE may be
+     0 in which case we have to check the on-disk SIZE.  Also, this doubles
+     as a simple guard against general rep-cache induced corruption. */
   if (   ((*old_rep)->expanded_size != rep->expanded_size)
-      || ((*old_rep)->size != rep->size))
+      || ((rep->expanded_size == 0) && ((*old_rep)->size != rep->size)))
     {
       *old_rep = NULL;
     }

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/tree.c?rev=1670172&r1=1670171&r2=1670172&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/tree.c Mon Mar 30 18:38:40 2015
@@ -1357,7 +1357,7 @@ fs_node_relation(svn_fs_node_relation_t
       *relation = (   (root_a->rev == root_b->rev)
                    && (root_a->is_txn_root == root_b->is_txn_root)
                    && !different_txn)
-                ? svn_fs_node_same
+                ? svn_fs_node_unchanged
                 : svn_fs_node_common_ancestor;
       return SVN_NO_ERROR;
     }
@@ -1391,7 +1391,7 @@ fs_node_relation(svn_fs_node_relation_t
 
   /* The noderevs are actually related.  Are they the same? */
   if (svn_fs_fs__id_eq(id_a, id_b))
-    *relation = svn_fs_node_same;
+    *relation = svn_fs_node_unchanged;
   else
     *relation = svn_fs_node_common_ancestor;
 
@@ -2392,9 +2392,11 @@ static svn_error_t *
 fs_dir_optimal_order(apr_array_header_t **ordered_p,
                      svn_fs_root_t *root,
                      apr_hash_t *entries,
-                     apr_pool_t *pool)
+                     apr_pool_t *result_pool,
+                     apr_pool_t *scratch_pool)
 {
-  *ordered_p = svn_fs_fs__order_dir_entries(root->fs, entries, pool);
+  *ordered_p = svn_fs_fs__order_dir_entries(root->fs, entries, result_pool,
+                                            scratch_pool);
 
   return SVN_NO_ERROR;
 }

Propchange: subversion/branches/move-tracking-2/subversion/libsvn_fs_x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Mar 30 18:38:40 2015
@@ -90,4 +90,4 @@
 /subversion/branches/verify-keep-going/subversion/libsvn_fs_x:1439280-1492639,1546002-1546110
 /subversion/branches/wc-collate-path/subversion/libsvn_fs_x:1402685-1480384
 /subversion/trunk/subversion/libsvn_fs_fs:1415133-1596500,1596567,1597414,1597989,1598273,1599140,1600872,1601633,1603485-1603487,1603499,1603605,1604128,1604188,1604413-1604414,1604416-1604417,1604421,1604442,1604700,1604717,1604720,1604726,1604755,1604794,1604802,1604824,1604836,1604844,1604902-1604903,1604911,1604925,1604933,1604947,1605059-1605060,1605064-1605065,1605068,1605071-1605073,1605075,1605123,1605188-1605189,1605191,1605197,1605444,1605633,1606132,1606142,1606144,1606514,1606526,1606528,1606551,1606554,1606564,1606598-1606599,1606656,1606658,1606662,1606744,1606840,1607085,1607572,1612407,1612810,1613339,1613872,1614611,1615348,1615351-1615352,1615356,1616338-1616339,1616613,1617586,1617688,1618138,1618151,1618153,1618226,1618641,1618653,1618662,1619068,1619358,1619413,1619769,1619774,1620602,1620909,1620912,1620928,1620930,1621275,1621635,1622931,1622937,1622942,1622946,1622959-1622960,1622963,1622987,1623007,1623368,1623373,1623377,1623379,1623381,1623398,1623402,162
 4011,1624265,1624512,1626246,1626871,1626873,1626886,1627497-1627498,1627502,1627947-1627949,1627966,1628083,1628093,1628158-1628159,1628161,1628392-1628393,1628415,1628427,1628676,1628738,1628762,1628764,1629854-1629855,1629857,1629865,1629873,1629875,1629879,1630067,1630070,1631049-1631051,1631075,1631115,1631171,1631180,1631185-1631186,1631196-1631197,1631239-1631240,1631548,1631550,1631563,1631567,1631588,1631598,1632646,1632776,1632849,1632851-1632853,1632856-1632857,1632868,1632908,1632926,1633232,1633617-1633618,1634872,1634875,1634879-1634880,1634920,1636478,1636483,1636629,1636644,1637184,1637186,1637330,1637358,1637363,1637393,1639319,1639322,1639335,1639348,1639352,1639355,1639358,1639414,1639419,1639426,1639430,1639436,1639440,1639549,1640061-1640062,1640197,1640915,1640966,1641013,1643139,1643233,1645567,1646021,1646712,1646716,1647537,1647540-1647541,1647820,1647905,1648230,1648238,1648241-1648243,1648253,1648272,1648532,1648537-1648539,1648542,1648591,1648612,1653608,
 1658482
-/subversion/trunk/subversion/libsvn_fs_x:1414756-1509914,1606692-1668666
+/subversion/trunk/subversion/libsvn_fs_x:1414756-1509914,1606692-1670169

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs_id.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs_id.c?rev=1670172&r1=1670171&r2=1670172&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs_id.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs_id.c Mon Mar 30 18:38:40 2015
@@ -217,7 +217,7 @@ id_compare(const svn_fs_id_t *a,
 
   /* Quick check: same IDs? */
   if (svn_fs_x__id_eq(&id_a->noderev_id, &id_b->noderev_id))
-    return svn_fs_node_same;
+    return svn_fs_node_unchanged;
 
   /* Fetch the nodesrevs, compare the IDs of the nodes they belong to and
      clean up any temporaries.  If we can't find one of the noderevs, don't

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_x/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_x/lock.c?rev=1670172&r1=1670171&r2=1670172&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_x/lock.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_x/lock.c Mon Mar 30 18:38:40 2015
@@ -1239,6 +1239,7 @@ svn_fs_x__lock(svn_fs_t *fs,
   apr_array_header_t *sorted_targets;
   apr_hash_t *canonical_targets = apr_hash_make(scratch_pool);
   apr_hash_index_t *hi;
+  apr_pool_t *iterpool;
   svn_error_t *err, *cb_err = SVN_NO_ERROR;
   int i;
 
@@ -1277,11 +1278,13 @@ svn_fs_x__lock(svn_fs_t *fs,
   lb.steal_lock = steal_lock;
   lb.result_pool = result_pool;
 
-  err = svn_fs_x__with_write_lock(fs, lock_body, &lb, scratch_pool);
+  iterpool = svn_pool_create(scratch_pool);
+  err = svn_fs_x__with_write_lock(fs, lock_body, &lb, iterpool);
   for (i = 0; i < lb.infos->nelts; ++i)
     {
       struct lock_info_t *info = &APR_ARRAY_IDX(lb.infos, i,
                                                 struct lock_info_t);
+      svn_pool_clear(iterpool);
       if (!cb_err && lock_callback)
         {
           if (!info->lock && !info->fs_err)
@@ -1290,10 +1293,11 @@ svn_fs_x__lock(svn_fs_t *fs,
                                              info->path);
 
           cb_err = lock_callback(lock_baton, info->path, info->lock,
-                                 info->fs_err, scratch_pool);
+                                 info->fs_err, iterpool);
         }
       svn_error_clear(info->fs_err);
     }
+  svn_pool_destroy(iterpool);
 
   if (err && cb_err)
     svn_error_compose(err, cb_err);
@@ -1333,6 +1337,7 @@ svn_fs_x__unlock(svn_fs_t *fs,
   apr_array_header_t *sorted_targets;
   apr_hash_t *canonical_targets = apr_hash_make(scratch_pool);
   apr_hash_index_t *hi;
+  apr_pool_t *iterpool;
   svn_error_t *err, *cb_err = SVN_NO_ERROR;
   int i;
 
@@ -1365,10 +1370,12 @@ svn_fs_x__unlock(svn_fs_t *fs,
   ub.break_lock = break_lock;
   ub.result_pool = result_pool;
 
-  err = svn_fs_x__with_write_lock(fs, unlock_body, &ub, scratch_pool);
+  iterpool = svn_pool_create(scratch_pool);
+  err = svn_fs_x__with_write_lock(fs, unlock_body, &ub, iterpool);
   for (i = 0; i < ub.infos->nelts; ++i)
     {
       unlock_info_t *info = &APR_ARRAY_IDX(ub.infos, i, unlock_info_t);
+      svn_pool_clear(iterpool);
       if (!cb_err && lock_callback)
         {
           if (!info->done && !info->fs_err)
@@ -1376,10 +1383,11 @@ svn_fs_x__unlock(svn_fs_t *fs,
                                              0, _("Failed to unlock '%s'"),
                                              info->path);
           cb_err = lock_callback(lock_baton, info->path, NULL, info->fs_err,
-                                 scratch_pool);
+                                 iterpool);
         }
       svn_error_clear(info->fs_err);
     }
+  svn_pool_destroy(iterpool);
 
   if (err && cb_err)
     svn_error_compose(err, cb_err);

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_x/pack.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_x/pack.c?rev=1670172&r1=1670171&r2=1670172&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_x/pack.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_x/pack.c Mon Mar 30 18:38:40 2015
@@ -625,13 +625,14 @@ compare_dir_entries(const svn_sort__item
 apr_array_header_t *
 svn_fs_x__order_dir_entries(svn_fs_t *fs,
                             apr_hash_t *directory,
-                            apr_pool_t *pool)
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool)
 {
   apr_array_header_t *ordered
-    = svn_sort__hash(directory, compare_dir_entries, pool);
+    = svn_sort__hash(directory, compare_dir_entries, scratch_pool);
 
   apr_array_header_t *result
-    = apr_array_make(pool, ordered->nelts, sizeof(svn_fs_dirent_t *));
+    = apr_array_make(result_pool, ordered->nelts, sizeof(svn_fs_dirent_t *));
 
   int i;
   for (i = 0; i < ordered->nelts; ++i)

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_x/pack.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_x/pack.h?rev=1670172&r1=1670171&r2=1670172&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_x/pack.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_x/pack.h Mon Mar 30 18:38:40 2015
@@ -51,13 +51,15 @@ svn_fs_x__get_packed_offset(apr_off_t *r
                             apr_pool_t *scratch_pool);
 
 /* Return the svn_dir_entry_t* objects of DIRECTORY in an APR array
- * allocated in POOL with entries added in storage (on-disk) order.
- * FS format will be used to pick the optimal ordering strategy.
+ * allocated in RESULT_POOL with entries added in storage (on-disk) order.
+ * FS' format will be used to pick the optimal ordering strategy.  Use
+ * SCRATCH_POOL for temporary allocations.
  */
 apr_array_header_t *
 svn_fs_x__order_dir_entries(svn_fs_t *fs,
                             apr_hash_t *directory,
-                            apr_pool_t *pool);
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool);
 
 
 #endif

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_x/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_x/tree.c?rev=1670172&r1=1670171&r2=1670172&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_x/tree.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_x/tree.c Mon Mar 30 18:38:40 2015
@@ -1354,7 +1354,7 @@ x_node_relation(svn_fs_node_relation_t *
       *relation = (   (root_a->rev == root_b->rev)
                    && (root_a->is_txn_root == root_b->is_txn_root)
                    && !different_txn)
-                ? svn_fs_node_same
+                ? svn_fs_node_unchanged
                 : svn_fs_node_common_ancestor;
       return SVN_NO_ERROR;
     }
@@ -1372,7 +1372,7 @@ x_node_relation(svn_fs_node_relation_t *
   /* In FSX, even in-txn IDs are globally unique.
    * So, we can simply compare them. */
   if (svn_fs_x__id_eq(&noderev_id_a, &noderev_id_b))
-    *relation = svn_fs_node_same;
+    *relation = svn_fs_node_unchanged;
   else if (svn_fs_x__id_eq(&node_id_a, &node_id_b))
     *relation = svn_fs_node_common_ancestor;
   else
@@ -2411,9 +2411,11 @@ static svn_error_t *
 x_dir_optimal_order(apr_array_header_t **ordered_p,
                     svn_fs_root_t *root,
                     apr_hash_t *entries,
-                    apr_pool_t *pool)
+                    apr_pool_t *result_pool,
+                    apr_pool_t *scratch_pool)
 {
-  *ordered_p = svn_fs_x__order_dir_entries(root->fs, entries, pool);
+  *ordered_p = svn_fs_x__order_dir_entries(root->fs, entries, result_pool,
+                                           scratch_pool);
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/move-tracking-2/subversion/libsvn_repos/delta.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_repos/delta.c?rev=1670172&r1=1670171&r2=1670172&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_repos/delta.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_repos/delta.c Mon Mar 30 18:38:40 2015
@@ -321,7 +321,7 @@ svn_repos_dir_delta2(svn_fs_root_t *src_
   SVN_ERR(svn_fs_node_relation(&relation, tgt_root, tgt_fullpath,
                                src_root, src_fullpath, pool));
 
-  if (relation == svn_fs_node_same)
+  if (relation == svn_fs_node_unchanged)
     {
       /* They are the same node!  No-op (you gotta love those). */
       goto cleanup;

Modified: subversion/branches/move-tracking-2/subversion/libsvn_repos/reporter.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_repos/reporter.c?rev=1670172&r1=1670171&r2=1670172&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_repos/reporter.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_repos/reporter.c Mon Mar 30 18:38:40 2015
@@ -1282,7 +1282,7 @@ delta_dirs(report_baton_t *b, svn_revnum
 
       /* Loop over the dirents in the target. */
       SVN_ERR(svn_fs_dir_optimal_order(&t_ordered_entries, b->t_root,
-                                       t_entries, subpool));
+                                       t_entries, subpool, iterpool));
       for (i = 0; i < t_ordered_entries->nelts; ++i)
         {
           const svn_fs_dirent_t *t_entry

Modified: subversion/branches/move-tracking-2/subversion/mod_dav_svn/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/mod_dav_svn/repos.c?rev=1670172&r1=1670171&r2=1670172&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/mod_dav_svn/repos.c (original)
+++ subversion/branches/move-tracking-2/subversion/mod_dav_svn/repos.c Mon Mar 30 18:38:40 2015
@@ -1948,7 +1948,7 @@ do_out_of_date_check(dav_resource_combin
                                       r->pool);
         }
 
-      if (node_relation != svn_fs_node_same)
+      if (node_relation != svn_fs_node_unchanged)
         {
           serr = svn_error_createf(SVN_ERR_RA_OUT_OF_DATE, NULL,
                                    "Directory '%s' is out of date",

Modified: subversion/branches/move-tracking-2/subversion/mod_dav_svn/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/mod_dav_svn/util.c?rev=1670172&r1=1670171&r2=1670172&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/mod_dav_svn/util.c (original)
+++ subversion/branches/move-tracking-2/subversion/mod_dav_svn/util.c Mon Mar 30 18:38:40 2015
@@ -217,7 +217,7 @@ dav_svn__get_safe_cr(svn_fs_root_t *root
       return revision;
     }
 
-  if (node_relation == svn_fs_node_same)
+  if (node_relation == svn_fs_node_unchanged)
     return history_rev;  /* the history rev is safe!  the same node
                             exists at the same path in both revisions. */
 

Modified: subversion/branches/move-tracking-2/subversion/mod_dav_svn/version.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/mod_dav_svn/version.c?rev=1670172&r1=1670171&r2=1670172&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/mod_dav_svn/version.c (original)
+++ subversion/branches/move-tracking-2/subversion/mod_dav_svn/version.c Mon Mar 30 18:38:40 2015
@@ -751,7 +751,7 @@ dav_svn__checkout(dav_resource *resource
                   svn_error_clear(serr);
                   return err;
                 }
-              if (node_relation != svn_fs_node_same)
+              if (node_relation != svn_fs_node_unchanged)
                 {
                   return dav_svn__new_error_svn
                     (resource->pool, HTTP_CONFLICT, SVN_ERR_FS_CONFLICT,

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=1670172&r1=1670171&r2=1670172&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnadmin/svnadmin.c (original)
+++ subversion/branches/move-tracking-2/subversion/svnadmin/svnadmin.c Mon Mar 30 18:38:40 2015
@@ -2510,6 +2510,7 @@ sub_main(int *exit_code, int argc, const
         SVN_ERR(svn_stringbuf_from_file2(&(opt_state.filedata),
                                              utf8_opt_arg, pool));
         dash_F_arg = TRUE;
+        break;
       case svnadmin__version:
         opt_state.version = TRUE;
         break;

Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/log_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/log_tests.py?rev=1670172&r1=1670171&r2=1670172&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/cmdline/log_tests.py (original)
+++ subversion/branches/move-tracking-2/subversion/tests/cmdline/log_tests.py Mon Mar 30 18:38:40 2015
@@ -2686,6 +2686,99 @@ def log_revision_move_copy(sbox):
                                      'log', '-v', '-q', sbox.wc_dir,
                                      '-c3')
 
+def log_on_deleted_deep(sbox):
+  "log on deleted deep path"
+
+  sbox.build()
+  sbox.simple_propset('k', 'v', 'A/B/E/alpha')
+  sbox.simple_commit() #r2
+  sbox.simple_propset('k', 'v', 'A/B/E/beta')
+  sbox.simple_commit() #r3
+
+  sbox.simple_update() # Or commit fails
+  sbox.simple_move('A/B', 'B')
+  sbox.simple_commit() #r4
+
+  expected_output = svntest.verify.RegexListOutput([
+     r'-+\n',
+     r'r1 .*\n',
+     r'-+\n',
+     r'r2 .*\n',
+     r'-+\n',
+     r'r2 .*\n',
+     r'-+\n',
+     r'r3 .*\n',
+     r'-+\n',
+  ])
+  # In deleted location
+  svntest.actions.run_and_verify_svn(expected_output, [],
+                                     'log', sbox.repo_url + '/A/B/E@3',
+                                     '-q', '-c', '1-2,2-3')
+
+  svntest.actions.run_and_verify_svn(expected_output, [],
+                                     'log', sbox.repo_url + '/A/B/E@3',
+                                     'alpha', 'beta',
+                                     '-q', '-c', '1-2,2-3')
+
+  # In new location
+  svntest.actions.run_and_verify_svn(expected_output, [],
+                                     'log', sbox.repo_url + '/B/E',
+                                     '-q', '-c', '1-2,2-3')
+
+  svntest.actions.run_and_verify_svn(expected_output, [],
+                                     'log', sbox.repo_url + '/B/E@4',
+                                     'alpha', 'beta',
+                                     '-q', '-c', '1-2,2-3')
+
+  expected_output = svntest.verify.RegexListOutput([
+     r'-+\n',
+     r'r1 .*\n',
+     r'-+\n',
+     r'r2 .*\n',
+     r'-+\n',
+  ])
+  # 2 ranges
+  svntest.actions.run_and_verify_svn(expected_output, [],
+                                     'log', sbox.repo_url + '/A/B/E@3',
+                                     'alpha',
+                                     '-q', '-c', '1,2')
+
+  svntest.actions.run_and_verify_svn(expected_output, [],
+                                     'log', sbox.repo_url + '/B/E',
+                                     'alpha',
+                                     '-q', '-c', '1,2')
+
+  svntest.actions.run_and_verify_svn(expected_output, [],
+                                     'log', sbox.repo_url + '/A/B/E@3',
+                                     '',
+                                     '-q', '-c', '1,2')
+
+  svntest.actions.run_and_verify_svn(expected_output, [],
+                                     'log', sbox.repo_url + '/B/E',
+                                     '',
+                                     '-q', '-c', '1,2')
+
+  # 1 range
+  svntest.actions.run_and_verify_svn(expected_output, [],
+                                     'log', sbox.repo_url + '/A/B/E@3',
+                                     'alpha',
+                                     '-q', '-c', '1-2')
+
+  svntest.actions.run_and_verify_svn(expected_output, [],
+                                     'log', sbox.repo_url + '/B/E',
+                                     'alpha',
+                                     '-q', '-c', '1-2')
+
+  svntest.actions.run_and_verify_svn(expected_output, [],
+                                     'log', sbox.repo_url + '/A/B/E@3',
+                                     '',
+                                     '-q', '-c', '1-2')
+
+  svntest.actions.run_and_verify_svn(expected_output, [],
+                                     'log', sbox.repo_url + '/B/E',
+                                     '',
+                                     '-q', '-c', '1-2')
+
 
 ########################################################################
 # Run the tests
@@ -2736,6 +2829,7 @@ test_list = [ None,
               mergeinfo_log,
               merge_sensitive_log_xml_reverse_merges,
               log_revision_move_copy,
+              log_on_deleted_deep,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_fs/fs-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_fs/fs-test.c?rev=1670172&r1=1670171&r2=1670172&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/libsvn_fs/fs-test.c (original)
+++ subversion/branches/move-tracking-2/subversion/tests/libsvn_fs/fs-test.c Mon Mar 30 18:38:40 2015
@@ -4268,7 +4268,7 @@ check_related(const svn_test_opts_t *opt
             if (i == j)
               {
                 /* Identical note. */
-                if (!related || relation != svn_fs_node_same)
+                if (!related || relation != svn_fs_node_unchanged)
                   {
                     return svn_error_createf
                       (SVN_ERR_TEST_FAILED, NULL,
@@ -4319,7 +4319,7 @@ check_related(const svn_test_opts_t *opt
                                          rev_root, path, subpool));
 
             /* They shall use the same noderevs */
-            if (relation != svn_fs_node_same)
+            if (relation != svn_fs_node_unchanged)
               {
                 return svn_error_createf
                   (SVN_ERR_TEST_FAILED, NULL,
@@ -4486,7 +4486,7 @@ check_txn_related(const svn_test_opts_t
             if (i == j)
               {
                 /* Identical noderev. */
-                if (!related || relation != svn_fs_node_same)
+                if (!related || relation != svn_fs_node_unchanged)
                   {
                     return svn_error_createf
                       (SVN_ERR_TEST_FAILED, NULL,
@@ -4525,7 +4525,7 @@ check_txn_related(const svn_test_opts_t
                                      root[0], "D", subpool));
 
         /* They shall use the same noderevs */
-        if (relation != svn_fs_node_same)
+        if (relation != svn_fs_node_unchanged)
           {
             return svn_error_createf
               (SVN_ERR_TEST_FAILED, NULL,
@@ -6524,7 +6524,7 @@ test_dir_optimal_order(const svn_test_op
 
   /* Call the API function we are interested in. */
   SVN_ERR(svn_fs_dir_entries(&unordered, root, "A", pool));
-  SVN_ERR(svn_fs_dir_optimal_order(&ordered, root, unordered, pool));
+  SVN_ERR(svn_fs_dir_optimal_order(&ordered, root, unordered, pool, pool));
 
   /* Verify that all entries are returned. */
   SVN_TEST_ASSERT(ordered->nelts == apr_hash_count(unordered));

Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_fs_fs/fs-fs-pack-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_fs_fs/fs-fs-pack-test.c?rev=1670172&r1=1670171&r2=1670172&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/tests/libsvn_fs_fs/fs-fs-pack-test.c (original)
+++ subversion/branches/move-tracking-2/subversion/tests/libsvn_fs_fs/fs-fs-pack-test.c Mon Mar 30 18:38:40 2015
@@ -1372,6 +1372,172 @@ plain_0_length(const svn_test_opts_t *op
 
 #undef REPO_NAME
 
+/* ------------------------------------------------------------------------ */
+
+#define REPO_NAME "test-repo-rep_sharing_effectiveness"
+
+static int
+count_substring(svn_stringbuf_t *string,
+                const char *needle)
+{
+  int count = 0;
+  apr_size_t len = strlen(needle);
+  apr_size_t pos;
+
+  for (pos = 0; pos + len <= string->len; ++pos)
+    if (memcmp(string->data + pos, needle, len) == 0)
+      ++count;
+
+  return count;
+}
+
+static svn_error_t *
+count_representations(int *count,
+                      svn_fs_t *fs,
+                      svn_revnum_t revision,
+                      apr_pool_t *pool)
+{
+  svn_stringbuf_t *rev_contents;
+  const char *rev_path = svn_fs_fs__path_rev_absolute(fs, revision, pool);
+  SVN_ERR(svn_stringbuf_from_file2(&rev_contents, rev_path, pool));
+
+  *count = count_substring(rev_contents, "PLAIN")
+         + count_substring(rev_contents, "DELTA");
+
+  return SVN_NO_ERROR;
+}
+
+/* Repeat string S many times to make it big enough for deltification etc.
+   to kick in. */
+static const char*
+multiply_string(const char *s,
+                apr_pool_t *pool)
+{
+  svn_stringbuf_t *temp = svn_stringbuf_create(s, pool);
+
+  int i;
+  for (i = 0; i < 7; ++i)
+    svn_stringbuf_insert(temp, temp->len, temp->data, temp->len);
+
+  return temp->data;
+}
+
+static svn_error_t *
+rep_sharing_effectiveness(const svn_test_opts_t *opts,
+                          apr_pool_t *pool)
+{
+  svn_fs_t *fs;
+  fs_fs_data_t *ffd;
+  svn_fs_txn_t *txn;
+  svn_fs_root_t *root;
+  svn_revnum_t rev;
+  const char *hello_str = multiply_string("Hello, ", pool);
+  const char *world_str = multiply_string("World!", pool);
+  const char *goodbye_str = multiply_string("Goodbye!", pool);
+
+  if (strcmp(opts->fs_type, "fsfs") != 0)
+    return svn_error_create(SVN_ERR_TEST_SKIPPED, NULL, NULL);
+
+  /* Create a repo that and explicitly enable rep sharing. */
+  SVN_ERR(svn_test__create_fs(&fs, REPO_NAME, opts, pool));
+
+  ffd = fs->fsap_data;
+  if (ffd->format < SVN_FS_FS__MIN_REP_SHARING_FORMAT)
+    return svn_error_create(SVN_ERR_TEST_SKIPPED, NULL, NULL);
+
+  ffd->rep_sharing_allowed = TRUE;
+
+  /* Revision 1: create 2 files with different content. */
+  SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, pool));
+  SVN_ERR(svn_fs_txn_root(&root, txn, pool));
+  SVN_ERR(svn_fs_make_file(root, "foo", pool));
+  SVN_ERR(svn_test__set_file_contents(root, "foo", hello_str, pool));
+  SVN_ERR(svn_fs_make_file(root, "bar", pool));
+  SVN_ERR(svn_test__set_file_contents(root, "bar", world_str, pool));
+  SVN_ERR(svn_fs_commit_txn(NULL, &rev, txn, pool));
+
+  /* Revision 2: modify a file to match another file's r1 content and
+                 add another with the same content.
+                 (classic rep-sharing). */
+  SVN_ERR(svn_fs_begin_txn(&txn, fs, rev, pool));
+  SVN_ERR(svn_fs_txn_root(&root, txn, pool));
+  SVN_ERR(svn_test__set_file_contents(root, "foo", world_str, pool));
+  SVN_ERR(svn_fs_make_file(root, "baz", pool));
+  SVN_ERR(svn_test__set_file_contents(root, "baz", hello_str, pool));
+  SVN_ERR(svn_fs_commit_txn(NULL, &rev, txn, pool));
+
+  /* Revision 3: modify all files to some new, identical content and add
+                 another with the same content.
+                 (in-revision rep-sharing). */
+  SVN_ERR(svn_fs_begin_txn(&txn, fs, rev, pool));
+  SVN_ERR(svn_fs_txn_root(&root, txn, pool));
+  SVN_ERR(svn_test__set_file_contents(root, "foo", goodbye_str, pool));
+  SVN_ERR(svn_test__set_file_contents(root, "bar", goodbye_str, pool));
+  SVN_ERR(svn_test__set_file_contents(root, "baz", goodbye_str, pool));
+  SVN_ERR(svn_fs_make_file(root, "qux", pool));
+  SVN_ERR(svn_test__set_file_contents(root, "qux", goodbye_str, pool));
+  SVN_ERR(svn_fs_commit_txn(NULL, &rev, txn, pool));
+
+  /* Verify revision contents. */
+  {
+    const struct {
+      svn_revnum_t revision;
+      const char *file;
+      const char *contents;
+    } expected[] = {
+      { 1, "foo", "Hello, " },
+      { 1, "bar", "World!" },
+      { 2, "foo", "World!" },
+      { 2, "bar", "World!" },
+      { 2, "baz", "Hello, " },
+      { 3, "foo", "Goodbye!" },
+      { 3, "bar", "Goodbye!" },
+      { 3, "baz", "Goodbye!" },
+      { 3, "qux", "Goodbye!" },
+      { SVN_INVALID_REVNUM, NULL, NULL }
+    };
+
+    int i;
+    apr_pool_t *iterpool = svn_pool_create(pool);
+    for (i = 0; SVN_IS_VALID_REVNUM(expected[i].revision); ++i)
+      {
+        svn_stringbuf_t *str;
+
+        SVN_ERR(svn_fs_revision_root(&root, fs, expected[i].revision,
+                                     iterpool));
+        SVN_ERR(svn_test__get_file_contents(root, expected[i].file, &str,
+                                            iterpool));
+
+        SVN_TEST_STRING_ASSERT(str->data,
+                               multiply_string(expected[i].contents,
+                                               iterpool));
+      }
+
+    svn_pool_destroy(iterpool);
+  }
+
+  /* Verify that rep sharing eliminated most reps. */
+  {
+    /* Number of expected representations (including the root directory). */
+    const int expected[] = { 1, 3, 1, 2 } ;
+
+    svn_revnum_t i;
+    apr_pool_t *iterpool = svn_pool_create(pool);
+    for (i = 0; i <= rev; ++i)
+      {
+        int count;
+        SVN_ERR(count_representations(&count, fs, i, iterpool));
+        SVN_TEST_ASSERT(count == expected[i]);
+      }
+
+    svn_pool_destroy(iterpool);
+  }
+
+  return SVN_NO_ERROR;
+}
+
+#undef REPO_NAME
+
 
 /* The test table.  */
 
@@ -1416,6 +1582,8 @@ static struct svn_test_descriptor_t test
                        "id parser test"),
     SVN_TEST_OPTS_PASS(plain_0_length,
                        "file with 0 expanded-length, issue #4554"),
+    SVN_TEST_OPTS_PASS(rep_sharing_effectiveness,
+                       "rep-sharing effectiveness"),
     SVN_TEST_NULL
   };
 

Propchange: subversion/branches/move-tracking-2/tools/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Mar 30 18:38:40 2015
@@ -82,4 +82,4 @@
 /subversion/branches/verify-at-commit/tools:1462039-1462408
 /subversion/branches/verify-keep-going/tools:1439280-1546110
 /subversion/branches/wc-collate-path/tools:1402685-1480384
-/subversion/trunk/tools:1606692-1668666
+/subversion/trunk/tools:1606692-1670169

Copied: subversion/branches/move-tracking-2/tools/dist/README.backport (from r1670040, subversion/trunk/tools/dist/README.backport)
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/tools/dist/README.backport?p2=subversion/branches/move-tracking-2/tools/dist/README.backport&p1=subversion/trunk/tools/dist/README.backport&r1=1670040&r2=1670172&rev=1670172&view=diff
==============================================================================
    (empty)

Modified: subversion/branches/move-tracking-2/tools/dist/backport.pl
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/tools/dist/backport.pl?rev=1670172&r1=1670171&r2=1670172&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/tools/dist/backport.pl (original)
+++ subversion/branches/move-tracking-2/tools/dist/backport.pl Mon Mar 30 18:38:40 2015
@@ -431,7 +431,7 @@ fi
 $SVNq up
 $SVNq merge @mergeargs
 if [ "`$SVN status -q | wc -l`" -eq 1 ]; then
-  if [ -n "`$SVN diff | perl -lne 'print if s/^(Added|Deleted|Modified): //' | grep -vx svn:mergeinfo`" ]; then
+  if [ -z "`$SVN diff | perl -lne 'print if s/^(Added|Deleted|Modified): //' | grep -vx svn:mergeinfo`" ]; then
     # This check detects STATUS entries that name non-^/subversion/ revnums.
     # ### Q: What if we actually commit a mergeinfo fix to trunk and then want
     # ###    to backport it?
@@ -578,7 +578,7 @@ sub parse_entry {
   # summary
   do {
     push @logsummary, shift
-  } until $_[0] =~ /^\s*[][\w]+:/ or not defined $_[0];
+  } until $_[0] =~ /^\s*[A-Z][][\w]*:/ or not defined $_[0];
 
   # votes
   unshift @votes, pop until $_[-1] =~ /^\s*Votes:/ or not defined $_[-1];

Modified: subversion/branches/move-tracking-2/tools/dist/backport/merger.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/tools/dist/backport/merger.py?rev=1670172&r1=1670040&r2=1670172&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/tools/dist/backport/merger.py (original)
+++ subversion/branches/move-tracking-2/tools/dist/backport/merger.py Mon Mar 30 18:38:40 2015
@@ -38,10 +38,6 @@ logger = logging.getLogger(__name__)
 SVN = os.getenv('SVN', 'svn')
 # TODO: maybe run 'svn info' to check if it works / fail early?
 
-# ### Hardcode these here.
-TRUNK = '^/subversion/trunk'
-BRANCHES = '^/subversion/branches'
-
 
 class UnableToMergeException(Exception):
   pass
@@ -145,18 +141,19 @@ def _includes_only_svn_mergeinfo_changes
   return False
 
 
-def merge(entry, expected_stderr=None, *, commit=False, sf=None):
+def merge(entry, expected_stderr=None, *, commit=False):
   """Merges ENTRY into the working copy at cwd.
 
   Do not commit the result, unless COMMIT is true.  When committing,
-  use parameter SF, a StatusFile instance, to remove ENTRY from the STATUS file
-  prior to committing.
+  remove ENTRY from its STATUS file prior to committing.
   
   EXPECTED_STDERR will be passed to run_svn() for the actual 'merge' command."""
 
-  assert (commit == False) or isinstance(sf, backport.status.StatusFile)
   assert isinstance(entry, backport.status.StatusEntry)
   assert entry.valid()
+  assert entry.status_file
+
+  sf = entry.status_file
 
   # TODO(interactive mode): catch the exception
   validate_branch_contains_named_revisions(entry)
@@ -164,7 +161,7 @@ def merge(entry, expected_stderr=None, *
   # Prepare mergeargs and logmsg.
   logmsg = ""
   if entry.branch:
-    branch_url = "%s/%s" % (BRANCHES, entry.branch)
+    branch_url = "%s/%s" % (sf.BRANCHES, entry.branch)
     if svn_version() >= (1, 8):
       mergeargs = ['--', branch_url]
       logmsg = "Merge {}:\n".format(entry.noun())
@@ -184,7 +181,7 @@ def merge(entry, expected_stderr=None, *
       logmsg += "Merge {} from trunk:\n".format(entry.noun())
     logmsg += "\n"
     mergeargs.extend('-c' + str(revision) for revision in entry.revisions)
-    mergeargs.extend(['--', TRUNK])
+    mergeargs.extend(['--', sf.TRUNK])
   logmsg += entry.raw
 
   # TODO(interactive mode): exclude STATUS from reverts
@@ -239,10 +236,13 @@ def validate_branch_contains_named_revis
   if svn_version() < (1,5): # doesn't have 'svn mergeinfo' subcommand
     return # skip check
 
-  branch_url = "%s/%s" % (BRANCHES, entry.branch)
-  present_str = \
-    run_svn(['mergeinfo', '--show-revs=merged', '--', TRUNK, branch_url])[1] + \
+  sf = entry.status_file
+  branch_url = "%s/%s" % (sf.BRANCHES, entry.branch)
+  present_str = (
+    run_svn(['mergeinfo', '--show-revs=merged', '--', sf.TRUNK, branch_url])[1]
+    +
     run_svn(['mergeinfo', '--show-revs=eligible', '--', branch_url])[1]
+  )
 
   present = map(int, re.compile(r'(\d+)').findall(present_str))
 

Modified: subversion/branches/move-tracking-2/tools/dist/backport/status.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/tools/dist/backport/status.py?rev=1670172&r1=1670040&r2=1670172&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/tools/dist/backport/status.py (original)
+++ subversion/branches/move-tracking-2/tools/dist/backport/status.py Mon Mar 30 18:38:40 2015
@@ -157,17 +157,20 @@ class Paragraph:
 class StatusFile:
   "Encapsulates the STATUS file."
 
-  def __init__(self, status_file):
-    "Constructor.  STATUS_FILE is an open file-like object to parse."
-    self._parse(status_file)
+  TRUNK = '^/subversion/trunk'
+  BRANCHES = '^/subversion/branches'
+
+  def __init__(self, status_fp):
+    "Constructor.  STATUS_FP is an open file-like object to parse."
+    self._parse(status_fp)
     self.validate_unique_entry_ids() # Use-case for making this optional?
 
-  def _parse(self, status_file):
-    "Parse self.status_file into self.paragraphs."
+  def _parse(self, status_fp):
+    "Parse self.status_fp into self.paragraphs."
 
     self.paragraphs = []
     last_header = None
-    for para_text in _ParagraphsIterator(status_file):
+    for para_text in _ParagraphsIterator(status_fp):
       kind = None
       entry = None
       header = Paragraph.is_header(para_text)
@@ -178,12 +181,12 @@ class StatusFile:
         last_header = header
       elif last_header is not None:
         try:
-          entry = StatusEntry(para_text)
+          entry = StatusEntry(para_text, status_file=self)
           kind = Kind.nomination
         except ParseException:
           kind = Kind.unknown
           logger.warning("Failed to parse entry {!r} in {!r}".format(
-                          para_text, status_file))
+                          para_text, status_fp))
       else:
         kind = Kind.preamble
 
@@ -276,6 +279,8 @@ class Test_StatusFile(unittest.TestCase)
     self.assertTrue(sf.paragraphs[3].approved()) # header
     self.assertTrue(sf.paragraphs[4].approved()) # unknown
 
+    self.assertIs(sf.paragraphs[2].entry().status_file, sf)
+
     output_file = io.StringIO()
     sf.unparse(output_file)
     self.assertEqual(s, output_file.getvalue())
@@ -316,15 +321,19 @@ class StatusEntry:
   votes_str - everything after the "Votes:" subheader.  An unparsed string.
   """
 
-  def __init__(self, para_text):
+  def __init__(self, para_text, status_file=None):
     """Parse an entry from PARA_TEXT, and add it to SELF.  PARA_TEXT must
-    contain exactly one entry, as a single multiline string."""
+    contain exactly one entry, as a single multiline string.
+    
+    STATUS_FILE is the StatusFile object containing this entry, if any.
+    """
     self.branch = None
     self.revisions = []
     self.logsummary = []
     self.depends = False
     self.accept = None
     self.votes_str = None
+    self.status_file = status_file
 
     self.raw = para_text
 

Modified: subversion/branches/move-tracking-2/tools/dist/backport_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/tools/dist/backport_tests.py?rev=1670172&r1=1670171&r2=1670172&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/tools/dist/backport_tests.py (original)
+++ subversion/branches/move-tracking-2/tools/dist/backport_tests.py Mon Mar 30 18:38:40 2015
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 # py:encoding=utf-8
 #
-#  backport_tests.py:  Test backport.pl
+#  backport_tests.py:  Test backport.pl or backport.py
 #
 #  Subversion is a tool for revision control.
 #  See http://subversion.apache.org for more information.
@@ -25,6 +25,25 @@
 #    under the License.
 ######################################################################
 
+# We'd like to test backport.pl and backport.py the same way, and to reuse
+# the svntest Python harness.  Since the latter standardizes argv parsing,
+# we can't use argv to determine whether .py or .pl should be tested.  Thus,
+# we implement the tests themselves in this file, while two driver files
+# (backport_tests_pl.py and backport_tests_py.py) invoke this file set
+# to run either backport-suite implementation.
+#
+# ### Note: the two driver scripts use the same repository names in
+# ### svn-test-work.  This is not ideal, but hopefully acceptable
+# ### temporarily until we switch over to backport.py and remove backport.pl.
+# ###
+# ### See svntest.testcase.FunctionTestCase.get_sandbox_name().
+try:
+  run_backport, run_conflicter
+except NameError:
+  raise Exception("Failure: %s should not be run directly, or the wrapper "
+                  "does not define both run_backport() and run_conflicter()"
+                  % __file__)
+
 # General modules
 import contextlib
 import functools
@@ -58,8 +77,6 @@ Wimp = svntest.testcase.Wimp_deco
 ######################################################################
 # Helper functions
 
-BACKPORT_PL = os.path.abspath(os.path.join(os.path.dirname(__file__),
-                                           'backport.pl'))
 STATUS = 'branch/STATUS'
 
 class BackportTest(object):
@@ -159,12 +176,15 @@ def serialize_entry(entry):
   ])
 
 def serialize_STATUS(approveds,
+                     candidates=[],
                      serialize_entry=serialize_entry):
   """Construct and return the contents of a STATUS file.
 
   APPROVEDS is an iterable of ENTRY dicts.  The dicts are defined
   to have the following keys: 'revisions', a list of revision numbers (ints);
   'logsummary'; and 'votes', a dict mapping ±1/±0 (int) to list of voters.
+
+  CANDIDATES is like APPROVEDS, except added to a different section of the file.
   """
 
   strings = []
@@ -173,6 +193,8 @@ def serialize_STATUS(approveds,
   strings.append("Candidate changes:\n")
   strings.append("==================\n\n")
 
+  strings.extend(map(serialize_entry, candidates))
+
   strings.append("Random new subheading:\n")
   strings.append("======================\n\n")
 
@@ -186,22 +208,6 @@ def serialize_STATUS(approveds,
 
   return "".join(strings)
 
-def run_backport(sbox, error_expected=False, extra_env=[]):
-  """Run backport.pl.  EXTRA_ENV is a list of key=value pairs (str) to set in
-  the child's environment.  ERROR_EXPECTED is propagated to run_command()."""
-  # TODO: if the test is run in verbose mode, pass DEBUG=1 in the environment,
-  #       and pass error_expected=True to run_command() to not croak on
-  #       stderr output from the child (because it uses 'sh -x').
-  args = [
-    '/usr/bin/env',
-    'SVN=' + svntest.main.svn_binary,
-    'YES=1', 'MAY_COMMIT=1', 'AVAILID=jrandom',
-  ] + list(extra_env) + [
-    'perl', BACKPORT_PL,
-  ]
-  with chdir(sbox.ospath('branch')):
-    return svntest.main.run_command(args[0], error_expected, False, *(args[1:]))
-
 def verify_backport(sbox, expected_dump_file, uuid):
   """Compare the contents of the SBOX repository with EXPECTED_DUMP_FILE.
   Set the UUID of SBOX to UUID beforehand.
@@ -225,7 +231,7 @@ def verify_backport(sbox, expected_dump_
   src_dump = svntest.actions.run_and_verify_dump(sbox.repo_dir)
 
   svntest.verify.compare_dump_files(
-    "Dump files", "DUMP", src_dump, dest_dump)
+    "Dump files", "DUMP", dest_dump, src_dump)
 
 ######################################################################
 # Tests
@@ -376,16 +382,14 @@ def backport_conflicts_detection(sbox):
   sbox.simple_commit(message="Conflicting change on iota")
 
   # r7: nominate r4, but without the requisite --accept
-  approved_entries = [
+  candidate_entries = [
     make_entry([4], notes="This will conflict."),
   ]
-  sbox.simple_append(STATUS, serialize_STATUS(approved_entries))
+  sbox.simple_append(STATUS, serialize_STATUS([], candidate_entries))
   sbox.simple_commit(message='Nominate r4')
 
   # Run it.
-  exit_code, output, errput = run_backport(sbox, True,
-                                           # Choose conflicts mode:
-                                           ["MAY_COMMIT=0"])
+  exit_code, output, errput = run_conflicter(sbox, True)
 
   # Verify the conflict is detected.
   expected_output = svntest.verify.RegexOutput(
@@ -418,9 +422,9 @@ def backport_conflicts_detection(sbox):
   sbox.simple_commit(message='Re-nominate r4')
 
   # Detect conflicts.
-  exit_code, output, errput = run_backport(sbox, extra_env=["MAY_COMMIT=0"])
+  exit_code, output, errput = run_conflicter(sbox)
 
-  # Verify stdout.  (exit_code and errput were verified by run_backport().)
+  # Verify stdout.  (exit_code and errput were verified by run_conflicter().)
   svntest.verify.verify_outputs(None, output, errput,
                                 "Conflicts found.*, as expected.", [])
 
@@ -501,7 +505,7 @@ def backport_double_conflict(sbox):
   sbox.simple_commit(message='Nominate the r4 group')
 
   # Run it, in conflicts mode.
-  exit_code, output, errput = run_backport(sbox, True, ["MAY_COMMIT=0"])
+  exit_code, output, errput = run_conflicter(sbox, True)
 
   # Verify the failure mode: "merge conflict" error on stderr, but backport.pl
   # itself exits with code 0, since conflicts were confined to Depends:-ed
@@ -541,13 +545,16 @@ def backport_double_conflict(sbox):
   sbox.simple_append(STATUS, serialize_STATUS(approved_entries), truncate=True)
   sbox.simple_commit(message='Re-nominate the r4 group')
 
-  exit_code, output, errput = run_backport(sbox, True, ["MAY_COMMIT=0"])
+  exit_code, output, errput = run_conflicter(sbox, True)
 
+  ## An unexpected non-zero exit code is treated as a fatal error.
   # [1-9]\d+ matches non-zero exit codes
-  expected_errput = r'r4 .*: subshell exited with code (?:[1-9]\d+)'
+  expected_stdout = None
+  expected_errput = r'r4 .*: subshell exited with code (?:[1-9]\d+)' \
+                   r"|.*subprocess.CalledProcessError.*'merge'.*exit status 1"
   svntest.verify.verify_exit_code(None, exit_code, 1)
   svntest.verify.verify_outputs(None, output, errput,
-                                svntest.verify.AnyOutput, expected_errput)
+                                expected_stdout, expected_errput)
 
 
 
@@ -590,6 +597,55 @@ def backport_branch_with_original_revisi
 
 
 #----------------------------------------------------------------------
+@BackportTest(None)
+def backport_otherproject_change(sbox):
+  "inoperative revision"
+
+  # r6: a change outside ^/subversion
+  sbox.simple_mkdir('elsewhere')
+  sbox.simple_commit()
+
+  # r7: Nominate r6 by mistake
+  approved_entries = [
+    make_entry([6])
+  ]
+  sbox.simple_append(STATUS, serialize_STATUS(approved_entries))
+  sbox.simple_commit(message='Nominate r6 by mistake')
+
+  # Run it.
+  exit_code, output, errput = run_backport(sbox, error_expected=True)
+
+  # Verify no commit occurred.
+  svntest.actions.run_and_verify_svnlook(["7\n"], [],
+                                         'youngest', sbox.repo_dir)
+
+  # Verify the failure mode.
+  expected_stdout = None
+  expected_stderr = ".*only svn:mergeinfo changes.*"
+  if exit_code == 0:
+    # Can't use verify_exit_code() since the exact code used varies.
+    raise svntest.Failure("exit_code should be non-zero")
+  svntest.verify.verify_outputs(None, output, errput,
+                                expected_stdout, expected_stderr)
+
+#----------------------------------------------------------------------
+@BackportTest(None)
+def backport_STATUS_mods(sbox):
+  "local mods to STATUS"
+
+  # Introduce a local mod.
+  sbox.simple_append(STATUS, "\n")
+
+  exit_code, output, errput = run_backport(sbox, error_expected=True)
+  expected_stdout = None
+  expected_stderr = ".*Local mods.*STATUS.*"
+  if exit_code == 0:
+    # Can't use verify_exit_code() since the exact code used varies.
+    raise svntest.Failure("exit_code should be non-zero")
+  svntest.verify.verify_outputs(None, output, errput,
+                                expected_stdout, expected_stderr)
+
+#----------------------------------------------------------------------
 
 ########################################################################
 # Run the tests
@@ -605,6 +661,8 @@ test_list = [ None,
               backport_branch_contains,
               backport_double_conflict,
               backport_branch_with_original_revision,
+              backport_otherproject_change,
+              backport_STATUS_mods,
               # When adding a new test, include the test number in the last
               # 6 bytes of the UUID.
              ]

Propchange: subversion/branches/move-tracking-2/tools/dist/backport_tests.py
            ('svn:executable' removed)

Copied: subversion/branches/move-tracking-2/tools/dist/backport_tests_pl.py (from r1670040, subversion/trunk/tools/dist/backport_tests_pl.py)
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/tools/dist/backport_tests_pl.py?p2=subversion/branches/move-tracking-2/tools/dist/backport_tests_pl.py&p1=subversion/trunk/tools/dist/backport_tests_pl.py&r1=1670040&r2=1670172&rev=1670172&view=diff
==============================================================================
    (empty)

Propchange: subversion/branches/move-tracking-2/tools/dist/backport_tests_pl.py
------------------------------------------------------------------------------
    svn:executable = *

Copied: subversion/branches/move-tracking-2/tools/dist/backport_tests_py.py (from r1670040, subversion/trunk/tools/dist/backport_tests_py.py)
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/tools/dist/backport_tests_py.py?p2=subversion/branches/move-tracking-2/tools/dist/backport_tests_py.py&p1=subversion/trunk/tools/dist/backport_tests_py.py&r1=1670040&r2=1670172&rev=1670172&view=diff
==============================================================================
    (empty)

Propchange: subversion/branches/move-tracking-2/tools/dist/backport_tests_py.py
------------------------------------------------------------------------------
    svn:executable = *

Copied: subversion/branches/move-tracking-2/tools/dist/detect-conflicting-backports.py (from r1670040, subversion/trunk/tools/dist/detect-conflicting-backports.py)
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/tools/dist/detect-conflicting-backports.py?p2=subversion/branches/move-tracking-2/tools/dist/detect-conflicting-backports.py&p1=subversion/trunk/tools/dist/detect-conflicting-backports.py&r1=1670040&r2=1670172&rev=1670172&view=diff
==============================================================================
    (empty)

Propchange: subversion/branches/move-tracking-2/tools/dist/detect-conflicting-backports.py
------------------------------------------------------------------------------
    svn:executable = *

Copied: subversion/branches/move-tracking-2/tools/dist/merge-approved-backports.py (from r1670040, subversion/trunk/tools/dist/merge-approved-backports.py)
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/tools/dist/merge-approved-backports.py?p2=subversion/branches/move-tracking-2/tools/dist/merge-approved-backports.py&p1=subversion/trunk/tools/dist/merge-approved-backports.py&r1=1670040&r2=1670172&rev=1670172&view=diff
==============================================================================
--- subversion/trunk/tools/dist/merge-approved-backports.py (original)
+++ subversion/branches/move-tracking-2/tools/dist/merge-approved-backports.py Mon Mar 30 18:38:40 2015
@@ -47,4 +47,4 @@ entries_paras = list(sf.entries_paras())
 for entry_para in entries_paras:
   if entry_para.approved():
     entry = entry_para.entry()
-    backport.merger.merge(entry, commit=True, sf=sf)
+    backport.merger.merge(entry, commit=True)

Propchange: subversion/branches/move-tracking-2/tools/dist/merge-approved-backports.py
------------------------------------------------------------------------------
    svn:executable = *