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/10/20 10:43:19 UTC

svn commit: r1709538 [1/2] - in /subversion/branches/move-tracking-2: ./ subversion/ subversion/include/ subversion/libsvn_fs_base/ subversion/libsvn_fs_fs/ subversion/libsvn_fs_x/ subversion/libsvn_repos/ subversion/mod_authz_svn/ subversion/po/ subve...

Author: julianfoad
Date: Tue Oct 20 08:43:19 2015
New Revision: 1709538

URL: http://svn.apache.org/viewvc?rev=1709538&view=rev
Log:
On the 'move-tracking-2' branch: catch up to trunk@1709537.

Modified:
    subversion/branches/move-tracking-2/   (props changed)
    subversion/branches/move-tracking-2/subversion/   (props changed)
    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_base/dag.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_base/fs.h
    subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/dag.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.h
    subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.h
    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.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs.h
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs_x.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs_x.h
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/revprops.c
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/revprops.h
    subversion/branches/move-tracking-2/subversion/libsvn_fs_x/verify.c
    subversion/branches/move-tracking-2/subversion/libsvn_repos/delta.c
    subversion/branches/move-tracking-2/subversion/libsvn_repos/dump.c
    subversion/branches/move-tracking-2/subversion/libsvn_repos/reporter.c
    subversion/branches/move-tracking-2/subversion/libsvn_repos/rev_hunt.c
    subversion/branches/move-tracking-2/subversion/mod_authz_svn/mod_authz_svn.c
    subversion/branches/move-tracking-2/subversion/po/es.po
    subversion/branches/move-tracking-2/subversion/po/fr.po
    subversion/branches/move-tracking-2/subversion/po/it.po
    subversion/branches/move-tracking-2/subversion/po/ja.po
    subversion/branches/move-tracking-2/subversion/po/ko.po
    subversion/branches/move-tracking-2/subversion/po/nb.po
    subversion/branches/move-tracking-2/subversion/po/pl.po
    subversion/branches/move-tracking-2/subversion/po/pt_BR.po
    subversion/branches/move-tracking-2/subversion/po/sv.po
    subversion/branches/move-tracking-2/subversion/po/zh_CN.po
    subversion/branches/move-tracking-2/subversion/po/zh_TW.po
    subversion/branches/move-tracking-2/subversion/svnlook/svnlook.c
    subversion/branches/move-tracking-2/subversion/tests/cmdline/svnadmin_tests.py
    subversion/branches/move-tracking-2/subversion/tests/libsvn_fs/fs-sequential-test.c
    subversion/branches/move-tracking-2/subversion/tests/libsvn_fs/fs-test.c
    subversion/branches/move-tracking-2/subversion/tests/svn_test_fs.c

Propchange: subversion/branches/move-tracking-2/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Oct 20 08:43:19 2015
@@ -94,4 +94,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-1708078
+/subversion/trunk:1606692-1709537

Propchange: subversion/branches/move-tracking-2/subversion/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Oct 20 08:43:19 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-1708078
+/subversion/trunk/subversion:1606692-1709537

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=1709538&r1=1709537&r2=1709538&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/svn_ra.h (original)
+++ subversion/branches/move-tracking-2/subversion/include/svn_ra.h Tue Oct 20 08:43:19 2015
@@ -1797,11 +1797,10 @@ svn_ra_get_location_segments(svn_ra_sess
  * to support reversion of the revision range for @a include_merged_revision
  * @c FALSE reporting by switching  @a end with @a start.
  *
- * @note Prior to Subversion 1.9, this function may request delta handlers
- * from @a handler even for empty text deltas.  Starting with 1.9, the
- * delta handler / baton return arguments passed to @a handler will be
- * #NULL unless there is an actual difference in the file contents between
- * the current and the previous call.
+ * @note In Subversion 1.9.0-1.9.2, the delta handler / baton return
+ * arguments passed to @a handler were set to #NULL in case of an empty
+ * text delta.  All other versions may request delta handlers from
+ * @a handler even for empty text deltas.
  *
  * @since New in 1.5.
  */

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=1709538&r1=1709537&r2=1709538&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/include/svn_repos.h (original)
+++ subversion/branches/move-tracking-2/subversion/include/svn_repos.h Tue Oct 20 08:43:19 2015
@@ -2093,11 +2093,10 @@ svn_repos_fs_get_mergeinfo(svn_mergeinfo
  * the revision range for @a include_merged_revision @c FALSE reporting by
  * switching @a start with @a end.
  *
- * @note Prior to Subversion 1.9, this function may request delta handlers
- * from @a handler even for empty text deltas.  Starting with 1.9, the
- * delta handler / baton return arguments passed to @a handler will be
- * #NULL unless there is an actual difference in the file contents between
- * the current and the previous call.
+ * @note In Subversion 1.9.0-1.9.2, the delta handler / baton return
+ * arguments passed to @a handler were set to #NULL in case of an empty
+ * text delta.  All other versions may request delta handlers from
+ * @a handler even for empty text deltas.
  *
  * @since New in 1.5.
  */

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_base/dag.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_base/dag.c?rev=1709538&r1=1709537&r2=1709538&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_base/dag.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_base/dag.c Tue Oct 20 08:43:19 2015
@@ -1657,8 +1657,14 @@ svn_fs_base__things_different(svn_boolea
 
   /* Compare contents keys and their (optional) uniquifiers. */
   if (contents_changed != NULL)
-    *contents_changed = (! svn_fs_base__same_keys(noderev1->data_key,
-                                                  noderev2->data_key));
+    *contents_changed =
+      (! (svn_fs_base__same_keys(noderev1->data_key,
+                                 noderev2->data_key)
+          /* Technically, these uniquifiers aren't used and "keys",
+             but keys are base-36 stringified numbers, so we'll take
+             this liberty. */
+          && (svn_fs_base__same_keys(noderev1->data_key_uniquifier,
+                                     noderev2->data_key_uniquifier))));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_base/fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_base/fs.h?rev=1709538&r1=1709537&r2=1709538&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_base/fs.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_base/fs.h Tue Oct 20 08:43:19 2015
@@ -195,11 +195,7 @@ typedef struct node_revision_t
      only because one or both of us decided to pick up a shared
      representation after-the-fact."  May be NULL (if this node
      revision isn't using a shared rep, or isn't the original
-     "assignee" of a shared rep).
-
-     This is no longer used by the 1.9 code but we have to keep
-     reading and writing it to remain compatible with 1.8, and
-     earlier, that require it. */
+     "assignee" of a shared rep). */
   const char *data_key_uniquifier;
 
   /* representation key for this node's text-data-in-progess (files

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/dag.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/dag.c?rev=1709538&r1=1709537&r2=1709538&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/dag.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/dag.c Tue Oct 20 08:43:19 2015
@@ -1305,34 +1305,61 @@ svn_fs_fs__dag_things_different(svn_bool
                                 apr_pool_t *pool)
 {
   node_revision_t *noderev1, *noderev2;
-  svn_fs_t *fs;
-  svn_boolean_t same;
 
   /* If we have no place to store our results, don't bother doing
      anything. */
   if (! props_changed && ! contents_changed)
     return SVN_NO_ERROR;
 
-  fs = svn_fs_fs__dag_get_fs(node1);
-
   /* The node revision skels for these two nodes. */
   SVN_ERR(get_node_revision(&noderev1, node1));
   SVN_ERR(get_node_revision(&noderev2, node2));
 
-  /* Compare property keys. */
-  if (props_changed != NULL)
+  if (strict)
     {
-      SVN_ERR(svn_fs_fs__prop_rep_equal(&same, fs, noderev1, noderev2,
-                                        strict, pool));
-      *props_changed = !same;
+      /* In strict mode, compare text and property representations in the
+         svn_fs_contents_different() / svn_fs_props_different() manner.
+         These functions are currently not being used in our codebase, but
+         we released them as a part of 1.9, and keep them for compatibility
+         reasons.
+
+         See the "No-op changes no longer dumped by 'svnadmin dump' in 1.9"
+         discussion (http://svn.haxx.se/dev/archive-2015-09/0269.shtml) and
+         issue #4598 (https://issues.apache.org/jira/browse/SVN-4598). */
+      svn_fs_t *fs = svn_fs_fs__dag_get_fs(node1);
+      svn_boolean_t same;
+
+      /* Compare property keys. */
+      if (props_changed != NULL)
+        {
+          SVN_ERR(svn_fs_fs__prop_rep_equal(&same, fs, noderev1,
+                                            noderev2, pool));
+          *props_changed = !same;
+        }
+
+      /* Compare contents keys. */
+      if (contents_changed != NULL)
+        {
+          SVN_ERR(svn_fs_fs__file_text_rep_equal(&same, fs, noderev1,
+                                                 noderev2, pool));
+          *contents_changed = !same;
+        }
     }
-
-  /* Compare contents keys. */
-  if (contents_changed != NULL)
+  else
     {
-      SVN_ERR(svn_fs_fs__file_text_rep_equal(&same, fs, noderev1, noderev2,
-                                             strict, pool));
-      *contents_changed = !same;
+      /* Otherwise, compare representation keys -- as in Subversion 1.8. */
+
+      /* Compare property keys. */
+      if (props_changed != NULL)
+        *props_changed =
+          !svn_fs_fs__noderev_same_rep_key(noderev1->prop_rep,
+                                           noderev2->prop_rep);
+
+      /* Compare contents keys. */
+      if (contents_changed != NULL)
+        *contents_changed =
+          !svn_fs_fs__noderev_same_rep_key(noderev1->data_rep,
+                                           noderev2->data_rep);
     }
 
   return SVN_NO_ERROR;

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.h?rev=1709538&r1=1709537&r2=1709538&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs.h Tue Oct 20 08:43:19 2015
@@ -550,13 +550,7 @@ typedef struct representation_t
   /* For rep-sharing, we need a way of uniquifying node-revs which share the
      same representation (see svn_fs_fs__noderev_same_rep_key() ).  So, we
      store the original txn of the node rev (not the rep!), along with some
-     intra-node uniqification content.
-
-     This is no longer used by the 1.9 code but we have to keep
-     reading and writing it for old formats to remain compatible with
-     1.8, and earlier, that require it.  We also read/write it in
-     format 7 even though it is not currently required by any code
-     that handles that format. */
+     intra-node uniqification content. */
   struct
     {
       /* unique context, i.e. txn ID, in which the noderev (!) got created */

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=1709538&r1=1709537&r2=1709538&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 Oct 20 08:43:19 2015
@@ -1387,12 +1387,30 @@ svn_fs_fs__file_length(svn_filesize_t *l
   return SVN_NO_ERROR;
 }
 
+svn_boolean_t
+svn_fs_fs__noderev_same_rep_key(representation_t *a,
+                                representation_t *b)
+{
+  if (a == b)
+    return TRUE;
+
+  if (a == NULL || b == NULL)
+    return FALSE;
+
+  if (a->item_index != b->item_index)
+    return FALSE;
+
+  if (a->revision != b->revision)
+    return FALSE;
+
+  return memcmp(&a->uniquifier, &b->uniquifier, sizeof(a->uniquifier)) == 0;
+}
+
 svn_error_t *
 svn_fs_fs__file_text_rep_equal(svn_boolean_t *equal,
                                svn_fs_t *fs,
                                node_revision_t *a,
                                node_revision_t *b,
-                               svn_boolean_t strict,
                                apr_pool_t *scratch_pool)
 {
   svn_stream_t *contents_a, *contents_b;
@@ -1437,19 +1455,6 @@ svn_fs_fs__file_text_rep_equal(svn_boole
       return SVN_NO_ERROR;
     }
 
-  /* Old repositories may not have the SHA1 checksum handy.
-     This check becomes expensive.  Skip it unless explicitly required.
-
-     We already have seen that the ID is different, so produce a likely
-     false negative as allowed by the API description - even though the
-     MD5 matched, there is an extremely slim chance that the SHA1 wouldn't.
-   */
-  if (!strict)
-    {
-      *equal = FALSE;
-      return SVN_NO_ERROR;
-    }
-
   SVN_ERR(svn_fs_fs__get_contents(&contents_a, fs, rep_a, TRUE,
                                   scratch_pool));
   SVN_ERR(svn_fs_fs__get_contents(&contents_b, fs, rep_b, TRUE,
@@ -1465,7 +1470,6 @@ svn_fs_fs__prop_rep_equal(svn_boolean_t
                           svn_fs_t *fs,
                           node_revision_t *a,
                           node_revision_t *b,
-                          svn_boolean_t strict,
                           apr_pool_t *scratch_pool)
 {
   representation_t *rep_a = a->prop_rep;
@@ -1512,14 +1516,6 @@ svn_fs_fs__prop_rep_equal(svn_boolean_t
       return SVN_NO_ERROR;
     }
 
-  /* Skip the expensive bits unless we are in strict mode.
-     Simply assume that there is a difference. */
-  if (!strict)
-    {
-      *equal = FALSE;
-      return SVN_NO_ERROR;
-    }
-
   /* At least one of the reps has been modified in a txn.
      Fetch and compare them. */
   SVN_ERR(svn_fs_fs__get_proplist(&proplist_a, fs, a, scratch_pool));

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.h?rev=1709538&r1=1709537&r2=1709538&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_fs/fs_fs.h Tue Oct 20 08:43:19 2015
@@ -90,28 +90,29 @@ svn_error_t *svn_fs_fs__file_length(svn_
                                     node_revision_t *noderev,
                                     apr_pool_t *pool);
 
+/* Return TRUE if the representation keys in A and B both point to the
+   same representation, else return FALSE. */
+svn_boolean_t svn_fs_fs__noderev_same_rep_key(representation_t *a,
+                                              representation_t *b);
+
 /* Set *EQUAL to TRUE if the text representations in A and B within FS
-   have equal contents, else set it to FALSE.  If STRICT is not set, allow
-   for false negatives.
+   have equal contents, else set it to FALSE.
    Use SCRATCH_POOL for temporary allocations. */
 svn_error_t *
 svn_fs_fs__file_text_rep_equal(svn_boolean_t *equal,
                                svn_fs_t *fs,
                                node_revision_t *a,
                                node_revision_t *b,
-                               svn_boolean_t strict,
                                apr_pool_t *scratch_pool);
 
 /* Set *EQUAL to TRUE if the property representations in A and B within FS
-   have equal contents, else set it to FALSE.  If STRICT is not set, allow
-   for false negatives.
+   have equal contents, else set it to FALSE.
    Use SCRATCH_POOL for temporary allocations. */
 svn_error_t *
 svn_fs_fs__prop_rep_equal(svn_boolean_t *equal,
                           svn_fs_t *fs,
                           node_revision_t *a,
                           node_revision_t *b,
-                          svn_boolean_t strict,
                           apr_pool_t *scratch_pool);
 
 

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=1709538&r1=1709537&r2=1709538&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 Tue Oct 20 08:43:19 2015
@@ -1882,7 +1882,6 @@ merge(svn_stringbuf_t *conflict_p,
   */
   {
     node_revision_t *tgt_nr, *anc_nr, *src_nr;
-    svn_boolean_t same;
     apr_pool_t *scratch_pool;
 
     /* Get node revisions for our id's. */
@@ -1899,15 +1898,16 @@ merge(svn_stringbuf_t *conflict_p,
 
     /* Now compare the prop-keys of the skels.  Note that just because
        the keys are different -doesn't- mean the proplists have
-       different contents. */
-    SVN_ERR(svn_fs_fs__prop_rep_equal(&same, fs, src_nr, anc_nr, TRUE, pool));
-    if (! same)
+       different contents.  But merge() isn't concerned with contents;
+       it doesn't do a brute-force comparison on textual contents, so
+       it won't do that here either.  Checking to see if the propkey
+       atoms are `equal' is enough. */
+    if (! svn_fs_fs__noderev_same_rep_key(src_nr->prop_rep, anc_nr->prop_rep))
       return conflict_err(conflict_p, target_path);
 
     /* The directory entries got changed in the repository but the directory
        properties did not. */
-    SVN_ERR(svn_fs_fs__prop_rep_equal(&same, fs, tgt_nr, anc_nr, TRUE, pool));
-    if (! same)
+    if (! svn_fs_fs__noderev_same_rep_key(tgt_nr->prop_rep, anc_nr->prop_rep))
       {
         /* There is an incoming prop change for this directory.
            We will accept it only if the directory changes were mere updates

Propchange: subversion/branches/move-tracking-2/subversion/libsvn_fs_x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Oct 20 08:43:19 2015
@@ -94,4 +94,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-1708078
+/subversion/trunk/subversion/libsvn_fs_x:1414756-1509914,1606692-1709537

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=1709538&r1=1709537&r2=1709538&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 Oct 20 08:43:19 2015
@@ -222,23 +222,7 @@ static svn_error_t *
 x_refresh_revprops(svn_fs_t *fs,
                    apr_pool_t *scratch_pool)
 {
-  return SVN_NO_ERROR;
-}
-
-/* Wrapper around svn_fs_x__revision_prop() adapting between function
-   signatures. */
-static svn_error_t *
-x_revision_prop(svn_string_t **value_p,
-                svn_fs_t *fs,
-                svn_revnum_t rev,
-                const char *propname,
-                svn_boolean_t refresh,
-                apr_pool_t *result_pool,
-                apr_pool_t *scratch_pool)
-{
-  SVN_ERR(svn_fs_x__revision_prop(value_p, fs, rev, propname, result_pool,
-                                  scratch_pool));
-
+  svn_fs_x__invalidate_revprop_generation(fs);
   return SVN_NO_ERROR;
 }
 
@@ -254,7 +238,8 @@ x_revision_proplist(apr_hash_t **proplis
 {
   /* No need to bypass the caches for r/o access to revprops. */
   SVN_ERR(svn_fs_x__get_revision_proplist(proplist_p, fs, rev, FALSE,
-                                          result_pool, scratch_pool));
+                                          refresh, result_pool,
+                                          scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -292,7 +277,7 @@ x_begin_txn(svn_fs_txn_t **txn_p,
 static fs_vtable_t fs_vtable = {
   svn_fs_x__youngest_rev,
   x_refresh_revprops,
-  x_revision_prop,
+  svn_fs_x__revision_prop,
   x_revision_proplist,
   svn_fs_x__change_rev_prop,
   x_set_uuid,
@@ -323,6 +308,8 @@ static svn_error_t *
 initialize_fs_struct(svn_fs_t *fs)
 {
   svn_fs_x__data_t *ffd = apr_pcalloc(fs->pool, sizeof(*ffd));
+  ffd->revprop_generation = -1;
+
   fs->vtable = &fs_vtable;
   fs->fsap_data = ffd;
   return SVN_NO_ERROR;

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs.h?rev=1709538&r1=1709537&r2=1709538&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs.h Tue Oct 20 08:43:19 2015
@@ -295,9 +295,8 @@ typedef struct svn_fs_x__data_t
      rep key (revision/offset) to svn_stringbuf_t. */
   svn_cache__t *fulltext_cache;
 
-  /* Access object to the revprop "generation". Will be NULL until
-     the first access.  May be also get closed and set to NULL again. */
-  apr_file_t *revprop_generation_file;
+  /* Revprop generation number.  Will be -1 if it has to reread from disk. */
+  apr_int64_t revprop_generation;
 
   /* Revision property cache.  Maps from (rev,generation) to apr_hash_t. */
   svn_cache__t *revprop_cache;

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs_x.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs_x.c?rev=1709538&r1=1709537&r2=1709538&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs_x.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs_x.c Tue Oct 20 08:43:19 2015
@@ -996,6 +996,9 @@ svn_fs_x__create_file_tree(svn_fs_t *fs,
                           scratch_pool));
 
   /* Initialize the revprop caching info. */
+  SVN_ERR(svn_io_file_create_empty(
+                        svn_fs_x__path_revprop_generation(fs, scratch_pool),
+                        scratch_pool));
   SVN_ERR(svn_fs_x__reset_revprop_generation_file(fs, scratch_pool));
 
   ffd->youngest_rev_cache = 0;
@@ -1112,13 +1115,14 @@ svn_fs_x__revision_prop(svn_string_t **v
                         svn_fs_t *fs,
                         svn_revnum_t rev,
                         const char *propname,
+                        svn_boolean_t refresh,
                         apr_pool_t *result_pool,
                         apr_pool_t *scratch_pool)
 {
   apr_hash_t *table;
 
   SVN_ERR(svn_fs__check_fs(fs, TRUE));
-  SVN_ERR(svn_fs_x__get_revision_proplist(&table, fs, rev, FALSE,
+  SVN_ERR(svn_fs_x__get_revision_proplist(&table, fs, rev, FALSE, refresh,
                                           scratch_pool, scratch_pool));
 
   *value_p = svn_string_dup(svn_hash_gets(table, propname), result_pool);
@@ -1151,7 +1155,7 @@ change_rev_prop_body(void *baton,
      Even if somehow the cache got out of sync, we want to make sure that
      we read, update and write up-to-date data. */
   SVN_ERR(svn_fs_x__get_revision_proplist(&table, cb->fs, cb->rev, TRUE,
-                                          scratch_pool, scratch_pool));
+                                          TRUE, scratch_pool, scratch_pool));
   present_value = svn_hash_gets(table, cb->name);
 
   if (cb->old_value_p)

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs_x.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs_x.h?rev=1709538&r1=1709537&r2=1709538&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs_x.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_x/fs_x.h Tue Oct 20 08:43:19 2015
@@ -160,12 +160,15 @@ svn_fs_x__write_format(svn_fs_t *fs,
 
 /* Find the value of the property named PROPNAME in transaction REV.
    Return the contents in *VALUE_P, allocated from RESULT_POOL.
+   If REFRESH is not set, continue using the potentially outdated
+   revprop generation value in FS->FSAP_DATA.
    Use SCRATCH_POOL for temporary allocations. */
 svn_error_t *
 svn_fs_x__revision_prop(svn_string_t **value_p,
                         svn_fs_t *fs,
                         svn_revnum_t rev,
                         const char *propname,
+                        svn_boolean_t refresh,
                         apr_pool_t *result_pool,
                         apr_pool_t *scratch_pool);
 

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_x/revprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_x/revprops.c?rev=1709538&r1=1709537&r2=1709538&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_x/revprops.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_x/revprops.c Tue Oct 20 08:43:19 2015
@@ -48,10 +48,6 @@
    giving up. */
 #define GENERATION_READ_RETRY_COUNT 100
 
-/* Maximum size of the generation number file contents (including NUL). */
-#define CHECKSUMMED_NUMBER_BUFFER_LEN \
-           (SVN_INT64_BUFFER_SIZE + 3 + APR_MD5_DIGESTSIZE * 2)
-
 
 /* Revprop caching management.
  *
@@ -67,16 +63,7 @@
  * as keys with the generation being incremented upon every revprop change.
  * Since the cache is process-local, the generation needs to be tracked
  * for at least as long as the process lives but may be reset afterwards.
- *
- * We track the revprop generation in a persistent, unbuffered file that
- * we may keep open for the lifetime of the svn_fs_t.  It is the OS'
- * responsibility to provide us with the latest contents upon read.  To
- * detect incomplete updates due to non-atomic reads, we put a MD5 checksum
- * next to the actual generation number and verify that it matches.
- *
- * Since we cannot guarantee that the OS will provide us with up-to-date
- * data buffers for open files, we re-open and re-read the file before
- * modifying it.  This will prevent lost updates.
+ * We track the revprop generation in a file that.
  *
  * A race condition exists between switching to the modified revprop data
  * and bumping the generation number.  In particular, the process may crash
@@ -95,110 +82,6 @@
  * after the crash, reader caches may be stale.
  */
 
-/* If the revprop generation file in FS is open, close it.  This is a no-op
- * if the file is not open.
- */
-static svn_error_t *
-close_revprop_generation_file(svn_fs_t *fs,
-                              apr_pool_t *scratch_pool)
-{
-  svn_fs_x__data_t *ffd = fs->fsap_data;
-  if (ffd->revprop_generation_file)
-    {
-      SVN_ERR(svn_io_file_close(ffd->revprop_generation_file, scratch_pool));
-      ffd->revprop_generation_file = NULL;
-    }
-
-  return SVN_NO_ERROR;
-}
-
-/* Make sure the revprop_generation member in FS is set.  If READ_ONLY is
- * set, open the file w/o write permission if the file is not open yet.
- * The file is kept open if it has sufficient rights (or more) but will be
- * closed and re-opened if it provided insufficient access rights.
- *
- * Call only for repos that support revprop caching.
- */
-static svn_error_t *
-open_revprop_generation_file(svn_fs_t *fs,
-                             svn_boolean_t read_only,
-                             apr_pool_t *scratch_pool)
-{
-  svn_fs_x__data_t *ffd = fs->fsap_data;
-  apr_int32_t flags = read_only ? APR_READ : (APR_READ | APR_WRITE);
-
-  /* Close the current file handle if it has insufficient rights. */
-  if (   ffd->revprop_generation_file
-      && (apr_file_flags_get(ffd->revprop_generation_file) & flags) != flags)
-    SVN_ERR(close_revprop_generation_file(fs, scratch_pool));
-
-  /* If not open already, open with sufficient rights. */
-  if (ffd->revprop_generation_file == NULL)
-    {
-      const char *path = svn_fs_x__path_revprop_generation(fs, scratch_pool);
-      SVN_ERR(svn_io_file_open(&ffd->revprop_generation_file, path,
-                               flags, APR_OS_DEFAULT, fs->pool));
-    }
-
-  return SVN_NO_ERROR;
-}
-
-/* Return the textual representation of NUMBER and its checksum in *BUFFER.
- */
-static svn_error_t *
-checkedsummed_number(svn_stringbuf_t **buffer,
-                     apr_int64_t number,
-                     apr_pool_t *result_pool,
-                     apr_pool_t *scratch_pool)
-{
-  svn_checksum_t *checksum;
-  const char *digest;
-
-  char str[SVN_INT64_BUFFER_SIZE];
-  apr_size_t len = svn__i64toa(str, number);
-  str[len] = 0;
-
-  SVN_ERR(svn_checksum(&checksum, svn_checksum_md5, str, len, scratch_pool));
-  digest = svn_checksum_to_cstring_display(checksum, scratch_pool);
-
-  *buffer = svn_stringbuf_createf(result_pool, "%s %s\n", digest, str);
-
-  return SVN_NO_ERROR;
-}
-
-/* Extract the generation number from the text BUFFER of LEN bytes and
- * verify it against the checksum in the same BUFFER.  If they match, return
- * the generation in *NUMBER.  Otherwise, return an error.
- * BUFFER does not need to be NUL-terminated.
- */
-static svn_error_t *
-verify_extract_number(apr_int64_t *number,
-                      const char *buffer,
-                      apr_size_t len,
-                      apr_pool_t *scratch_pool)
-{
-  const char *digest_end = strchr(buffer, ' ');
-
-  /* Does the buffer even contain checksum _and_ number? */
-  if (digest_end != NULL)
-    {
-      svn_checksum_t *expected;
-      svn_checksum_t *actual;
-
-      SVN_ERR(svn_checksum_parse_hex(&expected, svn_checksum_md5, buffer,
-                                     scratch_pool));
-      SVN_ERR(svn_checksum(&actual, svn_checksum_md5, digest_end + 1,
-                           (buffer + len) - (digest_end + 1), scratch_pool));
-
-      if (svn_checksum_match(expected, actual))
-        return svn_error_trace(svn_cstring_atoi64(number, digest_end + 1));
-    }
-
-  /* Incomplete buffer or not a match. */
-  return svn_error_create(SVN_ERR_FS_INVALID_GENERATION, NULL,
-                          _("Invalid generation number data."));
-}
-
 /* Read revprop generation as stored on disk for repository FS. The result is
  * returned in *CURRENT.  Call only for repos that support revprop caching.
  */
@@ -207,46 +90,32 @@ read_revprop_generation_file(apr_int64_t
                              svn_fs_t *fs,
                              apr_pool_t *scratch_pool)
 {
-  svn_fs_x__data_t *ffd = fs->fsap_data;
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
-  char buf[CHECKSUMMED_NUMBER_BUFFER_LEN];
-  apr_size_t len;
-  apr_off_t offset = 0;
   int i;
   svn_error_t *err = SVN_NO_ERROR;
+  const char *path = svn_fs_x__path_revprop_generation(fs, scratch_pool);
 
   /* Retry in case of incomplete file buffer updates. */
   for (i = 0; i < GENERATION_READ_RETRY_COUNT; ++i)
     {
+      svn_stringbuf_t *buf;
+
       svn_error_clear(err);
       svn_pool_clear(iterpool);
 
-      /* If we can't even access the data, things are very wrong.
-       * Don't retry in that case.
-       */
-      SVN_ERR(open_revprop_generation_file(fs, TRUE, iterpool));
-      SVN_ERR(svn_io_file_seek(ffd->revprop_generation_file, APR_SET, &offset,
-                              iterpool));
-
-      len = sizeof(buf);
-      SVN_ERR(svn_io_file_read(ffd->revprop_generation_file, buf, &len,
-                               iterpool));
-      /* Properly terminate the string we just read.  Valid contents ends
-         with a '\n'.  Empty the buffer in all other cases. */
-      if (len > 0 && buf[len-1] == '\n')
-        buf[--len] = '\0';
-      else
-        buf[0] = '\0';
-
-      /* Some data has been read.  It will most likely be complete and
-       * consistent.  Extract and verify anyway. */
-      err = verify_extract_number(current, buf, len, iterpool);
-      if (!err)
-        break;
+      /* Read the generation file. */
+      err = svn_stringbuf_from_file2(&buf, path, iterpool);
 
-      /* Got unlucky and data was invalid.  Retry. */
-      SVN_ERR(close_revprop_generation_file(fs, iterpool));
+      /* If we could read the file, it should be complete due to our atomic
+       * file replacement scheme. */
+      if (!err)
+        {
+          svn_stringbuf_strip_whitespace(buf);
+          SVN_ERR(svn_cstring_atoi64(current, buf->data));
+          break;
+        }
 
+      /* Got unlucky the file was not available.  Retry. */
 #if APR_HAS_THREADS
       apr_thread_yield();
 #else
@@ -270,17 +139,21 @@ write_revprop_generation_file(svn_fs_t *
 {
   svn_fs_x__data_t *ffd = fs->fsap_data;
   svn_stringbuf_t *buffer;
-  apr_off_t offset = 0;
+  const char *path = svn_fs_x__path_revprop_generation(fs, scratch_pool);
 
-  SVN_ERR(checkedsummed_number(&buffer, current, scratch_pool, scratch_pool));
+  /* Invalidate our cached revprop generation in case the file operations
+   * below fail. */
+  ffd->revprop_generation = -1;
+
+  /* Write the new number. */
+  buffer = svn_stringbuf_createf(scratch_pool, "%" APR_INT64_T_FMT "\n",
+                                 current);
+  SVN_ERR(svn_io_write_atomic2(path, buffer->data, buffer->len,
+                               path /* copy_perms */, TRUE,
+                               scratch_pool));
 
-  SVN_ERR(open_revprop_generation_file(fs, FALSE, scratch_pool));
-  SVN_ERR(svn_io_file_seek(ffd->revprop_generation_file, APR_SET, &offset,
-                           scratch_pool));
-  SVN_ERR(svn_io_file_write_full(ffd->revprop_generation_file, buffer->data,
-                                 buffer->len, NULL, scratch_pool));
-  SVN_ERR(svn_io_file_flush_to_disk(ffd->revprop_generation_file,
-                                    scratch_pool));
+  /* Remember it to spare us the re-read. */
+  ffd->revprop_generation = current;
 
   return SVN_NO_ERROR;
 }
@@ -289,49 +162,12 @@ svn_error_t *
 svn_fs_x__reset_revprop_generation_file(svn_fs_t *fs,
                                         apr_pool_t *scratch_pool)
 {
-  const char *path = svn_fs_x__path_revprop_generation(fs, scratch_pool);
-  svn_stringbuf_t *buffer;
-
-  /* Unconditionally close the revprop generation file.
-   * Don't care about FS formats. This ensures consistent internal state. */
-  SVN_ERR(close_revprop_generation_file(fs, scratch_pool));
-
-  /* Unconditionally remove any old revprop generation file.
-   * Don't care about FS formats.  This ensures consistent on-disk state
-   * for old format repositories. */
-  SVN_ERR(svn_io_remove_file2(path, TRUE, scratch_pool));
-
-  /* Write the initial revprop generation file contents, if supported by
-   * the current format.  This ensures consistent on-disk state for new
-   * format repositories. */
-  SVN_ERR(checkedsummed_number(&buffer, 0, scratch_pool, scratch_pool));
-  SVN_ERR(svn_io_write_atomic2(path, buffer->data, buffer->len, NULL,
-                               TRUE, scratch_pool));
-
-  /* ffd->revprop_generation_file will be re-opened on demand. */
+  /* Write the initial revprop generation file contents. */
+  SVN_ERR(write_revprop_generation_file(fs, 0, scratch_pool));
 
   return SVN_NO_ERROR;
 }
 
-/* Create an error object with the given MESSAGE and pass it to the
-   WARNING member of FS. Clears UNDERLYING_ERR. */
-static void
-log_revprop_cache_init_warning(svn_fs_t *fs,
-                               svn_error_t *underlying_err,
-                               const char *message,
-                               apr_pool_t *scratch_pool)
-{
-  svn_error_t *err = svn_error_createf(
-                       SVN_ERR_FS_REVPROP_CACHE_INIT_FAILURE,
-                       underlying_err, message,
-                       svn_dirent_local_style(fs->path, scratch_pool));
-
-  if (fs->warning)
-    (fs->warning)(fs->warning_baton, err);
-
-  svn_error_clear(err);
-}
-
 /* Test whether revprop cache and necessary infrastructure are
    available in FS. */
 static svn_boolean_t
@@ -339,29 +175,9 @@ has_revprop_cache(svn_fs_t *fs,
                   apr_pool_t *scratch_pool)
 {
   svn_fs_x__data_t *ffd = fs->fsap_data;
-  svn_error_t *error;
-
-  /* is the cache (still) enabled? */
-  if (ffd->revprop_cache == NULL)
-    return FALSE;
-
-  /* try initialize our file-backed infrastructure */
-  error = open_revprop_generation_file(fs, TRUE, scratch_pool);
-  if (error)
-    {
-      /* failure -> disable revprop cache for good */
-
-      ffd->revprop_cache = NULL;
-      log_revprop_cache_init_warning(fs, error,
-                                     "Revprop caching for '%s' disabled "
-                                     "because infrastructure for revprop "
-                                     "caching failed to initialize.",
-                                     scratch_pool);
-
-      return FALSE;
-    }
 
-  return TRUE;
+  /* is the cache enabled? */
+  return ffd->revprop_cache != NULL;
 }
 
 /* Baton structure for revprop_generation_fixup. */
@@ -389,9 +205,6 @@ revprop_generation_fixup(void *void_bato
   svn_fs_x__data_t *ffd = baton->fs->fsap_data;
   assert(ffd->has_write_lock);
 
-  /* Make sure we don't operate on stale OS buffers. */
-  SVN_ERR(close_revprop_generation_file(baton->fs, scratch_pool));
-
   /* Maybe, either the original revprop writer or some other reader has
      already corrected / bumped the revprop generation.  Thus, we need
      to read it again.  However, we will now be the only ones changing
@@ -412,12 +225,10 @@ revprop_generation_fixup(void *void_bato
   return SVN_NO_ERROR;
 }
 
-/* Read the current revprop generation and return it in *GENERATION.
-   Also, detect aborted / crashed writers and recover from that.
-   Use the access object in FS to set the shared mem values. */
+/* Read the current revprop generation of FS and its value in FS->FSAP_DATA.
+   Also, detect aborted / crashed writers and recover from that. */
 static svn_error_t *
-read_revprop_generation(apr_int64_t *generation,
-                        svn_fs_t *fs,
+read_revprop_generation(svn_fs_t *fs,
                         apr_pool_t *scratch_pool)
 {
   apr_int64_t current = 0;
@@ -462,56 +273,68 @@ read_revprop_generation(apr_int64_t *gen
     }
 
   /* return the value we just got */
-  *generation = current;
+  ffd->revprop_generation = current;
   return SVN_NO_ERROR;
 }
 
+void
+svn_fs_x__invalidate_revprop_generation(svn_fs_t *fs)
+{
+  svn_fs_x__data_t *ffd = fs->fsap_data;
+  ffd->revprop_generation = -1;
+}
+
+/* Return TRUE if the revprop generation value in FS->FSAP_DATA is valid. */
+static svn_boolean_t
+is_generation_valid(svn_fs_t *fs)
+{
+  svn_fs_x__data_t *ffd = fs->fsap_data;
+  return ffd->revprop_generation >= 0;
+}
+
 /* Set the revprop generation in FS to the next odd number to indicate
-   that there is a revprop write process under way.  Return that value
-   in *GENERATION.  If the change times out, readers shall recover from
-   that state & re-read revprops.
+   that there is a revprop write process under way.  Update the value
+   in FS->FSAP_DATA accordingly.  If the change times out, readers shall
+   recover from that state & re-read revprops.
    This is a no-op for repo formats that don't support revprop caching. */
 static svn_error_t *
-begin_revprop_change(apr_int64_t *generation,
-                     svn_fs_t *fs,
+begin_revprop_change(svn_fs_t *fs,
                      apr_pool_t *scratch_pool)
 {
   svn_fs_x__data_t *ffd = fs->fsap_data;
   SVN_ERR_ASSERT(ffd->has_write_lock);
 
-  /* Close and re-open to make sure we read the latest data. */
-  SVN_ERR(close_revprop_generation_file(fs, scratch_pool));
-  SVN_ERR(open_revprop_generation_file(fs, FALSE, scratch_pool));
-
   /* Set the revprop generation to an odd value to indicate
    * that a write is in progress.
    */
-  SVN_ERR(read_revprop_generation(generation, fs, scratch_pool));
-  ++*generation;
-  SVN_ERR(write_revprop_generation_file(fs, *generation, scratch_pool));
+  SVN_ERR(read_revprop_generation(fs, scratch_pool));
+  ++ffd->revprop_generation;
+  SVN_ERR_ASSERT(ffd->revprop_generation % 2);
+  SVN_ERR(write_revprop_generation_file(fs, ffd->revprop_generation,
+                                        scratch_pool));
 
   return SVN_NO_ERROR;
 }
 
 /* Set the revprop generation in FS to the next even generation after
-   the odd value in GENERATION to indicate that
+   the odd value in FS->FSAP_DATA to indicate that
    a) readers shall re-read revprops, and
    b) the write process has been completed (no recovery required).
    This is a no-op for repo formats that don't support revprop caching. */
 static svn_error_t *
 end_revprop_change(svn_fs_t *fs,
-                   apr_int64_t generation,
                    apr_pool_t *scratch_pool)
 {
   svn_fs_x__data_t *ffd = fs->fsap_data;
   SVN_ERR_ASSERT(ffd->has_write_lock);
-  SVN_ERR_ASSERT(generation % 2);
+  SVN_ERR_ASSERT(ffd->revprop_generation % 2);
 
   /* Set the revprop generation to an even value to indicate
    * that a write has been completed.  Since we held the write
    * lock, nobody else could have updated the file contents.
    */
-  SVN_ERR(write_revprop_generation_file(fs, generation + 1, scratch_pool));
+  SVN_ERR(write_revprop_generation_file(fs, ffd->revprop_generation + 1,
+                                        scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -525,9 +348,6 @@ typedef struct packed_revprops_t
   /* revision number to read (not necessarily the first in the pack) */
   svn_revnum_t revision;
 
-  /* current revprop generation. Used when populating the revprop cache */
-  apr_int64_t generation;
-
   /* the actual revision properties */
   apr_hash_t *properties;
 
@@ -571,8 +391,7 @@ typedef struct packed_revprops_t
 /* Parse the serialized revprops in CONTENT and return them in *PROPERTIES.
  * Also, put them into the revprop cache, if activated, for future use.
  * Three more parameters are being used to update the revprop cache: FS is
- * our file system, the revprops belong to REVISION and the global revprop
- * GENERATION is used as well.
+ * our file system, the revprops belong to REVISION.
  *
  * The returned hash will be allocated in RESULT_POOL, SCRATCH_POOL is
  * being used for temporary allocations.
@@ -581,7 +400,6 @@ static svn_error_t *
 parse_revprop(apr_hash_t **properties,
               svn_fs_t *fs,
               svn_revnum_t revision,
-              apr_int64_t generation,
               svn_string_t *content,
               apr_pool_t *result_pool,
               apr_pool_t *scratch_pool)
@@ -596,8 +414,10 @@ parse_revprop(apr_hash_t **properties,
       svn_fs_x__data_t *ffd = fs->fsap_data;
       svn_fs_x__pair_cache_key_t key = { 0 };
 
+      SVN_ERR_ASSERT(is_generation_valid(fs));
+
       key.revision = revision;
-      key.second = generation;
+      key.second = ffd->revprop_generation;
       SVN_ERR(svn_cache__set(ffd->revprop_cache, &key, *properties,
                              scratch_pool));
     }
@@ -606,8 +426,7 @@ parse_revprop(apr_hash_t **properties,
 }
 
 /* Read the non-packed revprops for revision REV in FS, put them into the
- * revprop cache if activated and return them in *PROPERTIES.  GENERATION
- * is the current revprop generation.
+ * revprop cache if activated and return them in *PROPERTIES.
  *
  * If the data could not be read due to an otherwise recoverable error,
  * leave *PROPERTIES unchanged. No error will be returned in that case.
@@ -618,7 +437,6 @@ static svn_error_t *
 read_non_packed_revprop(apr_hash_t **properties,
                         svn_fs_t *fs,
                         svn_revnum_t rev,
-                        apr_int64_t generation,
                         apr_pool_t *result_pool,
                         apr_pool_t *scratch_pool)
 {
@@ -640,7 +458,7 @@ read_non_packed_revprop(apr_hash_t **pro
     }
 
   if (content)
-    SVN_ERR(parse_revprop(properties, fs, rev, generation,
+    SVN_ERR(parse_revprop(properties, fs, rev,
                           svn_stringbuf__morph_into_string(content),
                           result_pool, iterpool));
 
@@ -887,8 +705,7 @@ parse_packed_revprops(svn_fs_t *fs,
         {
           /* Parse (and possibly cache) the one revprop list we care about. */
           SVN_ERR(parse_revprop(&revprops->properties, fs, revision,
-                                revprops->generation, &serialized,
-                                result_pool, iterpool));
+                                &serialized, result_pool, iterpool));
           revprops->serialized_size = serialized.len;
 
           /* If we only wanted the revprops for REVISION then we are done. */
@@ -899,8 +716,7 @@ parse_packed_revprops(svn_fs_t *fs,
         {
           /* Parse and cache all other revprop lists. */
           apr_hash_t *properties;
-          SVN_ERR(parse_revprop(&properties, fs, revision,
-                                revprops->generation, &serialized,
+          SVN_ERR(parse_revprop(&properties, fs, revision, &serialized,
                                 iterpool, iterpool));
         }
 
@@ -919,9 +735,9 @@ parse_packed_revprops(svn_fs_t *fs,
 }
 
 /* In filesystem FS, read the packed revprops for revision REV into
- * *REVPROPS.  Use GENERATION to populate the revprop cache, if enabled.
- * If you want to modify revprop contents / update REVPROPS, READ_ALL
- * must be set.  Otherwise, only the properties of REV are being provided.
+ * *REVPROPS.  Populate the revprop cache, if enabled.  If you want to
+ * modify revprop contents / update REVPROPS, READ_ALL must be set.
+ * Otherwise, only the properties of REV are being provided.
  *
  * Allocate *PROPERTIES in RESULT_POOL and temporaries in SCRATCH_POOL.
  */
@@ -929,7 +745,6 @@ static svn_error_t *
 read_pack_revprop(packed_revprops_t **revprops,
                   svn_fs_t *fs,
                   svn_revnum_t rev,
-                  apr_int64_t generation,
                   svn_boolean_t read_all,
                   apr_pool_t *result_pool,
                   apr_pool_t *scratch_pool)
@@ -951,7 +766,6 @@ read_pack_revprop(packed_revprops_t **re
   /* initialize the result data structure */
   result = apr_pcalloc(result_pool, sizeof(*result));
   result->revision = rev;
-  result->generation = generation;
 
   /* try to read the packed revprops. This may require retries if we have
    * concurrent writers. */
@@ -981,7 +795,7 @@ read_pack_revprop(packed_revprops_t **re
        * consider it outdated, otherwise.
        */
       if (missing && has_revprop_cache(fs, iterpool))
-        SVN_ERR(read_revprop_generation(&result->generation, fs, iterpool));
+        SVN_ERR(read_revprop_generation(fs, iterpool));
     }
 
   /* the file content should be available now */
@@ -1001,20 +815,16 @@ read_pack_revprop(packed_revprops_t **re
   return SVN_NO_ERROR;
 }
 
-/* Read the revprops for revision REV in FS and return them in *PROPERTIES_P.
- *
- * Allocations will be done in POOL.
- */
 svn_error_t *
 svn_fs_x__get_revision_proplist(apr_hash_t **proplist_p,
                                 svn_fs_t *fs,
                                 svn_revnum_t rev,
                                 svn_boolean_t bypass_cache,
+                                svn_boolean_t refresh,
                                 apr_pool_t *result_pool,
                                 apr_pool_t *scratch_pool)
 {
   svn_fs_x__data_t *ffd = fs->fsap_data;
-  apr_int64_t generation = 0;
 
   /* not found, yet */
   *proplist_p = NULL;
@@ -1022,16 +832,18 @@ svn_fs_x__get_revision_proplist(apr_hash
   /* should they be available at all? */
   SVN_ERR(svn_fs_x__ensure_revision_exists(rev, fs, scratch_pool));
 
+  /* Ensure that the revprop generation info is valid. */
+  if (refresh || !is_generation_valid(fs))
+    SVN_ERR(read_revprop_generation(fs, scratch_pool));
+
   /* Try cache lookup first. */
   if (!bypass_cache && has_revprop_cache(fs, scratch_pool))
     {
       svn_boolean_t is_cached;
       svn_fs_x__pair_cache_key_t key = { 0 };
 
-      SVN_ERR(read_revprop_generation(&generation, fs, scratch_pool));
-
       key.revision = rev;
-      key.second = generation;
+      key.second = ffd->revprop_generation;
       SVN_ERR(svn_cache__get((void **) proplist_p, &is_cached,
                              ffd->revprop_cache, &key, result_pool));
       if (is_cached)
@@ -1044,8 +856,7 @@ svn_fs_x__get_revision_proplist(apr_hash
   if (!svn_fs_x__is_packed_revprop(fs, rev))
     {
       svn_error_t *err = read_non_packed_revprop(proplist_p, fs, rev,
-                                                 generation, result_pool,
-                                                 scratch_pool);
+                                                 result_pool, scratch_pool);
       if (err)
         {
           if (!APR_STATUS_IS_ENOENT(err->apr_err))
@@ -1062,7 +873,7 @@ svn_fs_x__get_revision_proplist(apr_hash
   if (!*proplist_p)
     {
       packed_revprops_t *revprops;
-      SVN_ERR(read_pack_revprop(&revprops, fs, rev, generation, FALSE,
+      SVN_ERR(read_pack_revprop(&revprops, fs, rev, FALSE,
                                 result_pool, scratch_pool));
       *proplist_p = revprops->properties;
     }
@@ -1135,19 +946,17 @@ switch_to_new_revprop(svn_fs_t *fs,
                       svn_boolean_t bump_generation,
                       apr_pool_t *scratch_pool)
 {
-  apr_int64_t generation;
-
   /* Now, we may actually be replacing revprops. Make sure that all other
      threads and processes will know about this. */
   if (bump_generation)
-    SVN_ERR(begin_revprop_change(&generation, fs, scratch_pool));
+    SVN_ERR(begin_revprop_change(fs, scratch_pool));
 
   SVN_ERR(svn_fs_x__move_into_place(tmp_path, final_path, perms_reference,
                                     scratch_pool));
 
   /* Indicate that the update (if relevant) has been completed. */
   if (bump_generation)
-    SVN_ERR(end_revprop_change(fs, generation, scratch_pool));
+    SVN_ERR(end_revprop_change(fs, scratch_pool));
 
   /* Clean up temporary files, if necessary. */
   if (files_to_delete)
@@ -1369,7 +1178,6 @@ write_packed_revprop(const char **final_
 {
   svn_fs_x__data_t *ffd = fs->fsap_data;
   packed_revprops_t *revprops;
-  apr_int64_t generation = 0;
   svn_stream_t *stream;
   apr_file_t *file;
   svn_stringbuf_t *serialized;
@@ -1379,10 +1187,10 @@ write_packed_revprop(const char **final_
   /* read the current revprop generation. This value will not change
    * while we hold the global write lock to this FS. */
   if (has_revprop_cache(fs, scratch_pool))
-    SVN_ERR(read_revprop_generation(&generation, fs, scratch_pool));
+    SVN_ERR(read_revprop_generation(fs, scratch_pool));
 
   /* read contents of the current pack file */
-  SVN_ERR(read_pack_revprop(&revprops, fs, rev, generation, TRUE,
+  SVN_ERR(read_pack_revprop(&revprops, fs, rev, TRUE,
                             scratch_pool, scratch_pool));
 
   /* serialize the new revprops */

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_x/revprops.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_x/revprops.h?rev=1709538&r1=1709537&r2=1709538&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_x/revprops.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_x/revprops.h Tue Oct 20 08:43:19 2015
@@ -39,8 +39,15 @@ svn_error_t *
 svn_fs_x__reset_revprop_generation_file(svn_fs_t *fs,
                                         apr_pool_t *scratch_pool);
 
+/* Invalidate the cached revprop generation value in FS->FSAP_DATA.
+ * This enforces a re-read upon the next revprop read. */
+void
+svn_fs_x__invalidate_revprop_generation(svn_fs_t *fs);
+
 /* Read the revprops for revision REV in FS and return them in *PROPLIST_P.
  * If BYPASS_CACHE is set, don't consult the disks but always read from disk.
+ * If REFRESH is set, update the revprop generation info; otherwise access
+ * potentially outdated cache data directly.
  *
  * Allocate the *PROPLIST_P in RESULT_POOL and use SCRATCH_POOL for temporary
  * allocations.
@@ -50,6 +57,7 @@ svn_fs_x__get_revision_proplist(apr_hash
                                 svn_fs_t *fs,
                                 svn_revnum_t rev,
                                 svn_boolean_t bypass_cache,
+                                svn_boolean_t refresh,
                                 apr_pool_t *result_pool,
                                 apr_pool_t *scratch_pool);
 

Modified: subversion/branches/move-tracking-2/subversion/libsvn_fs_x/verify.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_fs_x/verify.c?rev=1709538&r1=1709537&r2=1709538&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_fs_x/verify.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_fs_x/verify.c Tue Oct 20 08:43:19 2015
@@ -701,7 +701,7 @@ verify_revprops(svn_fs_t *fs,
       /* Access the svn:date revprop.
        * This implies parsing all revprops for that revision. */
       SVN_ERR(svn_fs_x__revision_prop(&date, fs, revision,
-                                      SVN_PROP_REVISION_DATE,
+                                      SVN_PROP_REVISION_DATE, TRUE,
                                       iterpool, iterpool));
 
       /* The time stamp is the only revprop that, if given, needs to

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=1709538&r1=1709537&r2=1709538&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_repos/delta.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_repos/delta.c Tue Oct 20 08:43:19 2015
@@ -530,8 +530,8 @@ delta_proplists(struct context *c,
       svn_boolean_t changed;
 
       /* Is this deltification worth our time? */
-      SVN_ERR(svn_fs_props_different(&changed, c->target_root, target_path,
-                                     c->source_root, source_path, subpool));
+      SVN_ERR(svn_fs_props_changed(&changed, c->target_root, target_path,
+                                   c->source_root, source_path, subpool));
       if (! changed)
         goto cleanup;
 
@@ -611,8 +611,62 @@ svn_repos__compare_files(svn_boolean_t *
                          const char *path2,
                          apr_pool_t *pool)
 {
-  return svn_error_trace(svn_fs_contents_different(changed_p, root1, path1,
-                                                   root2, path2, pool));
+  svn_filesize_t size1, size2;
+  svn_checksum_t *checksum1, *checksum2;
+  svn_stream_t *stream1, *stream2;
+  svn_boolean_t same;
+
+  /* If the filesystem claims the things haven't changed, then they
+     haven't changed. */
+  SVN_ERR(svn_fs_contents_changed(changed_p, root1, path1,
+                                  root2, path2, pool));
+  if (!*changed_p)
+    return SVN_NO_ERROR;
+
+  /* If the SHA1 checksums match for these things, we'll claim they
+     have the same contents.  (We don't give quite as much weight to
+     MD5 checksums.)  */
+  SVN_ERR(svn_fs_file_checksum(&checksum1, svn_checksum_sha1,
+                               root1, path1, FALSE, pool));
+  SVN_ERR(svn_fs_file_checksum(&checksum2, svn_checksum_sha1,
+                               root2, path2, FALSE, pool));
+  if (checksum1 && checksum2)
+    {
+      *changed_p = !svn_checksum_match(checksum1, checksum2);
+      return SVN_NO_ERROR;
+    }
+
+  /* From this point on, our default answer is "Nothing's changed". */
+  *changed_p = FALSE;
+
+  /* Different filesizes means the contents are different. */
+  SVN_ERR(svn_fs_file_length(&size1, root1, path1, pool));
+  SVN_ERR(svn_fs_file_length(&size2, root2, path2, pool));
+  if (size1 != size2)
+    {
+      *changed_p = TRUE;
+      return SVN_NO_ERROR;
+    }
+
+  /* Different MD5 checksums means the contents are different. */
+  SVN_ERR(svn_fs_file_checksum(&checksum1, svn_checksum_md5, root1, path1,
+                               FALSE, pool));
+  SVN_ERR(svn_fs_file_checksum(&checksum2, svn_checksum_md5, root2, path2,
+                               FALSE, pool));
+  if (!svn_checksum_match(checksum1, checksum2))
+    {
+      *changed_p = TRUE;
+      return SVN_NO_ERROR;
+    }
+
+  /* And finally, different contents means the ... uh ... contents are
+     different. */
+  SVN_ERR(svn_fs_file_contents(&stream1, root1, path1, pool));
+  SVN_ERR(svn_fs_file_contents(&stream2, root2, path2, pool));
+  SVN_ERR(svn_stream_contents_same2(&same, stream1, stream2, pool));
+  *changed_p = !same;
+
+  return SVN_NO_ERROR;
 }
 
 
@@ -639,7 +693,19 @@ delta_files(struct context *c,
 
   if (source_path)
     {
-      SVN_ERR(svn_fs_contents_different(&changed,
+      /* Is this delta calculation worth our time?  If we are ignoring
+         ancestry, then our editor implementor isn't concerned by the
+         theoretical differences between "has contents which have not
+         changed with respect to" and "has the same actual contents
+         as".  We'll do everything we can to avoid transmitting even
+         an empty text-delta in that case.  */
+      if (c->ignore_ancestry)
+        SVN_ERR(svn_repos__compare_files(&changed,
+                                         c->target_root, target_path,
+                                         c->source_root, source_path,
+                                         subpool));
+      else
+        SVN_ERR(svn_fs_contents_changed(&changed,
                                         c->target_root, target_path,
                                         c->source_root, source_path,
                                         subpool));

Modified: subversion/branches/move-tracking-2/subversion/libsvn_repos/dump.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_repos/dump.c?rev=1709538&r1=1709537&r2=1709538&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_repos/dump.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_repos/dump.c Tue Oct 20 08:43:19 2015
@@ -1164,13 +1164,13 @@ dump_node(struct edit_baton *eb,
                                    svn_fs_root_fs(eb->fs_root),
                                    compare_rev, pool));
 
-      SVN_ERR(svn_fs_props_different(&must_dump_props,
-                                     compare_root, compare_path,
-                                     eb->fs_root, path, pool));
+      SVN_ERR(svn_fs_props_changed(&must_dump_props,
+                                   compare_root, compare_path,
+                                   eb->fs_root, path, pool));
       if (kind == svn_node_file)
-        SVN_ERR(svn_fs_contents_different(&must_dump_text,
-                                          compare_root, compare_path,
-                                          eb->fs_root, path, pool));
+        SVN_ERR(svn_fs_contents_changed(&must_dump_text,
+                                        compare_root, compare_path,
+                                        eb->fs_root, path, pool));
       break;
 
     case svn_node_action_delete:
@@ -1293,16 +1293,16 @@ dump_node(struct edit_baton *eb,
 
           /* Need to decide if the copied node had any extra textual or
              property mods as well.  */
-          SVN_ERR(svn_fs_props_different(&must_dump_props,
-                                         compare_root, compare_path,
-                                         eb->fs_root, path, pool));
+          SVN_ERR(svn_fs_props_changed(&must_dump_props,
+                                       compare_root, compare_path,
+                                       eb->fs_root, path, pool));
           if (kind == svn_node_file)
             {
               svn_checksum_t *checksum;
               const char *hex_digest;
-              SVN_ERR(svn_fs_contents_different(&must_dump_text,
-                                                compare_root, compare_path,
-                                                eb->fs_root, path, pool));
+              SVN_ERR(svn_fs_contents_changed(&must_dump_text,
+                                              compare_root, compare_path,
+                                              eb->fs_root, path, pool));
 
               SVN_ERR(svn_fs_file_checksum(&checksum, svn_checksum_md5,
                                            compare_root, compare_path,

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=1709538&r1=1709537&r2=1709538&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_repos/reporter.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_repos/reporter.c Tue Oct 20 08:43:19 2015
@@ -578,8 +578,8 @@ delta_proplists(report_baton_t *b, svn_r
       SVN_ERR(get_source_root(b, &s_root, s_rev));
 
       /* Is this deltification worth our time? */
-      SVN_ERR(svn_fs_props_different(&changed, b->t_root, t_path, s_root,
-                                     s_path, pool));
+      SVN_ERR(svn_fs_props_changed(&changed, b->t_root, t_path, s_root,
+                                   s_path, pool));
       if (! changed)
         return SVN_NO_ERROR;
 

Modified: subversion/branches/move-tracking-2/subversion/libsvn_repos/rev_hunt.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_repos/rev_hunt.c?rev=1709538&r1=1709537&r2=1709538&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_repos/rev_hunt.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_repos/rev_hunt.c Tue Oct 20 08:43:19 2015
@@ -1374,31 +1374,17 @@ send_path_revision(struct path_revision
   SVN_ERR(svn_prop_diffs(&prop_diffs, props, sb->last_props,
                          sb->iterpool));
 
-  /* Check if the contents *may* have changed. */
+  /* Check if the contents changed. */
   if (! sb->last_root)
     {
       /* Special case: In the first revision, we always provide a delta. */
       contents_changed = TRUE;
     }
-  else if (sb->include_merged_revisions
-           && strcmp(sb->last_path, path_rev->path))
-    {
-      /* ### This is a HACK!!!
-       * Blame -g, in older clients anyways, relies on getting a notification
-       * whenever the path changes - even if there was no content change.
-       *
-       * TODO: A future release should take an extra parameter and depending
-       * on that either always send a text delta or only send it if there
-       * is a difference. */
-      contents_changed = TRUE;
-    }
   else
     {
-      /* Did the file contents actually change?
-       * It could e.g. be a property-only change. */
-      SVN_ERR(svn_fs_contents_different(&contents_changed, sb->last_root,
-                                        sb->last_path, root, path_rev->path,
-                                        sb->iterpool));
+      SVN_ERR(svn_fs_contents_changed(&contents_changed, sb->last_root,
+                                      sb->last_path, root, path_rev->path,
+                                      sb->iterpool));
     }
 
   /* We have all we need, give to the handler. */

Modified: subversion/branches/move-tracking-2/subversion/mod_authz_svn/mod_authz_svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/mod_authz_svn/mod_authz_svn.c?rev=1709538&r1=1709537&r2=1709538&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/mod_authz_svn/mod_authz_svn.c (original)
+++ subversion/branches/move-tracking-2/subversion/mod_authz_svn/mod_authz_svn.c Tue Oct 20 08:43:19 2015
@@ -954,19 +954,21 @@ access_checker(request_rec *r)
 #if USE_FORCE_AUTHN
       if (authn_configured) {
           /* We have to check to see if authn is required because if so we must
-           * return UNAUTHORIZED (401) rather than FORBIDDEN (403) since returning
+           * return DECLINED rather than FORBIDDEN (403) since returning
            * the 403 leaks information about what paths may exist to
-           * unauthenticated users.  We must set a note here in order
-           * to use ap_some_authn_rquired() without triggering an infinite
-           * loop since the call will trigger this function to be called again. */
+           * unauthenticated users.  Returning DECLINED means apache's request
+           * handling will continue until the authn module itself generates
+           * UNAUTHORIZED (401).
+
+           * We must set a note here in order to use
+           * ap_some_authn_rquired() without triggering an infinite
+           * loop since the call will trigger this function to be
+           * called again. */
           apr_table_setn(r->notes, IN_SOME_AUTHN_NOTE, (const char*)1);
           authn_required = ap_some_authn_required(r);
           apr_table_unset(r->notes, IN_SOME_AUTHN_NOTE);
           if (authn_required)
-            {
-              ap_note_auth_failure(r);
-              return HTTP_UNAUTHORIZED;
-            }
+            return DECLINED;
       }
 #else
       if (!authn_required)

Modified: subversion/branches/move-tracking-2/subversion/po/es.po
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/po/es.po?rev=1709538&r1=1709537&r2=1709538&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/po/es.po [UTF-8] (original)
+++ subversion/branches/move-tracking-2/subversion/po/es.po [UTF-8] Tue Oct 20 08:43:19 2015
@@ -10197,13 +10197,11 @@ msgid "local %s, incoming %s upon %s"
 msgstr ""
 
 #: ../svn/util.c:74
-#, fuzzy, c-format
+#, c-format
 msgid ""
-"\n"
 "Committed revision %ld%s.\n"
 msgstr ""
-"\n"
-"Commit de la revisión %ld.\n"
+"Commit de la revisión %ld%s.\n"
 
 #: ../svn/util.c:78
 msgid " (the answer to life, the universe, and everything)"

Modified: subversion/branches/move-tracking-2/subversion/po/fr.po
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/po/fr.po?rev=1709538&r1=1709537&r2=1709538&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/po/fr.po [UTF-8] (original)
+++ subversion/branches/move-tracking-2/subversion/po/fr.po [UTF-8] Tue Oct 20 08:43:19 2015
@@ -11331,6 +11331,11 @@ msgstr "Mise à jour de '%s'\n"
 msgid "Redirecting to URL '%s':\n"
 msgstr "Redirection vers l'URL '%s' :\n"
 
+#: ../svn/notify.c:1066
+#, c-format
+msgid "Committing transaction...\n"
+msgstr "Transaction de propagation...\n"
+
 #: ../svn/propdel-cmd.c:88
 #, c-format
 msgid "Cannot specify revision for deleting versioned property '%s'"
@@ -11543,10 +11548,8 @@ msgstr "'%s' actualisé à la révision
 #: ../svn/util.c:76
 #, c-format
 msgid ""
-"\n"
 "Committed revision %ld%s.\n"
 msgstr ""
-"\n"
 "Révision %ld%s propagée.\n"
 
 #: ../svn/util.c:80

Modified: subversion/branches/move-tracking-2/subversion/po/it.po
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/po/it.po?rev=1709538&r1=1709537&r2=1709538&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/po/it.po (original)
+++ subversion/branches/move-tracking-2/subversion/po/it.po Tue Oct 20 08:43:19 2015
@@ -10283,19 +10283,17 @@ msgstr ""
 #: ../svn/tree-conflicts.c:107
 #, c-format
 msgid "local %s, incoming %s upon %s"
-msgstr ""
-
-#: ../svn/util.c:74
-#, fuzzy, c-format
-msgid ""
-"\n"
-"Committed revision %ld%s.\n"
-msgstr ""
-"\n"
-"Commit della Revisione %ld eseguito.\n"
-
-#: ../svn/util.c:78
-msgid " (the answer to life, the universe, and everything)"
+msgstr ""
+
+#: ../svn/util.c:74
+#, c-format
+msgid ""
+"Committed revision %ld%s.\n"
+msgstr ""
+"Commit della Revisione %ld%s eseguito.\n"
+
+#: ../svn/util.c:78
+msgid " (the answer to life, the universe, and everything)"
 msgstr ""
 
 #: ../svn/util.c:87

Modified: subversion/branches/move-tracking-2/subversion/po/ja.po
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/po/ja.po?rev=1709538&r1=1709537&r2=1709538&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/po/ja.po [UTF-8] (original)
+++ subversion/branches/move-tracking-2/subversion/po/ja.po [UTF-8] Tue Oct 20 08:43:19 2015
@@ -10640,19 +10640,17 @@ msgstr ""
 #: ../svn/tree-conflicts.c:107
 #, c-format
 msgid "local %s, incoming %s upon %s"
-msgstr ""
-
-#: ../svn/util.c:74
-#, fuzzy, c-format
-msgid ""
-"\n"
-"Committed revision %ld%s.\n"
-msgstr ""
-"\n"
-"リビジョン %ld をコミットしました。\n"
-
-#: ../svn/util.c:78
-msgid " (the answer to life, the universe, and everything)"
+msgstr ""
+
+#: ../svn/util.c:74
+#, c-format
+msgid ""
+"Committed revision %ld%s.\n"
+msgstr ""
+"リビジョン %ld%s をコミットしました。\n"
+
+#: ../svn/util.c:78
+msgid " (the answer to life, the universe, and everything)"
 msgstr ""
 
 #: ../svn/util.c:87

Modified: subversion/branches/move-tracking-2/subversion/po/ko.po
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/po/ko.po?rev=1709538&r1=1709537&r2=1709538&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/po/ko.po [UTF-8] (original)
+++ subversion/branches/move-tracking-2/subversion/po/ko.po [UTF-8] Tue Oct 20 08:43:19 2015
@@ -10527,16 +10527,14 @@ msgstr "업데이트 요약:\n"
 msgid "  Updated '%s' to r%ld.\n"
 msgstr "  '%s' 을(를) r%ld 로 업데이트함.\n"
 
-#: ../svn/util.c:75
-#, c-format
-msgid ""
-"\n"
-"Committed revision %ld%s.\n"
-msgstr ""
-"\n"
-"커밋된 리비전 %ld%s.\n"
-
-#: ../svn/util.c:79
+#: ../svn/util.c:75
+#, c-format
+msgid ""
+"Committed revision %ld%s.\n"
+msgstr ""
+"커밋된 리비전 %ld%s.\n"
+
+#: ../svn/util.c:79
 msgid " (the answer to life, the universe, and everything)"
 msgstr " (the answer to life, the universe, and everything)"
 

Modified: subversion/branches/move-tracking-2/subversion/po/nb.po
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/po/nb.po?rev=1709538&r1=1709537&r2=1709538&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/po/nb.po [UTF-8] (original)
+++ subversion/branches/move-tracking-2/subversion/po/nb.po [UTF-8] Tue Oct 20 08:43:19 2015
@@ -10226,13 +10226,11 @@ msgid "local %s, incoming %s upon %s"
 msgstr "lokal %s, innkommende %s på %s"
 
 #: ../svn/util.c:74
-#, fuzzy, c-format
+#, c-format
 msgid ""
-"\n"
 "Committed revision %ld%s.\n"
 msgstr ""
-"\n"
-"La inn revisjon %ld.\n"
+"La inn revisjon %ld%s.\n"
 
 #: ../svn/util.c:78
 msgid " (the answer to life, the universe, and everything)"

Modified: subversion/branches/move-tracking-2/subversion/po/pl.po
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/po/pl.po?rev=1709538&r1=1709537&r2=1709538&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/po/pl.po [UTF-8] (original)
+++ subversion/branches/move-tracking-2/subversion/po/pl.po [UTF-8] Tue Oct 20 08:43:19 2015
@@ -10285,13 +10285,11 @@ msgid "local %s, incoming %s upon %s"
 msgstr "lokalne: %s, przychodzące: %s, operacja: %s"
 
 #: ../svn/util.c:74
-#, fuzzy, c-format
+#, c-format
 msgid ""
-"\n"
 "Committed revision %ld%s.\n"
 msgstr ""
-"\n"
-"Zatwierdzona wersja %ld.\n"
+"Zatwierdzona wersja %ld%s.\n"
 
 #: ../svn/util.c:78
 msgid " (the answer to life, the universe, and everything)"

Modified: subversion/branches/move-tracking-2/subversion/po/pt_BR.po
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/po/pt_BR.po?rev=1709538&r1=1709537&r2=1709538&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/po/pt_BR.po [UTF-8] (original)
+++ subversion/branches/move-tracking-2/subversion/po/pt_BR.po [UTF-8] Tue Oct 20 08:43:19 2015
@@ -10087,13 +10087,11 @@ msgid "local %s, incoming %s upon %s"
 msgstr ""
 
 #: ../svn/util.c:74
-#, fuzzy, c-format
+#, c-format
 msgid ""
-"\n"
 "Committed revision %ld%s.\n"
 msgstr ""
-"\n"
-"Commit da revisão %ld.\n"
+"Commit da revisão %ld%s.\n"
 
 #: ../svn/util.c:78
 msgid " (the answer to life, the universe, and everything)"

Modified: subversion/branches/move-tracking-2/subversion/po/sv.po
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/po/sv.po?rev=1709538&r1=1709537&r2=1709538&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/po/sv.po [UTF-8] (original)
+++ subversion/branches/move-tracking-2/subversion/po/sv.po [UTF-8] Tue Oct 20 08:43:19 2015
@@ -13145,10 +13145,8 @@ msgstr "  Uppdaterade \"%s\" till r%ld.\
 #: ../svn/util.c:79
 #, c-format
 msgid ""
-"\n"
 "Committed revision %ld%s.\n"
 msgstr ""
-"\n"
 "Arkiverade revision %ld%s.\n"
 
 #: ../svn/util.c:83

Modified: subversion/branches/move-tracking-2/subversion/po/zh_CN.po
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/po/zh_CN.po?rev=1709538&r1=1709537&r2=1709538&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/po/zh_CN.po [UTF-8] (original)
+++ subversion/branches/move-tracking-2/subversion/po/zh_CN.po [UTF-8] Tue Oct 20 08:43:19 2015
@@ -11284,9 +11284,9 @@ msgid "done\n"
 msgstr "完成。\n"
 
 #: ../svn/notify.c:1066
-#, fuzzy, c-format
+#, c-format
 msgid "Committing transaction...\n"
-msgstr "正在读取事务"
+msgstr "正在读取事务\n"
 
 #: ../svn/propdel-cmd.c:88
 #, c-format
@@ -13710,10 +13710,9 @@ msgid "  Updated '%s' to r%ld.\n"
 msgstr "更新 '%s' 到版本 %ld。\n"
 
 #: ../svn/util.c:79
-#, fuzzy, c-format
+#, c-format
 msgid "Committed revision %ld%s.\n"
 msgstr ""
-"\n"
 "提交后的版本为 %ld%s。\n"
 
 #: ../svn/util.c:83

Modified: subversion/branches/move-tracking-2/subversion/po/zh_TW.po
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/po/zh_TW.po?rev=1709538&r1=1709537&r2=1709538&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/po/zh_TW.po [UTF-8] (original)
+++ subversion/branches/move-tracking-2/subversion/po/zh_TW.po [UTF-8] Tue Oct 20 08:43:19 2015
@@ -10120,19 +10120,17 @@ msgstr ""
 #: ../svn/tree-conflicts.c:107
 #, c-format
 msgid "local %s, incoming %s upon %s"
-msgstr ""
-
-#: ../svn/util.c:74
-#, fuzzy, c-format
-msgid ""
-"\n"
-"Committed revision %ld%s.\n"
-msgstr ""
-"\n"
-"送交修訂版 %ld.\n"
-
-#: ../svn/util.c:78
-msgid " (the answer to life, the universe, and everything)"
+msgstr ""
+
+#: ../svn/util.c:74
+#, c-format
+msgid ""
+"Committed revision %ld%s.\n"
+msgstr ""
+"送交修訂版 %ld%s.\n"
+
+#: ../svn/util.c:78
+msgid " (the answer to life, the universe, and everything)"
 msgstr ""
 
 #: ../svn/util.c:87

Modified: subversion/branches/move-tracking-2/subversion/svnlook/svnlook.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnlook/svnlook.c?rev=1709538&r1=1709537&r2=1709538&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnlook/svnlook.c (original)
+++ subversion/branches/move-tracking-2/subversion/svnlook/svnlook.c Tue Oct 20 08:43:19 2015
@@ -43,6 +43,7 @@
 #include "svn_dirent_uri.h"
 #include "svn_path.h"
 #include "svn_repos.h"
+#include "svn_cache_config.h"
 #include "svn_fs.h"
 #include "svn_time.h"
 #include "svn_utf.h"
@@ -144,6 +145,13 @@ static const apr_getopt_option_t options
   {"properties-only",   svnlook__properties_only, 0,
    N_("show only properties during the operation")},
 
+  {"memory-cache-size", 'M', 1,
+   N_("size of the extra in-memory cache in MB used to\n"
+      "                             "
+      "minimize redundant operations. Default: 16.\n"
+      "                             "
+      "[used for FSFS repositories only]")},
+
   {"no-newline",        svnlook__no_newline, 0,
    N_("do not output the trailing newline")},
 
@@ -296,7 +304,7 @@ static const svn_opt_subcommand_desc2_t
    N_("usage: svnlook tree REPOS_PATH [PATH_IN_REPOS]\n\n"
       "Print the tree, starting at PATH_IN_REPOS (if supplied, at the root\n"
       "of the tree otherwise), optionally showing node revision ids.\n"),
-   {'r', 't', 'N', svnlook__show_ids, svnlook__full_paths} },
+   {'r', 't', 'N', svnlook__show_ids, svnlook__full_paths, 'M'} },
 
   {"uuid", subcommand_uuid, {0},
    N_("usage: svnlook uuid REPOS_PATH\n\n"
@@ -340,6 +348,7 @@ struct svnlook_opt_state
   const char *diff_cmd;           /* --diff-cmd */
   svn_boolean_t show_inherited_props; /*  --show-inherited-props */
   svn_boolean_t no_newline;       /* --no-newline */
+  apr_uint64_t memory_cache_size; /* --memory-cache-size */
 };
 
 
@@ -2489,6 +2498,7 @@ sub_main(int *exit_code, int argc, const
   /* Initialize opt_state. */
   memset(&opt_state, 0, sizeof(opt_state));
   opt_state.rev = SVN_INVALID_REVNUM;
+  opt_state.memory_cache_size = svn_cache_config_get()->cache_size;
 
   /* Parse options. */
   SVN_ERR(svn_cmdline__getopt_init(&os, argc, argv, pool));
@@ -2530,6 +2540,11 @@ sub_main(int *exit_code, int argc, const
           opt_state.txn = opt_arg;
           break;
 
+        case 'M':
+          opt_state.memory_cache_size
+            = 0x100000 * apr_strtoi64(opt_arg, NULL, 0);
+          break;
+
         case 'N':
           opt_state.non_recursive = TRUE;
           break;
@@ -2825,6 +2840,17 @@ sub_main(int *exit_code, int argc, const
   apr_signal(SIGXFSZ, SIG_IGN);
 #endif
 
+  /* Configure FSFS caches for maximum efficiency with svnadmin.
+   * Also, apply the respective command line parameters, if given. */
+  {
+    svn_cache_config_t settings = *svn_cache_config_get();
+
+    settings.cache_size = opt_state.memory_cache_size;
+    settings.single_threaded = TRUE;
+
+    svn_cache_config_set(&settings);
+  }
+
   /* Run the subcommand. */
   err = (*subcommand->cmd_func)(os, &opt_state, pool);
   if (err)

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=1709538&r1=1709537&r2=1709538&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 Oct 20 08:43:19 2015
@@ -147,7 +147,7 @@ def check_hotcopy_fsfs_fsx(src, dst):
         # the hotcopy destination (i.e. a fresh cache generation)
         if src_file == 'revprop-generation':
           f2 = open(dst_path, 'r')
-          revprop_gen = int(f2.read().strip().split()[1])
+          revprop_gen = int(f2.read().strip())
           if revprop_gen != 0:
               raise svntest.Failure("Hotcopy destination has non-zero " +
                                     "revprop generation")
@@ -3202,7 +3202,7 @@ def dump_revprops(sbox):
   svntest.actions.run_and_verify_svnlook(log_msg, [], 'log', '-r1',
                                          sbox.repo_dir)
 
-@XFail()
+@XFail(svntest.main.is_fs_type_fsx)
 @Issue(4598)
 def dump_no_op_change(sbox):
   "svnadmin dump with no-op changes"