You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by cm...@apache.org on 2009/12/15 18:51:47 UTC

svn commit: r890917 - in /subversion/branches/issue-3550-dev: ./ build/generator/ build/generator/templates/ notes/obliterate/ subversion/include/ subversion/include/private/ subversion/libsvn_fs_base/ subversion/libsvn_fs_base/bdb/ subversion/libsvn_r...

Author: cmpilato
Date: Tue Dec 15 17:51:46 2009
New Revision: 890917

URL: http://svn.apache.org/viewvc?rev=890917&view=rev
Log:
Sync the 'issue-3550-dev' branch up with trunk changes.
(Merged /subversion/trunk:r889714-890873)

Modified:
    subversion/branches/issue-3550-dev/   (props changed)
    subversion/branches/issue-3550-dev/build/generator/neon.vcproj.ezt
    subversion/branches/issue-3550-dev/build/generator/serf.vcproj.ezt
    subversion/branches/issue-3550-dev/build/generator/svn_config.vcproj.ezt
    subversion/branches/issue-3550-dev/build/generator/svn_locale.vcproj.ezt
    subversion/branches/issue-3550-dev/build/generator/templates/vcnet_vcproj.ezt
    subversion/branches/issue-3550-dev/build/generator/zlib.vcproj.ezt
    subversion/branches/issue-3550-dev/notes/obliterate/design-authz.html
    subversion/branches/issue-3550-dev/notes/obliterate/req-spec.txt
    subversion/branches/issue-3550-dev/subversion/include/private/svn_mergeinfo_private.h
    subversion/branches/issue-3550-dev/subversion/include/private/svn_repos_private.h
    subversion/branches/issue-3550-dev/subversion/include/svn_mergeinfo.h
    subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/bdb/checksum-reps-table.c
    subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/fs.h
    subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/revs-txns.c
    subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/trail.h
    subversion/branches/issue-3550-dev/subversion/libsvn_ra_local/ra_plugin.c
    subversion/branches/issue-3550-dev/subversion/libsvn_repos/obliterate.c
    subversion/branches/issue-3550-dev/subversion/libsvn_subr/mergeinfo.c
    subversion/branches/issue-3550-dev/subversion/tests/cmdline/obliterate_tests.py
    subversion/branches/issue-3550-dev/subversion/tests/cmdline/svntest/objects.py
    subversion/branches/issue-3550-dev/subversion/tests/libsvn_subr/mergeinfo-test.c

Propchange: subversion/branches/issue-3550-dev/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Dec 15 17:51:46 2009
@@ -1,34 +1,35 @@
-subversion/branches/1.5.x-r30215:870312
-subversion/branches/bdb-reverse-deltas:872050-872529
-subversion/branches/diff-callbacks3:870059-870761
-subversion/branches/dont-save-plaintext-passwords-by-default:870728-871118
-subversion/branches/double-delete:870511-872970
-subversion/branches/explore-wc:875486,875493,875497,875507,875511,875514,875559,875580-875581,875584,875587,875611,875627,875647,875667-875668,875711-875712,875733-875734,875736,875744-875748,875751,875758,875782,875795-875796,875830,875836,875838,875842,875852,875855,875864,875870,875873,875880,875885-875888,875890,875897-875898,875905,875907-875909,875935,875943-875944,875946,875979,875982-875983,875985-875986,875990,875997
-subversion/branches/file-externals:871779-873302
-subversion/branches/fs-rep-sharing:869036-873803
-subversion/branches/fsfs-pack:873717-874575
-subversion/branches/gnome-keyring:870558-871410
-subversion/branches/http-protocol-v2:874395-876041
-subversion/branches/in-memory-cache:869829-871452
-subversion/branches/issue-2843-dev:871432-874179
-subversion/branches/issue-3000:871713,871716-871719,871721-871726,871728,871734
-subversion/branches/issue-3067-deleted-subtrees:873375-874084
-subversion/branches/issue-3148-dev:875193-875204
-subversion/branches/issue-3220-dev:872210-872226
-subversion/branches/issue-3334-dirs:875156-875867
-subversion/branches/kwallet:870785-871314
-subversion/branches/log-g-performance:870941-871032
-subversion/branches/merge-skips-obstructions:874525-874615
-subversion/branches/ra_serf-digest-authn:875693-876404
-subversion/branches/reintegrate-improvements:873853-874164
-subversion/branches/subtree-mergeinfo:876734-878766
-subversion/branches/svn-mergeinfo-enhancements:870119-870195,870197-870288
-subversion/branches/svnpatch-diff:865738-876477
-subversion/branches/svnraisetc:874709-875149
-subversion/branches/svnserve-logging:869828-870893
-subversion/branches/tc-issue-3334:874697-874773
-subversion/branches/tc-merge-notify:874017-874062
-subversion/branches/tc-resolve:874191-874239
-subversion/branches/tc_url_rev:874351-874483
-subversion/branches/tree-conflicts:868291-873154
-subversion/branches/tree-conflicts-notify:873926-874008
+/subversion/branches/1.5.x-r30215:870312
+/subversion/branches/bdb-reverse-deltas:872050-872529
+/subversion/branches/diff-callbacks3:870059-870761
+/subversion/branches/dont-save-plaintext-passwords-by-default:870728-871118
+/subversion/branches/double-delete:870511-872970
+/subversion/branches/explore-wc:875486,875493,875497,875507,875511,875514,875559,875580-875581,875584,875587,875611,875627,875647,875667-875668,875711-875712,875733-875734,875736,875744-875748,875751,875758,875782,875795-875796,875830,875836,875838,875842,875852,875855,875864,875870,875873,875880,875885-875888,875890,875897-875898,875905,875907-875909,875935,875943-875944,875946,875979,875982-875983,875985-875986,875990,875997
+/subversion/branches/file-externals:871779-873302
+/subversion/branches/fs-rep-sharing:869036-873803
+/subversion/branches/fsfs-pack:873717-874575
+/subversion/branches/gnome-keyring:870558-871410
+/subversion/branches/http-protocol-v2:874395-876041
+/subversion/branches/in-memory-cache:869829-871452
+/subversion/branches/issue-2843-dev:871432-874179
+/subversion/branches/issue-3000:871713,871716-871719,871721-871726,871728,871734
+/subversion/branches/issue-3067-deleted-subtrees:873375-874084
+/subversion/branches/issue-3148-dev:875193-875204
+/subversion/branches/issue-3220-dev:872210-872226
+/subversion/branches/issue-3334-dirs:875156-875867
+/subversion/branches/kwallet:870785-871314
+/subversion/branches/log-g-performance:870941-871032
+/subversion/branches/merge-skips-obstructions:874525-874615
+/subversion/branches/ra_serf-digest-authn:875693-876404
+/subversion/branches/reintegrate-improvements:873853-874164
+/subversion/branches/subtree-mergeinfo:876734-878766
+/subversion/branches/svn-mergeinfo-enhancements:870119-870195,870197-870288
+/subversion/branches/svnpatch-diff:865738-876477
+/subversion/branches/svnraisetc:874709-875149
+/subversion/branches/svnserve-logging:869828-870893
+/subversion/branches/tc-issue-3334:874697-874773
+/subversion/branches/tc-merge-notify:874017-874062
+/subversion/branches/tc-resolve:874191-874239
+/subversion/branches/tc_url_rev:874351-874483
+/subversion/branches/tree-conflicts:868291-873154
+/subversion/branches/tree-conflicts-notify:873926-874008
+/subversion/trunk:889714-890873

Modified: subversion/branches/issue-3550-dev/build/generator/neon.vcproj.ezt
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3550-dev/build/generator/neon.vcproj.ezt?rev=890917&r1=890916&r2=890917&view=diff
==============================================================================
--- subversion/branches/issue-3550-dev/build/generator/neon.vcproj.ezt (original)
+++ subversion/branches/issue-3550-dev/build/generator/neon.vcproj.ezt Tue Dec 15 17:51:46 2009
@@ -32,6 +32,7 @@
 [for platforms]		<Configuration
 			Name="Debug|[platforms]"
 			OutputDirectory="Debug"
+			BuildLogFile="$(IntDir)\BuildLog_$(ProjectName).htm"
 			IntermediateDirectory="Debug"
 			ConfigurationType="0"
 			ManagedExtensions="1"
@@ -47,6 +48,7 @@
 		<Configuration
 			Name="Release|[platforms]"
 			OutputDirectory="Release"
+			BuildLogFile="$(IntDir)\BuildLog_$(ProjectName).htm"
 			IntermediateDirectory="Release"
 			ConfigurationType="0"
 			ManagedExtensions="1"

Modified: subversion/branches/issue-3550-dev/build/generator/serf.vcproj.ezt
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3550-dev/build/generator/serf.vcproj.ezt?rev=890917&r1=890916&r2=890917&view=diff
==============================================================================
--- subversion/branches/issue-3550-dev/build/generator/serf.vcproj.ezt (original)
+++ subversion/branches/issue-3550-dev/build/generator/serf.vcproj.ezt Tue Dec 15 17:51:46 2009
@@ -32,6 +32,7 @@
 [for platforms]        <Configuration
             Name="Debug|[platforms]"
             OutputDirectory="Debug"
+            BuildLogFile="$(IntDir)\BuildLog_$(ProjectName).htm"
             IntermediateDirectory="Debug"
             ConfigurationType="0"
             ManagedExtensions="1"
@@ -47,6 +48,7 @@
         <Configuration
             Name="Release|[platforms]"
             OutputDirectory="Release"
+            BuildLogFile="$(IntDir)\BuildLog_$(ProjectName).htm"
             IntermediateDirectory="Release"
             ConfigurationType="0"
             ManagedExtensions="1"

Modified: subversion/branches/issue-3550-dev/build/generator/svn_config.vcproj.ezt
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3550-dev/build/generator/svn_config.vcproj.ezt?rev=890917&r1=890916&r2=890917&view=diff
==============================================================================
--- subversion/branches/issue-3550-dev/build/generator/svn_config.vcproj.ezt (original)
+++ subversion/branches/issue-3550-dev/build/generator/svn_config.vcproj.ezt Tue Dec 15 17:51:46 2009
@@ -32,6 +32,7 @@
 [for platforms][for configs]		<Configuration
 			Name="[configs]|[platforms]"
 			OutputDirectory="."
+			BuildLogFile="$(IntDir)\BuildLog_$(ProjectName).htm"
 			IntermediateDirectory="."
 			ConfigurationType="10"
 			UseOfMFC="0"

Modified: subversion/branches/issue-3550-dev/build/generator/svn_locale.vcproj.ezt
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3550-dev/build/generator/svn_locale.vcproj.ezt?rev=890917&r1=890916&r2=890917&view=diff
==============================================================================
--- subversion/branches/issue-3550-dev/build/generator/svn_locale.vcproj.ezt (original)
+++ subversion/branches/issue-3550-dev/build/generator/svn_locale.vcproj.ezt Tue Dec 15 17:51:46 2009
@@ -32,6 +32,7 @@
 [for platforms][for configs]		<Configuration
 			Name="[configs]|[platforms]"
 			OutputDirectory="..\..\[configs]\mo"
+			BuildLogFile="$(IntDir)\BuildLog_$(ProjectName).htm"
 			IntermediateDirectory="..\..\[configs]\mo"
 			ConfigurationType="0"
 			UseOfMFC="0"

Modified: subversion/branches/issue-3550-dev/build/generator/templates/vcnet_vcproj.ezt
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3550-dev/build/generator/templates/vcnet_vcproj.ezt?rev=890917&r1=890916&r2=890917&view=diff
==============================================================================
--- subversion/branches/issue-3550-dev/build/generator/templates/vcnet_vcproj.ezt (original)
+++ subversion/branches/issue-3550-dev/build/generator/templates/vcnet_vcproj.ezt Tue Dec 15 17:51:46 2009
@@ -31,6 +31,7 @@
 [for platforms][for configs]		<Configuration
 			Name="[configs.name]|[platforms]"
 			OutputDirectory="..\..\..\[configs.name]\[target.output_dir]"
+			BuildLogFile="$(IntDir)\BuildLog_$(ProjectName).htm"
 			IntermediateDirectory="..\..\..\[configs.name]\[target.intermediate_dir]"
 			ConfigurationType="[target_type]"[is configs.name "Release"]
 			WholeProgramOptimization="FALSE"[end]>

Modified: subversion/branches/issue-3550-dev/build/generator/zlib.vcproj.ezt
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3550-dev/build/generator/zlib.vcproj.ezt?rev=890917&r1=890916&r2=890917&view=diff
==============================================================================
--- subversion/branches/issue-3550-dev/build/generator/zlib.vcproj.ezt (original)
+++ subversion/branches/issue-3550-dev/build/generator/zlib.vcproj.ezt Tue Dec 15 17:51:46 2009
@@ -32,6 +32,7 @@
 [for platforms]		<Configuration
 			Name="Debug|[platforms]"
 			OutputDirectory="[zlib_path]\Debug"
+			BuildLogFile="$(IntDir)\BuildLog_$(ProjectName).htm"
 			IntermediateDirectory="[zlib_path]\Debug"
 			ConfigurationType="0"
 			ManagedExtensions="1"
@@ -47,6 +48,7 @@
 		<Configuration
 			Name="Release|[platforms]"
 			OutputDirectory="[zlib_path]\Release"
+			BuildLogFile="$(IntDir)\BuildLog_$(ProjectName).htm"
 			IntermediateDirectory="[zlib_path]\Release"
 			ConfigurationType="0"
 			ManagedExtensions="1"

Modified: subversion/branches/issue-3550-dev/notes/obliterate/design-authz.html
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3550-dev/notes/obliterate/design-authz.html?rev=890917&r1=890916&r2=890917&view=diff
==============================================================================
--- subversion/branches/issue-3550-dev/notes/obliterate/design-authz.html (original)
+++ subversion/branches/issue-3550-dev/notes/obliterate/design-authz.html Tue Dec 15 17:51:46 2009
@@ -46,6 +46,26 @@
 
 <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
 
+<div class="h2" id="introduction" title="#introduction">
+  <h2>Introduction</h2>
+
+  <p>Authorization is by a pre-obliterate hook which can base its decision on
+    the user name and the details of the attempted obliteration.</p>
+
+  <p>A post-obliterate hook will be available for reporting or other purposes,
+    analogous to the post-commit hook. This is not involved in authorization.
+    </p>
+
+  <p>Before a normal commit, two hooks are invoked: start-commit and
+    pre-commit, with only the list of files available to the first one and
+    the entire content of the change available to the second one. As
+    obliteration does not involve transmitting file contents, there is no
+    reason to have separate start-obliterate and pre-obliterate hooks.</p>
+
+</div>
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
 <div class="h2" id="pre-obliterate" title="#pre-obliterate">
   <h2>Pre-obliterate hook</h2>
 

Modified: subversion/branches/issue-3550-dev/notes/obliterate/req-spec.txt
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3550-dev/notes/obliterate/req-spec.txt?rev=890917&r1=890916&r2=890917&view=diff
==============================================================================
--- subversion/branches/issue-3550-dev/notes/obliterate/req-spec.txt (original)
+++ subversion/branches/issue-3550-dev/notes/obliterate/req-spec.txt Tue Dec 15 17:51:46 2009
@@ -117,6 +117,11 @@
     U1 wants to prune old versions of F1 regularly in order to limit server
     disk space usage.
 
+    This use case is not directly what most people consider to be
+    "obliterate". It is really a separate feature that could use the
+    functionality of "obliterate" in its implementation, but could also be
+    implemented in other ways.
+
 
 3. REQUIREMENTS
 

Modified: subversion/branches/issue-3550-dev/subversion/include/private/svn_mergeinfo_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3550-dev/subversion/include/private/svn_mergeinfo_private.h?rev=890917&r1=890916&r2=890917&view=diff
==============================================================================
--- subversion/branches/issue-3550-dev/subversion/include/private/svn_mergeinfo_private.h (original)
+++ subversion/branches/issue-3550-dev/subversion/include/private/svn_mergeinfo_private.h Tue Dec 15 17:51:46 2009
@@ -117,7 +117,10 @@
    appropriate newline terminated string.  If KEY_PREFIX is not NULL then
    prepend KEY_PREFIX to each key (path) in *OUTPUT.  if VAL_PREFIX is not
    NULL then prepend VAL_PREFIX to each merge source:rangelist line in
-   *OUTPUT. */
+   *OUTPUT.
+
+   Any relative merge source paths in the mergeinfo in CATALOG are converted
+   to absolute paths in *OUTPUT. */
 svn_error_t *
 svn_mergeinfo__catalog_to_formatted_string(svn_string_t **output,
                                            svn_mergeinfo_catalog_t catalog,
@@ -129,7 +132,10 @@
    Unlike svn_mergeinfo_to_string(), NULL MERGEINFO is tolerated and results
    in *OUTPUT set to "\n".  If SVN_DEBUG is true, then NULL or empty MERGEINFO
    causes *OUTPUT to be set to an appropriate newline terminated string.  If
-   PREFIX is not NULL then prepend PREFIX to each line in *OUTPUT. */
+   PREFIX is not NULL then prepend PREFIX to each line in *OUTPUT.
+
+   Any relative merge source paths in MERGEINFO are converted to absolute
+   paths in *OUTPUT.*/
 svn_error_t *
 svn_mergeinfo__to_formatted_string(svn_string_t **output,
                                    svn_mergeinfo_t mergeinfo,

Modified: subversion/branches/issue-3550-dev/subversion/include/private/svn_repos_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3550-dev/subversion/include/private/svn_repos_private.h?rev=890917&r1=890916&r2=890917&view=diff
==============================================================================
--- subversion/branches/issue-3550-dev/subversion/include/private/svn_repos_private.h (original)
+++ subversion/branches/issue-3550-dev/subversion/include/private/svn_repos_private.h Tue Dec 15 17:51:46 2009
@@ -40,14 +40,18 @@
 /**
  * Permanently delete @a path at revision @a revision in @a fs.
  *
- * Do not change the content of other node in the repository, even other nodes
- * that were copied from this one. The only other change in the repository is
- * to "copied from" pointers that were pointing to the now-deleted node. These
- * are removed or made to point to a previous version of the now-deleted node.
+ * Do not change the content of any other node in the repository, even other
+ * nodes that were copied from this one. The only other change in the
+ * repository is to "copied from" pointers that were pointing to the
+ * now-deleted node. These are removed or made to point to a previous
+ * version of the now-deleted node.
  * (### TODO: details.)
  *
+ * @a path is relative to the repository root and must start with "/".
+ *
  * If administratively forbidden, return @c SVN_ERR_RA_NOT_AUTHORIZED. If not
- * implemented by the server, return @c SVN_ERR_RA_NOT_IMPLEMENTED.
+ * implemented by the RA layer or by the server, return
+ * @c SVN_ERR_RA_NOT_IMPLEMENTED.
  *
  * @note This functionality is not implemented in pre-1.7 servers and may not
  * be implemented in all 1.7 and later servers.

Modified: subversion/branches/issue-3550-dev/subversion/include/svn_mergeinfo.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3550-dev/subversion/include/svn_mergeinfo.h?rev=890917&r1=890916&r2=890917&view=diff
==============================================================================
--- subversion/branches/issue-3550-dev/subversion/include/svn_mergeinfo.h (original)
+++ subversion/branches/issue-3550-dev/subversion/include/svn_mergeinfo.h Tue Dec 15 17:51:46 2009
@@ -157,6 +157,9 @@
  * inheritability are also allowed, but will be combined into a single
  * range when placed into @a *mergeinfo.
  *
+ * @a input may contain relative merge source paths, but these are
+ * converted to absolute paths in @a *mergeinfo.
+ *
  * @since New in 1.5.
  */
 svn_error_t *
@@ -438,6 +441,9 @@
  *  mergeinfo. Set @a *output to the result, allocated in @a pool.
  *  If @a input contains no elements, set @a *output to the empty string.
  *
+ * @a mergeinput may contain relative merge source paths, but these are
+ * converted to absolute paths in @a *output.
+ *
  * @since New in 1.5.
 */
 svn_error_t *

Modified: subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/bdb/checksum-reps-table.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/bdb/checksum-reps-table.c?rev=890917&r1=890916&r2=890917&view=diff
==============================================================================
--- subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/bdb/checksum-reps-table.c (original)
+++ subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/bdb/checksum-reps-table.c Tue Dec 15 17:51:46 2009
@@ -204,5 +204,5 @@
                                    svn_fs_base__str_to_dbt(&result, next_key),
                                    0);
 
-  return BDB_WRAP(fs, _("bumping next copy key"), db_err);
+  return BDB_WRAP(fs, _("bumping next representation reuse ID"), db_err);
 }

Modified: subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/fs.h?rev=890917&r1=890916&r2=890917&view=diff
==============================================================================
--- subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/fs.h (original)
+++ subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/fs.h Tue Dec 15 17:51:46 2009
@@ -83,9 +83,6 @@
 /* Revision at which the repo started using forward deltas. */
 #define SVN_FS_BASE__MISC_FORWARD_DELTA_UPGRADE  "forward-delta-rev"
 
-/* Next filesystem-global unique identifier value (base36). */
-#define SVN_FS_BASE__MISC_NEXT_FSGUID            "next-fsguid"
-
 
 
 /*** The filesystem structure.  ***/

Modified: subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/revs-txns.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/revs-txns.c?rev=890917&r1=890916&r2=890917&view=diff
==============================================================================
--- subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/revs-txns.c (original)
+++ subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/revs-txns.c Tue Dec 15 17:51:46 2009
@@ -434,6 +434,91 @@
 }
 
 
+/* Create a new row in the "copies" table that is a deep copy of the row
+ * keyed by OLD_COPY_ID. Assume that the txn-id component of its
+ * 'dst_noderev_id' field is OLD_TXN_ID, and change that to NEW_TXN_ID.
+ * Set *NEW_COPY_ID to the key of the new row.
+ * Work in TRAIL and allocate *NEW_COPY_ID in TRAIL->POOL. */
+static svn_error_t *
+copy_dup(const char **new_copy_id,
+         const char *old_copy_id,
+         const char *new_txn_id,
+         const char *old_txn_id,
+         trail_t *trail,
+         apr_pool_t *scratch_pool)
+{
+  copy_t *copy;
+  const char *node_id, *copy_id, *txn_id;
+
+  /* Get the old copy */
+  SVN_ERR(svn_fs_bdb__get_copy(&copy, trail->fs, old_copy_id, trail,
+                               scratch_pool));
+
+  /* Modify it: change dst_noderev_id's txn_id to NEW_TXN_ID */
+  node_id = svn_fs_base__id_node_id(copy->dst_noderev_id);
+  copy_id = svn_fs_base__id_copy_id(copy->dst_noderev_id);
+  txn_id = svn_fs_base__id_txn_id(copy->dst_noderev_id);
+  SVN_ERR_ASSERT(svn_fs_base__key_compare(copy_id, old_copy_id) == 0);
+  SVN_ERR_ASSERT(svn_fs_base__key_compare(txn_id, old_txn_id) == 0);
+  copy->dst_noderev_id = svn_fs_base__id_create(node_id, copy_id, new_txn_id,
+                                                scratch_pool);
+
+  /* Save the new copy */
+  SVN_ERR(svn_fs_bdb__reserve_copy_id(new_copy_id, trail->fs, trail,
+                                      trail->pool));
+  SVN_ERR(svn_fs_bdb__create_copy(trail->fs, *new_copy_id, copy->src_path,
+                                  copy->src_txn_id, copy->dst_noderev_id,
+                                  copy->kind, trail, scratch_pool));
+  return SVN_NO_ERROR;
+}
+
+
+/* Duplicate all entries in the "changes" table that are keyed by OLD_TXN_ID,
+ * creating new entries that are keyed by NEW_TXN_ID.
+ *
+ * Each new "change" has the same content as the old one, except with the
+ * txn-id component of its noderev-id (which is assumed to have been
+ * OLD_TXN_ID) changed to NEW_TXN_ID.
+ *
+ * Work within TRAIL. */
+static svn_error_t *
+changes_dup(const char *new_txn_id,
+            const char *old_txn_id,
+            trail_t *trail,
+            apr_pool_t *scratch_pool)
+{
+  apr_array_header_t *changes;
+  int i;
+
+  SVN_ERR(svn_fs_bdb__changes_fetch_raw(&changes, trail->fs, old_txn_id, trail,
+                                        scratch_pool));
+  for (i = 0; i < changes->nelts; i++)
+    {
+      change_t *change = APR_ARRAY_IDX(changes, i, change_t *);
+
+      if (change->kind != svn_fs_path_change_delete
+          && change->kind != svn_fs_path_change_reset)
+        {
+          const char *node_id, *copy_id;
+
+          /* Modify the "change": change noderev_id's txn_id to NEW_TXN_ID */
+          node_id = svn_fs_base__id_node_id(change->noderev_id);
+          copy_id = svn_fs_base__id_copy_id(change->noderev_id);
+          SVN_ERR_ASSERT(svn_fs_base__key_compare(
+            svn_fs_base__id_txn_id(change->noderev_id), old_txn_id) == 0);
+          change->noderev_id = svn_fs_base__id_create(node_id, copy_id,
+                                                      new_txn_id,
+                                                      scratch_pool);
+        }
+
+      /* Save the new "change" */
+      SVN_ERR(svn_fs_bdb__changes_add(trail->fs, new_txn_id, change, trail,
+                                      scratch_pool));
+    }
+  return SVN_NO_ERROR;
+}
+
+
 
 /* Generic transaction operations.  */
 
@@ -783,7 +868,40 @@
    * pervade node-ids throughout history. But what actually uses them, and
    * does anything use them during txn construction? */
 
-  /* ### TODO: Dup the "changes" that are keyed by the txn_id. */
+  /* Dup txn->copies
+   *
+   * ### PROBLEM:
+   * This code makes new rows in the 'copies' table, keyed by a NEW COPY-ID
+   * that is not the copy-id of the node-rev it refers to. WRONG!
+   *
+   * For the purpose of the txn keeping track of which "copies" table rows
+   * it allocated, this is fine. It is no good if something needs to look
+   * up copy info based on copy-id during txn construction.
+   *
+   * If no look-ups are required until after the txn is committed, maybe we
+   * could overwrite the old "copies" table entries with the new ones at
+   * commit time.
+   */
+  if (old_txn->copies)
+    {
+      int i;
+
+      new_txn->copies = apr_array_make(trail->pool, old_txn->copies->nelts,
+                                       sizeof(const char *));
+      for (i = 0; i < old_txn->copies->nelts; i++)
+        {
+          const char *old_copy_id = APR_ARRAY_IDX(old_txn->copies, i,
+                                                  const char *);
+          const char *new_copy_id;
+
+          SVN_ERR(copy_dup(&new_copy_id, old_copy_id, new_txn_id, old_txn_id,
+                           trail, trail->pool));
+          APR_ARRAY_PUSH(new_txn->copies, const char *) = new_copy_id;
+        }
+    }
+
+  /* Dup the "changes" that are keyed by the txn_id. */
+  SVN_ERR(changes_dup(new_txn_id, old_txn_id, trail, trail->pool));
 
   /* ### TODO: Update the "node-origins" table.
    * Or can this be deferred till commit time? Probably not. */

Modified: subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/trail.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/trail.h?rev=890917&r1=890916&r2=890917&view=diff
==============================================================================
--- subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/trail.h (original)
+++ subversion/branches/issue-3550-dev/subversion/libsvn_fs_base/trail.h Tue Dec 15 17:51:46 2009
@@ -119,7 +119,29 @@
    SVN_NO_ERROR, `svn_fs_base__retry_txn' commits the trail's Berkeley DB
    transaction, thus making your DB changes permanent, leaves the
    trail's pool alone so all the objects it contains are still
-   around (unless you request otherwise), and returns SVN_NO_ERROR.  */
+   around (unless you request otherwise), and returns SVN_NO_ERROR.
+
+
+   Keep the amount of work done in a trail small. C-Mike Pilato said to me:
+
+   I want to draw your attention to something that you may or may not realize
+   about designing for the BDB backend.  The 'trail' objects are (generally)
+   representative of Berkeley DB transactions -- that part I'm sure you know.
+   But you might not realize the value of keeping transactions as small as
+   possible.  Berkeley DB will accumulate locks (which I believe are
+   page-level, not as tight as row-level like you might hope) over the course
+   of a transaction, releasing those locks only at transaction commit/abort.
+   Berkeley DB backends are configured to have a maximum number of locks and
+   lockers allowed, and it's easier than you might think to hit the max-locks
+   thresholds (especially under high concurrency) and see an error (typically a
+   "Cannot allocate memory") result from that.
+
+   For example, in [a loop] you are writing a bunch of rows to the
+   `changes' table.  Could be 10.  Could be 100,000.  100,000 writes and
+   associated locks might be a problem or it might not.  But I use it as a way
+   to encourage you to think about reducing the amount of work you spend in any
+   one trail [...].
+*/
 
 struct trail_t
 {

Modified: subversion/branches/issue-3550-dev/subversion/libsvn_ra_local/ra_plugin.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3550-dev/subversion/libsvn_ra_local/ra_plugin.c?rev=890917&r1=890916&r2=890917&view=diff
==============================================================================
--- subversion/branches/issue-3550-dev/subversion/libsvn_ra_local/ra_plugin.c (original)
+++ subversion/branches/issue-3550-dev/subversion/libsvn_ra_local/ra_plugin.c Tue Dec 15 17:51:46 2009
@@ -1432,6 +1432,7 @@
 {
   svn_ra_local__session_baton_t *sess = session->priv;
 
+  path = svn_path_join(sess->fs_path->data, path, pool);
   SVN_ERR(svn_repos__obliterate_path_rev(sess->repos,
                                          revision,
                                          path,

Modified: subversion/branches/issue-3550-dev/subversion/libsvn_repos/obliterate.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3550-dev/subversion/libsvn_repos/obliterate.c?rev=890917&r1=890916&r2=890917&view=diff
==============================================================================
--- subversion/branches/issue-3550-dev/subversion/libsvn_repos/obliterate.c (original)
+++ subversion/branches/issue-3550-dev/subversion/libsvn_repos/obliterate.c Tue Dec 15 17:51:46 2009
@@ -26,6 +26,8 @@
 #include "svn_error_codes.h"
 #include "svn_fs.h"
 #include "svn_repos.h"
+#include "svn_dirent_uri.h"
+
 #include "repos.h"
 #include "private/svn_repos_private.h"
 #include "private/svn_fs_private.h"
@@ -40,10 +42,12 @@
                                apr_pool_t *pool)
 {
   svn_fs_t *fs = svn_repos_fs(repos);
-  svn_fs_root_t *rev_root;
+  svn_fs_root_t *rev_root, *txn_root;
   svn_fs_txn_t *txn;
   const svn_fs_id_t *node_id;
 
+  SVN_ERR_ASSERT(path[0] == '/' && svn_relpath_is_canonical(path + 1, pool));
+
   /* Sanity check: ensure the path exists in fs at the revision.
    * ### TODO: May want to allow non-existent node as a no-op.
    * ### This is an error for now to help catch wrong-node-reached bugs. */
@@ -58,9 +62,10 @@
 
   /* Begin a new transaction, based on the revision we want to modify. */
   SVN_ERR(svn_fs__begin_obliteration_txn(&txn, fs, revision, pool));
+  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
 
   /* Make the required changes in this txn */
-  /* ... */
+  SVN_ERR(svn_fs_delete(txn_root, path, pool));
 
   /* Commit the new transaction in place of the old revision */
   SVN_ERR(svn_fs__commit_obliteration_txn(revision, txn, pool));

Modified: subversion/branches/issue-3550-dev/subversion/libsvn_subr/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3550-dev/subversion/libsvn_subr/mergeinfo.c?rev=890917&r1=890916&r2=890917&view=diff
==============================================================================
--- subversion/branches/issue-3550-dev/subversion/libsvn_subr/mergeinfo.c (original)
+++ subversion/branches/issue-3550-dev/subversion/libsvn_subr/mergeinfo.c Tue Dec 15 17:51:46 2009
@@ -73,8 +73,10 @@
 
 /* pathname -> PATHNAME */
 static svn_error_t *
-parse_pathname(const char **input, const char *end,
-               svn_stringbuf_t **pathname, apr_pool_t *pool)
+parse_pathname(const char **input,
+               const char *end,
+               svn_stringbuf_t **pathname,
+               apr_pool_t *pool)
 {
   const char *curr = *input;
   const char *last_colon = NULL;
@@ -96,7 +98,18 @@
     return svn_error_create(SVN_ERR_MERGEINFO_PARSE_ERROR, NULL,
                             _("No pathname preceding ':'"));
 
-  *pathname = svn_stringbuf_ncreate(*input, last_colon - *input, pool);
+  /* Tolerate relative repository paths, but convert them to absolute. */
+  if (**input == '/')
+    {
+      *pathname = svn_stringbuf_ncreate(*input, last_colon - *input, pool);
+    }
+  else
+    {
+      const char *repos_rel_path = apr_pstrndup(pool, *input,
+                                                last_colon - *input);
+      *pathname = svn_stringbuf_createf(pool, "/%s",  repos_rel_path);
+    }
+
   *input = last_colon;
 
   return SVN_NO_ERROR;
@@ -564,6 +577,7 @@
                     apr_pool_t *pool)
 {
   svn_stringbuf_t *pathname;
+  apr_array_header_t *existing_rangelist;
   apr_array_header_t *rangelist = apr_array_make(pool, 1,
                                                  sizeof(svn_merge_range_t *));
 
@@ -634,6 +648,17 @@
           lastrange = APR_ARRAY_IDX(rangelist, i, svn_merge_range_t *);
         }
     }
+
+  /* Handle any funky mergeinfo with relative merge source paths that
+     might exist due to issue #3547.  It's possible that this issue allowed
+     the creation of mergeinfo with path keys that differ only by a
+     leading slash, e.g. "trunk:4033\n/trunk:4039-4995".  In the event
+     we encounter this we merge the rangelists together under a single
+     absolute path key. */
+  existing_rangelist = apr_hash_get(hash, pathname->data, APR_HASH_KEY_STRING);
+  if (existing_rangelist)
+    svn_rangelist_merge(&rangelist, existing_rangelist, pool);
+
   apr_hash_set(hash, pathname->data, APR_HASH_KEY_STRING, rangelist);
 
   return SVN_NO_ERROR;
@@ -1362,7 +1387,9 @@
 
 /* Converts a mergeinfo INPUT to an unparsed mergeinfo in OUTPUT.  If PREFIX
    is not NULL then prepend PREFIX to each line in OUTPUT.  If INPUT contains
-   no elements, return the empty string.
+   no elements, return the empty string.  If INPUT contains any merge source
+   path keys that are relative then convert these to absolute paths in
+   *OUTPUT.
  */
 static svn_error_t *
 mergeinfo_to_stringbuf(svn_stringbuf_t **output,
@@ -1384,11 +1411,13 @@
           svn_string_t *revlist;
 
           SVN_ERR(svn_rangelist_to_string(&revlist, elt.value, pool));
-          svn_stringbuf_appendcstr(*output,
-                                   apr_psprintf(pool, "%s%s:%s",
-                                                prefix ? prefix : "",
-                                                (const char *) elt.key,
-                                                revlist->data));
+          svn_stringbuf_appendcstr(
+            *output,
+            apr_psprintf(pool, "%s%s%s:%s",
+                         prefix ? prefix : "",
+                         *((const char *) elt.key) == '/' ? "" : "/",
+                         (const char *) elt.key,
+                         revlist->data));
           if (i < sorted->nelts - 1)
             svn_stringbuf_appendcstr(*output, "\n");
         }

Modified: subversion/branches/issue-3550-dev/subversion/tests/cmdline/obliterate_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3550-dev/subversion/tests/cmdline/obliterate_tests.py?rev=890917&r1=890916&r2=890917&view=diff
==============================================================================
--- subversion/branches/issue-3550-dev/subversion/tests/cmdline/obliterate_tests.py (original)
+++ subversion/branches/issue-3550-dev/subversion/tests/cmdline/obliterate_tests.py Tue Dec 15 17:51:46 2009
@@ -42,29 +42,32 @@
 # Test utilities
 #
 
+obliteration_dirs = ['f-mod', 'f-add', 'f-del', 'f-rpl', 'f-mov']
+
 def create_dd1_scenarios(wc):
   """Create, in the initially empty repository of the SvnWC WC, the
      obliteration test scenarios depicted in each "Example 1" in
      <notes/obliterate/fspec-dd1/dd1-file-ops.svg>."""
 
   # r1: base directories
-  for dir in ['f-mod', 'f-add', 'f-del', 'f-rpl', 'f-mov']:
+  for dir in obliteration_dirs:
     wc.svn_mkdir(dir)
-  wc.svn_commit()
+  rev = wc.svn_commit()
 
-  # r2 to r48 inclusive
-  for r in range(2, 9):
-    wc.svn_set_props('', { 'this-is-rev': str(r) })
-    wc.svn_commit()
+  # r2 to r8 inclusive, just so that the obliteration rev is a round and
+  # consistent number (10), no matter what complexity of history we have.
+  while rev < 8:
+    wc.svn_set_props('', { 'this-is-rev': str(rev + 1) })
+    rev = wc.svn_commit()
 
-  # r49: add the files used in the scenarios
+  # r9: add the files used in the scenarios
   wc.svn_file_create_add('f-mod/F', "Pear\n")
   wc.svn_file_create_add('f-del/F', "Pear\n")
   wc.svn_file_create_add('f-rpl/F', "Pear\n")
   wc.svn_file_create_add('f-mov/E', "Pear\n")  # 'E' will be moved to 'F'
   wc.svn_commit()
 
-  # r50: the rev to be obliterated
+  # r10: the rev in which files named 'F' are to be obliterated
   wc.file_modify('f-mod/F', 'Apple\n')
   wc.svn_file_create_add('f-add/F', 'Apple\n')
   wc.svn_delete('f-del/F')
@@ -74,10 +77,11 @@
   wc.file_modify('f-mov/F', 'Apple\n')
   rev = wc.svn_commit(log='Rev to be obliterated')
 
-  # r51
-  for dir in ['f-mod', 'f-add', 'f-rpl', 'f-mov']:
-    wc.file_modify(dir + '/F', 'Orange\n')
-  wc.svn_commit()
+  # r11: some more recent history that refers to the revision we changed
+  # (We are not ready to test this yet.)
+  #for dir in ['f-mod', 'f-add', 'f-rpl', 'f-mov']:
+  #  wc.file_modify(dir + '/F', 'Orange\n')
+  #wc.svn_commit()
 
   return rev
 
@@ -113,8 +117,9 @@
   except:
     pass
 
-  # Obliterate d/foo@{content=Apple}
-  repo.obliterate_node_rev('/d/foo', apple_rev)
+  # Obliterate a file in the revision where the file content was 'Apple'
+  for dir in obliteration_dirs:
+    repo.obliterate_node_rev(dir + '/F', apple_rev)
 
   # Dump the repository state, if possible, for debugging
   try:

Modified: subversion/branches/issue-3550-dev/subversion/tests/cmdline/svntest/objects.py
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3550-dev/subversion/tests/cmdline/svntest/objects.py?rev=890917&r1=890916&r2=890917&view=diff
==============================================================================
--- subversion/branches/issue-3550-dev/subversion/tests/cmdline/svntest/objects.py (original)
+++ subversion/branches/issue-3550-dev/subversion/tests/cmdline/svntest/objects.py Tue Dec 15 17:51:46 2009
@@ -42,12 +42,12 @@
   return os.sep.join(path.split('/'))
 
 
-def db_dump(repo_path, table):
+def db_dump(db_dump_name, repo_path, table):
   """Yield a human-readable representation of the rows of the BDB table
   TABLE in the repo at REPO_PATH.  Yield one line of text at a time.
   Calls the external program "db_dump" which is supplied with BDB."""
   table_path = repo_path + "/db/" + table
-  process = subprocess.Popen(["db_dump", "-p", table_path],
+  process = subprocess.Popen([db_dump_name, "-p", table_path],
                              stdout=subprocess.PIPE, universal_newlines=True)
   retcode = process.wait()
   assert retcode == 0
@@ -108,7 +108,7 @@
   new_line = '('.join(new_lparts)
   return new_line
 
-def dump_bdb(repo_path, dump_dir):
+def dump_bdb(db_dump_name, repo_path, dump_dir):
   """Dump all the known BDB tables in the repository at REPO_PATH into a
   single text file in DUMP_DIR.  Omit any "next-key" records."""
   dump_file = dump_dir + "/all.bdb"
@@ -117,9 +117,7 @@
                 'node-origins', 'representations', 'checksum-reps', 'strings',
                 'locks', 'lock-tokens', 'miscellaneous', 'uuids']:
     file.write(table + ":\n")
-    for line in db_dump(repo_path, table):
-      if line == " next-key\n":
-        break
+    for line in db_dump(db_dump_name, repo_path, table):
       file.write(crude_bdb_parse(line))
     file.write("\n")
   file.close()
@@ -129,6 +127,17 @@
   #svnadmin lslocks repo_path > dump_dir + "/locks.svn"
   #svnadmin lstxns  repo_path > dump_dir + "/txns.svn"
 
+def locate_db_dump():
+  """Locate a db_dump executable"""
+  # Assume that using the newest version is OK.
+  for db_dump_name in ['db4.8_dump', 'db4.7_dump', 'db4.6_dump',
+                       'db4.5_dump', 'db4.4_dump', 'db_dump']:
+    try:
+      if subprocess.Popen([db_dump_name, "-V"]).wait() == 0:
+        return db_dump_name
+    except OSError, e:
+      pass
+  return 'none'
 
 ######################################################################
 # Class SvnRepository
@@ -140,6 +149,7 @@
   def __init__(self, repo_url, repo_dir):
     self.repo_url = repo_url
     self.repo_absdir = os.path.abspath(repo_dir)
+    self.db_dump_name = locate_db_dump()
 
   def dump(self, output_dir):
     """Dump the repository into the directory OUTPUT_DIR"""
@@ -148,8 +158,8 @@
     print "## SvnRepository::dump(rep_dir=" + self.repo_absdir + ")"
 
     """Run a BDB dump on the repository"""
-    #subprocess.call(["/home/julianfoad/bin/svn-dump-bdb", self.repo_absdir, ldir])
-    dump_bdb(self.repo_absdir, ldir)
+    if self.db_dump_name != 'none':
+      dump_bdb(self.db_dump_name, self.repo_absdir, ldir)
 
     """Run 'svnadmin dump' on the repository."""
     exit_code, stdout, stderr = \

Modified: subversion/branches/issue-3550-dev/subversion/tests/libsvn_subr/mergeinfo-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3550-dev/subversion/tests/libsvn_subr/mergeinfo-test.c?rev=890917&r1=890916&r2=890917&view=diff
==============================================================================
--- subversion/branches/issue-3550-dev/subversion/tests/libsvn_subr/mergeinfo-test.c (original)
+++ subversion/branches/issue-3550-dev/subversion/tests/libsvn_subr/mergeinfo-test.c Tue Dec 15 17:51:46 2009
@@ -154,9 +154,12 @@
     "/trunk",
     "/trunk",
     "/branch",
-    "patch-common::netasq-bpf.c",
-    "patch-common_netasq-bpf.c:",
-    ":patch:common:netasq:bpf.c",
+
+    /* svn_mergeinfo_parse converts relative merge soure paths to absolute. */
+    "/patch-common::netasq-bpf.c",
+    "/patch-common_netasq-bpf.c:",
+    "/:patch:common:netasq:bpf.c",
+    
     "/trunk",
     "/trunk",
     "/trunk",
@@ -1083,6 +1086,22 @@
   if (svn_string_compare(expected, output) != TRUE)
     return fail(pool, "Mergeinfo string not what we expected");
 
+  /* Manually construct some mergeinfo with relative path
+     merge source keys.  These should be tolerated as input
+     to svn_mergeinfo_to_string(), but the resulting svn_string_t
+     should have absolute keys. */
+  info2 = apr_hash_make(pool);
+  apr_hash_set(info2, "fred",
+               APR_HASH_KEY_STRING,
+               apr_hash_get(info1, "/fred", APR_HASH_KEY_STRING));
+  apr_hash_set(info2, "trunk",
+               APR_HASH_KEY_STRING,
+               apr_hash_get(info1, "/trunk", APR_HASH_KEY_STRING));
+  SVN_ERR(svn_mergeinfo_to_string(&output, info2, pool));
+  
+  if (svn_string_compare(expected, output) != TRUE)
+    return fail(pool, "Mergeinfo string not what we expected");
+
   return SVN_NO_ERROR;
 }