You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2011/01/12 17:29:33 UTC

svn commit: r1058221 [1/3] - in /subversion/branches/ignore-mergeinfo-log: ./ build/ contrib/hook-scripts/ notes/api-errata/1.7/ notes/commit-access-templates/ subversion/include/ subversion/include/private/ subversion/libsvn_client/ subversion/libsvn_...

Author: hwright
Date: Wed Jan 12 16:29:32 2011
New Revision: 1058221

URL: http://svn.apache.org/viewvc?rev=1058221&view=rev
Log:
On the ignore-mergeinfo-log branch:
Bring up-to-date with trunk.

Added:
    subversion/branches/ignore-mergeinfo-log/notes/commit-access-templates/pmc-member.tmpl
      - copied unchanged from r1058220, subversion/trunk/notes/commit-access-templates/pmc-member.tmpl
Modified:
    subversion/branches/ignore-mergeinfo-log/   (props changed)
    subversion/branches/ignore-mergeinfo-log/CHANGES
    subversion/branches/ignore-mergeinfo-log/COMMITTERS
    subversion/branches/ignore-mergeinfo-log/build.conf
    subversion/branches/ignore-mergeinfo-log/build/run_tests.py
    subversion/branches/ignore-mergeinfo-log/contrib/hook-scripts/remove-zombie-locks.py
    subversion/branches/ignore-mergeinfo-log/notes/api-errata/1.7/wc007.txt   (contents, props changed)
    subversion/branches/ignore-mergeinfo-log/notes/commit-access-templates/full-committer.tmpl
    subversion/branches/ignore-mergeinfo-log/subversion/include/private/svn_adler32.h   (props changed)
    subversion/branches/ignore-mergeinfo-log/subversion/include/svn_client.h
    subversion/branches/ignore-mergeinfo-log/subversion/include/svn_diff.h
    subversion/branches/ignore-mergeinfo-log/subversion/include/svn_fs.h
    subversion/branches/ignore-mergeinfo-log/subversion/include/svn_io.h
    subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/add.c
    subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/commit.c
    subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/locking_commands.c
    subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/merge.c
    subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/mergeinfo.h
    subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/patch.c
    subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/repos_diff.c
    subversion/branches/ignore-mergeinfo-log/subversion/libsvn_delta/xdelta.c
    subversion/branches/ignore-mergeinfo-log/subversion/libsvn_diff/parse-diff.c
    subversion/branches/ignore-mergeinfo-log/subversion/libsvn_fs_base/bdb/env.c
    subversion/branches/ignore-mergeinfo-log/subversion/libsvn_fs_base/lock.c
    subversion/branches/ignore-mergeinfo-log/subversion/libsvn_ra_svn/cyrus_auth.c
    subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/adler32.c   (props changed)
    subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/dirent_uri.c
    subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/io.c
    subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/sqlite.c
    subversion/branches/ignore-mergeinfo-log/subversion/libsvn_subr/stream.c
    subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/update_editor.c
    subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/wc-metadata.sql
    subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/wc-queries.sql
    subversion/branches/ignore-mergeinfo-log/subversion/libsvn_wc/wc_db.c
    subversion/branches/ignore-mergeinfo-log/subversion/svn/info-cmd.c
    subversion/branches/ignore-mergeinfo-log/subversion/svn/main.c
    subversion/branches/ignore-mergeinfo-log/subversion/svn/propset-cmd.c
    subversion/branches/ignore-mergeinfo-log/subversion/svnadmin/main.c
    subversion/branches/ignore-mergeinfo-log/subversion/svndumpfilter/main.c
    subversion/branches/ignore-mergeinfo-log/subversion/svnlook/main.c
    subversion/branches/ignore-mergeinfo-log/subversion/svnrdump/svnrdump.c
    subversion/branches/ignore-mergeinfo-log/subversion/svnserve/main.c
    subversion/branches/ignore-mergeinfo-log/subversion/svnsync/main.c
    subversion/branches/ignore-mergeinfo-log/subversion/svnversion/main.c
    subversion/branches/ignore-mergeinfo-log/subversion/tests/cmdline/basic_tests.py
    subversion/branches/ignore-mergeinfo-log/subversion/tests/cmdline/dav-mirror-autocheck.sh
    subversion/branches/ignore-mergeinfo-log/subversion/tests/cmdline/davautocheck.sh
    subversion/branches/ignore-mergeinfo-log/subversion/tests/cmdline/merge_tests.py
    subversion/branches/ignore-mergeinfo-log/subversion/tests/cmdline/svnserveautocheck.sh
    subversion/branches/ignore-mergeinfo-log/subversion/tests/libsvn_diff/parse-diff-test.c
    subversion/branches/ignore-mergeinfo-log/subversion/tests/libsvn_subr/dirent_uri-test.c
    subversion/branches/ignore-mergeinfo-log/subversion/tests/libsvn_subr/stream-test.c
    subversion/branches/ignore-mergeinfo-log/tools/po/l10n-report.py   (contents, props changed)

Propchange: subversion/branches/ignore-mergeinfo-log/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Jan 12 16:29:32 2011
@@ -40,3 +40,4 @@
 /subversion/branches/tc_url_rev:874351-874483
 /subversion/branches/tree-conflicts:868291-873154
 /subversion/branches/tree-conflicts-notify:873926-874008
+/subversion/trunk:1054732-1058220

Modified: subversion/branches/ignore-mergeinfo-log/CHANGES
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/CHANGES?rev=1058221&r1=1058220&r2=1058221&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/CHANGES (original)
+++ subversion/branches/ignore-mergeinfo-log/CHANGES Wed Jan 12 16:29:32 2011
@@ -9,7 +9,9 @@ http://svn.apache.org/repos/asf/subversi
    * fix 'svn export' regression from 1.6.13 (r1032970)
    * fix 'svn export' mistakenly uri-encodes paths (issue #3745)
    * fix server-side memory leaks triggered by 'blame -g' (r1032808)
+            This has been tracked as CVE-2010-4644
    * prevent crash in mod_dav_svn when using SVNParentPath (r1033166)
+            This has been tracked as CVE-2010-4539
    * allow 'log -g' to continue in the face of invalid mergeinfo (r1028108)
    * filter unreadable paths for 'svn ls' and 'svn co' (r997026, -070, -474)
    * fix abort in 'svn blame -g' (issue #3666)

Modified: subversion/branches/ignore-mergeinfo-log/COMMITTERS
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/COMMITTERS?rev=1058221&r1=1058220&r2=1058221&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/COMMITTERS [UTF-8] (original)
+++ subversion/branches/ignore-mergeinfo-log/COMMITTERS [UTF-8] Wed Jan 12 16:29:32 2011
@@ -209,4 +209,4 @@ giorgio_valoti   Giorgio Valoti <giorgio
 ## Local Variables:
 ## coding:utf-8
 ## End:
-## vim:encoding=utf8
+## vim:fileencoding=utf8

Modified: subversion/branches/ignore-mergeinfo-log/build.conf
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/build.conf?rev=1058221&r1=1058220&r2=1058221&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/build.conf (original)
+++ subversion/branches/ignore-mergeinfo-log/build.conf Wed Jan 12 16:29:32 2011
@@ -53,10 +53,10 @@ private-built-includes =
         subversion/bindings/javahl/include/org_apache_subversion_javahl_CommitItemStateFlags.h
         subversion/bindings/javahl/include/org_apache_subversion_javahl_NativeResources.h
         subversion/bindings/javahl/include/org_apache_subversion_javahl_Path.h
-        subversion/bindings/javahl/include/org_apache_subversion_javahl_Revision.h
         subversion/bindings/javahl/include/org_apache_subversion_javahl_SVNRepos.h
         subversion/bindings/javahl/include/org_apache_subversion_javahl_SVNClient.h
         subversion/bindings/javahl/include/org_apache_subversion_javahl_types_Version.h
+        subversion/bindings/javahl/include/org_apache_subversion_javahl_types_Revision.h
         subversion/bindings/javahl/include/org_apache_subversion_javahl_callback_UserPasswordCallback.h
 
 

Modified: subversion/branches/ignore-mergeinfo-log/build/run_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/build/run_tests.py?rev=1058221&r1=1058220&r2=1058221&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/build/run_tests.py (original)
+++ subversion/branches/ignore-mergeinfo-log/build/run_tests.py Wed Jan 12 16:29:32 2011
@@ -53,6 +53,10 @@ try:
 except AttributeError:
   my_getopt = getopt.getopt
 
+# Ensure the compiled C tests use a known locale (Python tests set the locale
+# explicitly).
+os.environ['LC_ALL'] = 'C'
+
 class TextColors:
   '''Some ANSI terminal constants for output color'''
   ENDC = '\033[0;m'

Modified: subversion/branches/ignore-mergeinfo-log/contrib/hook-scripts/remove-zombie-locks.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/contrib/hook-scripts/remove-zombie-locks.py?rev=1058221&r1=1058220&r2=1058221&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/contrib/hook-scripts/remove-zombie-locks.py (original)
+++ subversion/branches/ignore-mergeinfo-log/contrib/hook-scripts/remove-zombie-locks.py Wed Jan 12 16:29:32 2011
@@ -20,7 +20,7 @@ remove-zombie-locks.py - remove zombie l
 
 Usage: remove-zombie-locks.py REPOS-PATH <REVISION|all>
 
-  When REVISION (an interger) is specified this script scans a commited
+  When REVISION (an interger) is specified this script scans a committed
   revision for deleted files and checks if a lock exists for any of these
   files. If any locks exist they are forcibly removed.
 
@@ -123,24 +123,34 @@ class RepositoryZombieLockRemover:
     print "Removing all zombie locks from repository at %s\n" \
           "This may take several minutes..." % self.repos_path
 
-    # Subversion's Berkeley DB implementation doesn't allow reentry of
-    # its BDB-transaction-using APIs from within BDB-transaction-using
-    # APIs (such as svn_fs_get_locks()).  So we have do this in two
-    # steps, first harvest the locks, then checking/removing them.
-    if self.fs_type == svn.fs.SVN_FS_TYPE_BDB:
-      self.locks = []
-      def bdb_lock_callback(lock, callback_pool):
-        self.locks.append(lock)
-      svn.fs.svn_fs_get_locks(self.fs_ptr, self.repos_subpath,
-                              bdb_lock_callback, self.pool)
-      subpool = svn.core.svn_pool_create(self.pool)
-      for lock in self.locks:
-        svn.core.svn_pool_clear(subpool)
-        self.unlock_nonexistant_files(lock, subpool)
-      svn.core.svn_pool_destroy(subpool)
+    # Try to use svn_fs_get_locks2() if it's present, as it's believed
+    # to be problem-free.
+    #
+    # If not, use svn_fs_get_locks().  But note that Subversion's
+    # Berkeley DB implementation of svn_fs_get_locks() in 1.6 and
+    # prior doesn't allow reentry of its BDB-transaction-using APIs
+    # from within BDB-transaction-using APIs (such as
+    # svn_fs_get_locks()).  So we have do this in two steps, first
+    # harvest the locks, then checking/removing them.
+    if hasattr(svn.fs, 'svn_fs_get_locks2'):
+      svn.fs.svn_fs_get_locks2(self.fs_ptr, self.repos_subpath,
+                               svn.core.svn_depth_infinity,
+                               self.unlock_nonexistant_files, self.pool)
     else:
-      svn.fs.svn_fs_get_locks(self.fs_ptr, self.repos_subpath,
-                              self.unlock_nonexistant_files, self.pool)
+      if self.fs_type == svn.fs.SVN_FS_TYPE_BDB:
+        self.locks = []
+        def bdb_lock_callback(lock, callback_pool):
+          self.locks.append(lock)
+        svn.fs.svn_fs_get_locks(self.fs_ptr, self.repos_subpath,
+                                bdb_lock_callback, self.pool)
+        subpool = svn.core.svn_pool_create(self.pool)
+        for lock in self.locks:
+          svn.core.svn_pool_clear(subpool)
+          self.unlock_nonexistant_files(lock, subpool)
+        svn.core.svn_pool_destroy(subpool)
+      else:
+        svn.fs.svn_fs_get_locks(self.fs_ptr, self.repos_subpath,
+                                self.unlock_nonexistant_files, self.pool)
     print "Done."
 
 

Modified: subversion/branches/ignore-mergeinfo-log/notes/api-errata/1.7/wc007.txt
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/notes/api-errata/1.7/wc007.txt?rev=1058221&r1=1058220&r2=1058221&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/notes/api-errata/1.7/wc007.txt (original)
+++ subversion/branches/ignore-mergeinfo-log/notes/api-errata/1.7/wc007.txt Wed Jan 12 16:29:32 2011
@@ -1,4 +1,4 @@
-API ERRATA -- $Id: wc006.txt 943050 2010-05-11 08:56:25Z julianfoad $
+API ERRATA -- $Id$
 
 Root Cause of Errata: 
  Library(s) Affected: libsvn_wc

Propchange: subversion/branches/ignore-mergeinfo-log/notes/api-errata/1.7/wc007.txt
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: subversion/branches/ignore-mergeinfo-log/notes/commit-access-templates/full-committer.tmpl
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/notes/commit-access-templates/full-committer.tmpl?rev=1058221&r1=1058220&r2=1058221&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/notes/commit-access-templates/full-committer.tmpl (original)
+++ subversion/branches/ignore-mergeinfo-log/notes/commit-access-templates/full-committer.tmpl Wed Jan 12 16:29:32 2011
@@ -30,7 +30,8 @@ modify the COMMITTERS file appropriately
 of your new username and password.
 
 Please remember to subscribe to the private (PMC) mailing list by
-emailing <private-subscribe{AT}subversion.apache.org>.
+emailing <private-subscribe{AT}subversion.apache.org>, and to checkout
+a working copy of https://svn.apache.org/repos/private/pmc/subversion/.
 
 Remember that you can still post patches for review before committing,
 when you want to.  Commit access just means that you can rely on your

Propchange: subversion/branches/ignore-mergeinfo-log/subversion/include/private/svn_adler32.h
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Jan 12 16:29:32 2011
@@ -40,3 +40,4 @@
 /subversion/branches/tc_url_rev/subversion/libsvn_diff/diff.h:874351-874483
 /subversion/branches/tree-conflicts/subversion/libsvn_diff/diff.h:868291-873154
 /subversion/branches/tree-conflicts-notify/subversion/libsvn_diff/diff.h:873926-874008
+/subversion/trunk/subversion/include/private/svn_adler32.h:1054732-1058220

Modified: subversion/branches/ignore-mergeinfo-log/subversion/include/svn_client.h
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/subversion/include/svn_client.h?rev=1058221&r1=1058220&r2=1058221&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/subversion/include/svn_client.h (original)
+++ subversion/branches/ignore-mergeinfo-log/subversion/include/svn_client.h Wed Jan 12 16:29:32 2011
@@ -1302,7 +1302,7 @@ svn_client_update(svn_revnum_t *result_r
  *                          the working copy was actually switched.
  * @param[in] path      The directory to be switched.  This need not be the
  *              root of a working copy.
- * @param[in] URL       The repository URL to switch to.
+ * @param[in] url       The repository URL to switch to.
  * @param[in] peg_revision  The peg revision.
  * @param[in] revision  The operative revision.
  * @param[in] depth     The depth of the operation.  If #svn_depth_infinity,

Modified: subversion/branches/ignore-mergeinfo-log/subversion/include/svn_diff.h
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/subversion/include/svn_diff.h?rev=1058221&r1=1058220&r2=1058221&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/subversion/include/svn_diff.h (original)
+++ subversion/branches/ignore-mergeinfo-log/subversion/include/svn_diff.h Wed Jan 12 16:29:32 2011
@@ -844,7 +844,7 @@ typedef struct svn_diff_hunk_t svn_diff_
  * @since New in 1.7.
  */
 svn_error_t *
-svn_diff_hunk_readline_diff_text(const svn_diff_hunk_t *hunk,
+svn_diff_hunk_readline_diff_text(svn_diff_hunk_t *hunk,
                                  svn_stringbuf_t **stringbuf,
                                  const char **eol,
                                  svn_boolean_t *eof,
@@ -864,7 +864,7 @@ svn_diff_hunk_readline_diff_text(const s
  * @since New in 1.7.
  */
 svn_error_t *
-svn_diff_hunk_readline_original_text(const svn_diff_hunk_t *hunk,
+svn_diff_hunk_readline_original_text(svn_diff_hunk_t *hunk,
                                      svn_stringbuf_t **stringbuf,
                                      const char **eol,
                                      svn_boolean_t *eof,
@@ -879,7 +879,7 @@ svn_diff_hunk_readline_original_text(con
  * @since New in 1.7.
  */
 svn_error_t *
-svn_diff_hunk_readline_modified_text(const svn_diff_hunk_t *hunk,
+svn_diff_hunk_readline_modified_text(svn_diff_hunk_t *hunk,
                                      svn_stringbuf_t **stringbuf,
                                      const char **eol,
                                      svn_boolean_t *eof,
@@ -888,18 +888,18 @@ svn_diff_hunk_readline_modified_text(con
 
 /** Reset the diff text of @a hunk so it can be read again from the start.
  * @since New in 1.7. */
-svn_error_t *
-svn_diff_hunk_reset_diff_text(const svn_diff_hunk_t *hunk);
+void
+svn_diff_hunk_reset_diff_text(svn_diff_hunk_t *hunk);
 
 /** Reset the original text of @a hunk so it can be read again from the start.
  * @since New in 1.7. */
-svn_error_t *
-svn_diff_hunk_reset_original_text(const svn_diff_hunk_t *hunk);
+void
+svn_diff_hunk_reset_original_text(svn_diff_hunk_t *hunk);
 
 /** Reset the modified text of @a hunk so it can be read again from the start.
  * @since New in 1.7. */
-svn_error_t *
-svn_diff_hunk_reset_modified_text(const svn_diff_hunk_t *hunk);
+void
+svn_diff_hunk_reset_modified_text(svn_diff_hunk_t *hunk);
 
 /** Return the line offset of the original hunk text,
  * as parsed from the hunk header.
@@ -941,6 +941,7 @@ svn_diff_hunk_get_trailing_context(const
 
 /**
  * Data type to manage parsing of properties in patches.
+ * API users should not allocate structures of this type directly.
  *
  * @since New in 1.7. */
 typedef struct svn_prop_patch_t {
@@ -957,15 +958,10 @@ typedef struct svn_prop_patch_t {
 
 /**
  * Data type to manage parsing of patches.
+ * API users should not allocate structures of this type directly.
  *
  * @since New in 1.7. */
 typedef struct svn_patch_t {
-  /** Path to the patch file. */
-  const char *path;
-
-  /** The patch file itself. */
-  apr_file_t *patch_file;
-
   /**
    * The old and new file names as retrieved from the patch file.
    * These paths are UTF-8 encoded and canonicalized, but otherwise
@@ -992,6 +988,20 @@ typedef struct svn_patch_t {
   svn_boolean_t reverse;
 } svn_patch_t;
 
+/* An opaque type representing an open patch file.
+ *
+ * @since New in 1.7. */
+typedef struct svn_patch_file_t svn_patch_file_t;
+
+/* Open @a patch_file at @a local_abspath.
+ * Allocate @a patch_file in @a result_pool.
+ *
+ * @since New in 1.7. */
+svn_error_t *
+svn_diff_open_patch_file(svn_patch_file_t **patch_file,
+                         const char *local_abspath,
+                         apr_pool_t *result_pool);
+
 /**
  * Return the next @a *patch in @a patch_file.
  * If no patch can be found, set @a *patch to NULL.
@@ -1004,20 +1014,21 @@ typedef struct svn_patch_t {
  * @since New in 1.7. */
 svn_error_t *
 svn_diff_parse_next_patch(svn_patch_t **patch,
-                          apr_file_t *patch_file,
+                          svn_patch_file_t *patch_file,
                           svn_boolean_t reverse,
                           svn_boolean_t ignore_whitespace,
                           apr_pool_t *result_pool,
                           apr_pool_t *scratch_pool);
 
 /**
- * Dispose of @a patch, closing any streams used by it.
+ * Dispose of @a patch_file.
  * Use @a scratch_pool for all temporary allocations.
  *
  * @since New in 1.7.
  */
 svn_error_t *
-svn_diff_close_patch(const svn_patch_t *patch, apr_pool_t *scratch_pool);
+svn_diff_close_patch_file(svn_patch_file_t *patch_file,
+                          apr_pool_t *scratch_pool);
 
 #ifdef __cplusplus
 }

Modified: subversion/branches/ignore-mergeinfo-log/subversion/include/svn_fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/subversion/include/svn_fs.h?rev=1058221&r1=1058220&r2=1058221&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/subversion/include/svn_fs.h (original)
+++ subversion/branches/ignore-mergeinfo-log/subversion/include/svn_fs.h Wed Jan 12 16:29:32 2011
@@ -2176,13 +2176,10 @@ typedef svn_error_t *(*svn_fs_get_locks_
  * lock iteration will terminate and that error will be returned by
  * this function.
  *
- * @note On Berkeley-DB-backed filesystems, the @a get_locks_func
- * callback will be invoked from within a Berkeley-DB transaction trail.
- * Implementors of the callback are, as a result, forbidden from
- * calling any svn_fs API functions which might themselves attempt to
- * start a new Berkeley DB transaction (which is most of this svn_fs
- * API).  Yes, this is a nasty implementation detail to have to be
- * aware of.  We hope to fix this problem in the future.
+ * @note Over the course of this function's invocation, locks might be
+ * added, removed, or modified by concurrent processes.  Callers need
+ * to anticipate and gracefully handle the transience of this
+ * information.
  *
  * @since New in 1.7.
  */
@@ -2194,9 +2191,17 @@ svn_fs_get_locks2(svn_fs_t *fs,
                   void *get_locks_baton,
                   apr_pool_t *pool);
 
-/**
- * Similar to svn_fs_get_locks2(), but with @a depth always passed as
- * svn_depth_infinity.
+/** Similar to svn_fs_get_locks2(), but with @a depth always passed as
+ * svn_depth_infinity, and with the following known problem (which is
+ * not present in svn_fs_get_locks2()):
+ *
+ * @note On Berkeley-DB-backed filesystems in Subversion 1.6 and
+ * prior, the @a get_locks_func callback will be invoked from within a
+ * Berkeley-DB transaction trail.  Implementors of the callback are,
+ * as a result, forbidden from calling any svn_fs API functions which
+ * might themselves attempt to start a new Berkeley DB transaction
+ * (which is most of this svn_fs API).  Yes, this is a nasty
+ * implementation detail to have to be aware of.
  *
  * @deprecated Provided for backward compatibility with the 1.6 API.
  */

Modified: subversion/branches/ignore-mergeinfo-log/subversion/include/svn_io.h
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/subversion/include/svn_io.h?rev=1058221&r1=1058220&r2=1058221&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/subversion/include/svn_io.h (original)
+++ subversion/branches/ignore-mergeinfo-log/subversion/include/svn_io.h Wed Jan 12 16:29:32 2011
@@ -930,40 +930,6 @@ svn_stream_t *
 svn_stream_from_aprfile(apr_file_t *file,
                         apr_pool_t *pool);
 
-/** Create a stream for reading from a range of an APR file.
- * The stream cannot be written to.
- *
- * @a start and @a end specify the start and end offsets for read
- * operations from @a file, in bytes. @a start marks the first byte
- * to be read from the file. When the stream is first created, the
- * cursor of the underlying file is set to the @a start offset.
- * The byte at @a end, and any bytes past @a end, will never be read.
- *
- * The stream returns 0 bytes if a read operation occurs past of
- * the specified range. If the requested number of bytes in a read
- * operation is larger than the remaining bytes in the range, only
- * the remaining amount of bytes is returned.
- *
- * If @a file is @c NULL, or if @a start is not smaller than @a end,
- * or if @a start is negative, or if @a end is zero or negative,
- * or if the file cursor cannot be set to the @a start offset,
- * an empty stream created by svn_stream_empty() is returned.
- *
- * This function should normally be called with @a disown set to FALSE,
- * in which case closing the stream will also close the underlying file.
- *
- * If @a disown is TRUE, the stream will disown the underlying file,
- * meaning that svn_stream_close() will not close the file.
- *
- * @since New in 1.7.
- */
-svn_stream_t*
-svn_stream_from_aprfile_range_readonly(apr_file_t *file,
-                                       svn_boolean_t disown,
-                                       apr_off_t start,
-                                       apr_off_t end,
-                                       apr_pool_t *pool);
-
 /** Set @a *out to a generic stream connected to stdout, allocated in
  * @a pool.  The stream and its underlying APR handle will be closed
  * when @a pool is cleared or destroyed.

Modified: subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/add.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/add.c?rev=1058221&r1=1058220&r2=1058221&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/add.c (original)
+++ subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/add.c Wed Jan 12 16:29:32 2011
@@ -462,6 +462,11 @@ struct add_with_write_lock_baton {
   svn_boolean_t force;
   svn_boolean_t no_ignore;
   svn_client_ctx_t *ctx;
+
+  /* Absolute path to the first existing parent directory of local_abspath.
+   * If not NULL, all missing parents of local_abspath must be created
+   * before local_abspath can be added. */
+  const char *existing_parent_abspath;
 };
 
 /* The main logic of the public svn_client_add4. */
@@ -472,6 +477,47 @@ add(void *baton, apr_pool_t *result_pool
   svn_error_t *err;
   struct add_with_write_lock_baton *b = baton;
 
+  if (b->existing_parent_abspath)
+    {
+      const char *parent_abspath;
+      const char *child_relpath;
+      apr_array_header_t *components;
+      int i;
+      apr_pool_t *iterpool;
+
+      parent_abspath = b->existing_parent_abspath;
+      child_relpath = svn_dirent_is_child(b->existing_parent_abspath,
+                                          b->local_abspath, NULL);
+      components = svn_path_decompose(child_relpath, scratch_pool);
+      iterpool = svn_pool_create(scratch_pool);
+      for (i = 0; i < components->nelts - 1; i++)
+        {
+          const char *component;
+          svn_node_kind_t disk_kind;
+
+          svn_pool_clear(iterpool);
+
+          if (b->ctx->cancel_func)
+            SVN_ERR(b->ctx->cancel_func(b->ctx->cancel_baton));
+
+          component = APR_ARRAY_IDX(components, i, const char *);
+          parent_abspath = svn_dirent_join(parent_abspath, component,
+                                           scratch_pool);
+          SVN_ERR(svn_io_check_path(parent_abspath, &disk_kind, iterpool));
+          if (disk_kind != svn_node_none && disk_kind != svn_node_dir)
+            return svn_error_createf(SVN_ERR_CLIENT_NO_VERSIONED_PARENT, NULL,
+                                     _("'%s' prevents creating parent of '%s'"),
+                                     parent_abspath, b->local_abspath);
+
+          SVN_ERR(svn_io_make_dir_recursively(parent_abspath, scratch_pool));
+          SVN_ERR(svn_wc_add_from_disk(b->ctx->wc_ctx, parent_abspath,
+                                       b->ctx->notify_func2,
+                                       b->ctx->notify_baton2,
+                                       scratch_pool));
+        }
+      svn_pool_destroy(iterpool);
+    }
+
   SVN_ERR(svn_io_check_path(b->local_abspath, &kind, scratch_pool));
   if (kind == svn_node_dir)
     {
@@ -505,26 +551,27 @@ add(void *baton, apr_pool_t *result_pool
 }
 
 
-/* Go up the directory tree, looking for a versioned directory.  If found,
-   add all the intermediate directories.  Otherwise, return
-   SVN_ERR_CLIENT_NO_VERSIONED_PARENT. */
-/* ### This function needs rewriting into its callers in a style that finds the
-       parent and then acquires an infinite depth lock there for the entire
-       operation */
+/* Go up the directory tree from LOCAL_ABSPATH, looking for a versioned
+ * directory.  If found, return its path in *EXISTING_PARENT_ABSPATH.
+ * Otherwise, return SVN_ERR_CLIENT_NO_VERSIONED_PARENT. */
 static svn_error_t *
-add_parent_dirs(svn_client_ctx_t *ctx,
-                const char *local_abspath,
-                apr_pool_t *scratch_pool)
+find_existing_parent(const char **existing_parent_abspath,
+                     svn_client_ctx_t *ctx,
+                     const char *local_abspath,
+                     apr_pool_t *result_pool,
+                     apr_pool_t *scratch_pool)
 {
   int format;
   const char *parent_abspath;
-  svn_boolean_t own_lock;
   svn_wc_context_t *wc_ctx = ctx->wc_ctx;
 
   SVN_ERR(svn_wc_check_wc2(&format, wc_ctx, local_abspath, scratch_pool));
 
   if (format > 0)
-    return SVN_NO_ERROR;
+    {
+      *existing_parent_abspath = apr_pstrdup(result_pool, local_abspath);
+      return SVN_NO_ERROR;
+    }
 
   if (svn_dirent_is_root(local_abspath, strlen(local_abspath)))
     return svn_error_create(SVN_ERR_CLIENT_NO_VERSIONED_PARENT, NULL, NULL);
@@ -538,25 +585,11 @@ add_parent_dirs(svn_client_ctx_t *ctx,
 
   parent_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
 
-  SVN_ERR(add_parent_dirs(ctx, parent_abspath, scratch_pool));
-
-  SVN_ERR(svn_wc_locked2(&own_lock, NULL, wc_ctx, parent_abspath,
-                         scratch_pool));
-
-  if (!own_lock)
-    SVN_ERR(svn_wc__acquire_write_lock(NULL, wc_ctx, parent_abspath, FALSE,
-                                       scratch_pool, scratch_pool));
-
   if (ctx->cancel_func)
     SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
 
-  SVN_ERR(svn_wc_add_from_disk(wc_ctx, local_abspath,
-                               ctx->notify_func2, ctx->notify_baton2,
-                               scratch_pool));
-  /* ### New dir gets added with its own per-directory lock which we
-     must release.  This code should be redundant when we move to a
-     single db. */
-  SVN_ERR(svn_wc__release_write_lock(wc_ctx, parent_abspath, scratch_pool));
+  SVN_ERR(find_existing_parent(existing_parent_abspath, ctx, parent_abspath,
+                               result_pool, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -594,12 +627,17 @@ svn_client_add4(const char *path,
   else
     parent_abspath = svn_dirent_dirname(local_abspath, pool);
 
+  baton.existing_parent_abspath = NULL;
   if (add_parents)
     {
       apr_pool_t *subpool;
+      const char *existing_parent_abspath;
 
       subpool = svn_pool_create(pool);
-      SVN_ERR(add_parent_dirs(ctx, parent_abspath, subpool));
+      SVN_ERR(find_existing_parent(&existing_parent_abspath, ctx,
+                                   parent_abspath, pool, subpool));
+      if (strcmp(existing_parent_abspath, parent_abspath) != 0)
+        baton.existing_parent_abspath = existing_parent_abspath;
       svn_pool_destroy(subpool);
     }
 
@@ -609,8 +647,10 @@ svn_client_add4(const char *path,
   baton.no_ignore = no_ignore;
   baton.ctx = ctx;
   SVN_ERR(svn_wc__call_with_write_lock(add, &baton, ctx->wc_ctx,
-                                       parent_abspath, FALSE,
-                                       pool, pool));
+                                       baton.existing_parent_abspath
+                                         ? baton.existing_parent_abspath
+                                         : parent_abspath,
+                                       FALSE, pool, pool));
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/commit.c?rev=1058221&r1=1058220&r2=1058221&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/commit.c (original)
+++ subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/commit.c Wed Jan 12 16:29:32 2011
@@ -1091,6 +1091,13 @@ svn_client_commit5(const apr_array_heade
   SVN_ERR(svn_wc__acquire_write_lock(NULL, ctx->wc_ctx, base_abspath,
                                      FALSE, pool, pool));
 
+  /*
+   * At this point, the working copy must be unlocked (if possible)
+   * before returning from this function. So we must now handle every
+   * error explicitly, rather than using SVN_ERR().
+   *
+   */
+
   /* One day we might support committing from multiple working copies, but
      we don't yet.  This check ensures that we don't silently commit a
      subset of the targets.
@@ -1105,8 +1112,13 @@ svn_client_commit5(const apr_array_heade
         const char *target_path = APR_ARRAY_IDX(targets, i, const char *);
 
         svn_pool_clear(iterpool);
-        SVN_ERR(check_nonrecursive_dir_delete(target_path, ctx->wc_ctx, depth,
-                                              iterpool));
+        cmt_err = check_nonrecursive_dir_delete(target_path, ctx->wc_ctx,
+                                                depth, iterpool);
+        if (cmt_err)
+          {
+            svn_pool_destroy(iterpool);
+            goto cleanup;
+          }
       }
     svn_pool_destroy(iterpool);
   }

Modified: subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/locking_commands.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/locking_commands.c?rev=1058221&r1=1058220&r2=1058221&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/locking_commands.c (original)
+++ subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/locking_commands.c Wed Jan 12 16:29:32 2011
@@ -191,18 +191,15 @@ organize_lock_targets(const char **commo
 
   /* Get the common parent and all paths */
   if (url_mode)
-    {
-      SVN_ERR(svn_uri_condense_targets(common_parent_url, &rel_targets,
-                                       targets, TRUE, pool, pool));
-    }
+    SVN_ERR(svn_uri_condense_targets(common_parent_url, &rel_targets,
+                                     targets, TRUE, pool, pool));
   else
-    {
-      SVN_ERR(svn_dirent_condense_targets(common_parent_url, &rel_targets,
-                                          targets, TRUE, pool, pool));
-    }
+    SVN_ERR(svn_dirent_condense_targets(common_parent_url, &rel_targets,
+                                        targets, TRUE, pool, pool));
 
-  /* svn_path_condense_targets leaves paths empty if TARGETS only had
-     1 member, so we special case that. */
+  /* svn_uri_condense_targets and svn_dirent_condense_targets leaves
+     URLs/paths empty if TARGETS only had 1 member, so we special case
+     that. */
   if (apr_is_empty_array(rel_targets))
     {
       const char *parent, *base;
@@ -273,8 +270,8 @@ organize_lock_targets(const char **commo
       SVN_ERR(svn_uri_condense_targets(&common_url, &rel_urls, urls,
                                        FALSE, pool, pool));
 
-      /* svn_path_condense_targets leaves paths empty if TARGETS only had
-         1 member, so we special case that (again). */
+      /* svn_uri_condense_targets leaves URLs empty if TARGETS only
+         had 1 member, so we special case that (again). */
       if (apr_is_empty_array(rel_urls))
         {
           const char *base_name = svn_uri_basename(common_url, pool);

Modified: subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/merge.c?rev=1058221&r1=1058220&r2=1058221&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/merge.c (original)
+++ subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/merge.c Wed Jan 12 16:29:32 2011
@@ -3444,12 +3444,9 @@ get_full_mergeinfo(svn_mergeinfo_t *reco
      removing any self-referential mergeinfo. */
   if (recorded_mergeinfo)
     {
-      /* ### FIXME: There's probably an RA session we could/should be
-         ### using here instead of having this function possibly spawn
-         ### yet another one.  */
       SVN_ERR(svn_client__get_wc_or_repos_mergeinfo(recorded_mergeinfo,
                                                     &inherited, FALSE,
-                                                    inherit, NULL,
+                                                    inherit, ra_session,
                                                     target_abspath,
                                                     ctx, scratch_pool));
       if (indirect)

Modified: subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/mergeinfo.h
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/mergeinfo.h?rev=1058221&r1=1058220&r2=1058221&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/mergeinfo.h (original)
+++ subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/mergeinfo.h Wed Jan 12 16:29:32 2011
@@ -207,9 +207,10 @@ svn_client__get_repos_mergeinfo_catalog(
    target has no info of its own.
 
    If no mergeinfo can be obtained from the WC or REPOS_ONLY is TRUE,
-   get it from the repository.  RA_SESSION should be an open RA
-   session pointing at TARGET_WCPATH's URL, or NULL, in which case this
-   function will open its own temporary session.
+   get it from the repository.  If the repository is contacted for mergeinfo
+   and RA_SESSION does not point to TARGET_WCPATH's URL, then it is
+   temporarily reparented.  If RA_SESSION is NULL, then a temporary session
+   is opened as needed.
 
    Store any mergeinfo obtained for TARGET_WCPATH in
    *TARGET_MERGEINFO, if no mergeinfo is found *TARGET_MERGEINFO is

Modified: subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/patch.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/patch.c?rev=1058221&r1=1058220&r2=1058221&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/patch.c (original)
+++ subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/patch.c Wed Jan 12 16:29:32 2011
@@ -32,6 +32,7 @@
 #include "svn_client.h"
 #include "svn_dirent_uri.h"
 #include "svn_diff.h"
+#include "svn_hash.h"
 #include "svn_io.h"
 #include "svn_path.h"
 #include "svn_pools.h"
@@ -48,7 +49,7 @@
 
 typedef struct hunk_info_t {
   /* The hunk. */
-  const svn_diff_hunk_t *hunk;
+  svn_diff_hunk_t *hunk;
 
   /* The line where the hunk matched in the target file. */
   svn_linenum_t matched_line;
@@ -483,7 +484,7 @@ init_prop_target(prop_patch_target_t **p
 
   content_info = apr_pcalloc(result_pool, sizeof(*content_info));
 
-  /* All other fields in are FALSE or NULL due to apr_pcalloc().*/
+  /* All other fields are FALSE or NULL due to apr_pcalloc(). */
   content_info->current_line = 1;
   content_info->eol_style = svn_subst_eol_style_none;
   content_info->lines = apr_array_make(result_pool, 0,
@@ -834,7 +835,7 @@ seek_to_line(target_content_info_t *cont
  * Do temporary allocations in POOL. */
 static svn_error_t *
 match_hunk(svn_boolean_t *matched, target_content_info_t *content_info,
-           const svn_diff_hunk_t *hunk, int fuzz,
+           svn_diff_hunk_t *hunk, int fuzz,
            svn_boolean_t ignore_whitespace,
            svn_boolean_t match_modified, apr_pool_t *pool)
 {
@@ -861,12 +862,12 @@ match_hunk(svn_boolean_t *matched, targe
   trailing_context = svn_diff_hunk_get_trailing_context(hunk);
   if (match_modified)
     {
-      SVN_ERR(svn_diff_hunk_reset_modified_text(hunk));
+      svn_diff_hunk_reset_modified_text(hunk);
       hunk_length = svn_diff_hunk_get_modified_length(hunk);
     }
   else
     {
-      SVN_ERR(svn_diff_hunk_reset_original_text(hunk));
+      svn_diff_hunk_reset_original_text(hunk);
       hunk_length = svn_diff_hunk_get_original_length(hunk);
     }
   iterpool = svn_pool_create(pool);
@@ -950,7 +951,7 @@ match_hunk(svn_boolean_t *matched, targe
 static svn_error_t *
 scan_for_match(svn_linenum_t *matched_line,
                target_content_info_t *content_info,
-               const svn_diff_hunk_t *hunk, svn_boolean_t match_first,
+               svn_diff_hunk_t *hunk, svn_boolean_t match_first,
                svn_linenum_t upper_line, int fuzz,
                svn_boolean_t ignore_whitespace,
                svn_boolean_t match_modified,
@@ -1022,7 +1023,7 @@ scan_for_match(svn_linenum_t *matched_li
 static svn_error_t *
 match_existing_target(svn_boolean_t *match,
                       target_content_info_t *content_info,
-                      const svn_diff_hunk_t *hunk,
+                      svn_diff_hunk_t *hunk,
                       svn_stream_t *stream,
                       apr_pool_t *scratch_pool)
 {
@@ -1031,7 +1032,7 @@ match_existing_target(svn_boolean_t *mat
   svn_boolean_t eof;
   svn_boolean_t hunk_eof;
 
-  SVN_ERR(svn_diff_hunk_reset_modified_text(hunk));
+  svn_diff_hunk_reset_modified_text(hunk);
 
   iterpool = svn_pool_create(scratch_pool);
   do
@@ -1087,7 +1088,7 @@ match_existing_target(svn_boolean_t *mat
 static svn_error_t *
 get_hunk_info(hunk_info_t **hi, patch_target_t *target,
               target_content_info_t *content_info,
-              const svn_diff_hunk_t *hunk, int fuzz,
+              svn_diff_hunk_t *hunk, int fuzz,
               svn_boolean_t ignore_whitespace,
               svn_boolean_t is_prop_hunk,
               svn_cancel_func_t cancel_func, void *cancel_baton,
@@ -1301,7 +1302,7 @@ copy_lines_to_target(target_content_info
  * Do temporary allocations in POOL. */
 static svn_error_t *
 reject_hunk(patch_target_t *target, target_content_info_t *content_info,
-            const svn_diff_hunk_t *hunk, const char *prop_name,
+            svn_diff_hunk_t *hunk, const char *prop_name,
             apr_pool_t *pool)
 {
   const char *hunk_header;
@@ -1419,7 +1420,7 @@ apply_hunk(patch_target_t *target, targe
   /* Write the hunk's version to the patched result.
    * Don't write the lines which matched with fuzz. */
   lines_read = 0;
-  SVN_ERR(svn_diff_hunk_reset_modified_text(hi->hunk));
+  svn_diff_hunk_reset_modified_text(hi->hunk);
   iterpool = svn_pool_create(pool);
   do
     {
@@ -1701,6 +1702,9 @@ apply_one_patch(patch_target_t **patch_t
 
       svn_pool_clear(iterpool);
 
+      if (cancel_func)
+        SVN_ERR((cancel_func)(cancel_baton));
+
       hi = APR_ARRAY_IDX(target->content_info->hunks, i, hunk_info_t *);
       if (hi->already_applied)
         continue;
@@ -1935,8 +1939,7 @@ create_missing_parents(patch_target_t *t
 
       svn_pool_clear(iterpool);
 
-      component = APR_ARRAY_IDX(components, i,
-                                const char *);
+      component = APR_ARRAY_IDX(components, i, const char *);
       local_abspath = svn_dirent_join(local_abspath, component, scratch_pool);
 
       SVN_ERR(svn_wc_read_kind(&wc_kind, ctx->wc_ctx, local_abspath, TRUE,
@@ -1990,8 +1993,7 @@ create_missing_parents(patch_target_t *t
       for (i = 0; i < present_components; i++)
         {
           const char *component;
-          component = APR_ARRAY_IDX(components, i,
-                                    const char *);
+          component = APR_ARRAY_IDX(components, i, const char *);
           local_abspath = svn_dirent_join(local_abspath,
                                           component, scratch_pool);
         }
@@ -2011,10 +2013,9 @@ create_missing_parents(patch_target_t *t
 
           svn_pool_clear(iterpool);
 
-          component = APR_ARRAY_IDX(components, i,
-                                    const char *);
+          component = APR_ARRAY_IDX(components, i, const char *);
           local_abspath = svn_dirent_join(local_abspath, component,
-                                     scratch_pool);
+                                          scratch_pool);
           if (dry_run)
             {
               if (ctx->notify_func2)
@@ -2211,6 +2212,9 @@ install_patched_prop_targets(patch_targe
 
       svn_pool_clear(iterpool);
 
+      if (ctx->cancel_func)
+        SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
+
       /* For a deleted prop we only set the value to NULL. */
       if (prop_target->operation == svn_diff_op_deleted)
         {
@@ -2267,8 +2271,6 @@ install_patched_prop_targets(patch_targe
             {
               SVN_ERR(svn_io_file_create(target->local_abspath, "",
                                          scratch_pool));
-              if (ctx->cancel_func)
-                SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
               SVN_ERR(svn_wc_add_from_disk(ctx->wc_ctx, target->local_abspath,
                                            /* suppress notification */
                                            NULL, NULL,
@@ -2368,14 +2370,14 @@ find_existing_children(void *baton,
 
 /* Indicate in *EMPTY whether the directory at LOCAL_ABSPATH has any
  * versioned or unversioned children. Consider any DELETED_TARGETS,
- * as well as paths listed in DELETED_ABSPATHS_LIST (which may be NULL)
- * as already deleted. Use WC_CTX as the working copy context.
+ * as well as paths occuring as keys of DELETED_ABSPATHS_HASH (which may
+ * be NULL) as already deleted. Use WC_CTX as the working copy context.
  * Do temporary allocations in SCRATCH_POOL. */
 static svn_error_t *
 check_dir_empty(svn_boolean_t *empty, const char *local_abspath,
                 svn_wc_context_t *wc_ctx,
                 apr_array_header_t *deleted_targets,
-                apr_array_header_t *deleted_abspath_list,
+                apr_hash_t *deleted_abspath_hash,
                 apr_pool_t *scratch_pool)
 {
   struct status_baton btn;
@@ -2423,13 +2425,17 @@ check_dir_empty(svn_boolean_t *empty, co
               break;
            }
         }
-      if (! deleted && deleted_abspath_list)
+      if (! deleted && deleted_abspath_hash)
         {
-          for (j = 0; j < deleted_abspath_list->nelts; j++)
+          apr_hash_index_t *hi;
+
+          for (hi = apr_hash_first(scratch_pool, deleted_abspath_hash);
+               hi;
+               hi = apr_hash_next(hi))
             {
               const char *abspath;
 
-              abspath = APR_ARRAY_IDX(deleted_abspath_list, j, const char *);
+              abspath = svn__apr_hash_index_key(hi);
               if (! svn_path_compare_paths(found, abspath))
                {
                   deleted = TRUE;
@@ -2447,33 +2453,6 @@ check_dir_empty(svn_boolean_t *empty, co
   return SVN_NO_ERROR;
 }
 
-/* Push a copy of EMPTY_DIR, allocated in RESULT_POOL, onto the EMPTY_DIRS
- * array if no directory matching EMPTY_DIR is already in the array. */
-static void
-push_if_unique(apr_array_header_t *empty_dirs, const char *empty_dir,
-               apr_pool_t *result_pool)
-{
-  svn_boolean_t is_unique;
-  int i;
-
-  is_unique = TRUE;
-  for (i = 0; i < empty_dirs->nelts; i++)
-    {
-      const char *empty_dir2;
-
-      empty_dir2 = APR_ARRAY_IDX(empty_dirs, i, const char *);
-      if (strcmp(empty_dir, empty_dir2) == 0)
-        {
-          is_unique = FALSE;
-          break;
-        }
-    }
-
-  if (is_unique)
-    APR_ARRAY_PUSH(empty_dirs, const char *) = apr_pstrdup(result_pool,
-                                                           empty_dir);
-}
-
 /* Delete all directories from the working copy which are left empty
  * by deleted TARGETS. Use client context CTX.
  * If DRY_RUN is TRUE, do not modify the working copy.
@@ -2482,11 +2461,13 @@ static svn_error_t *
 delete_empty_dirs(apr_array_header_t *targets_info, svn_client_ctx_t *ctx,
                   svn_boolean_t dry_run, apr_pool_t *scratch_pool)
 {
-  apr_array_header_t *empty_dirs;
+  apr_hash_t *empty_dirs;
+  apr_hash_t *non_empty_dirs;
   apr_array_header_t *deleted_targets;
   apr_pool_t *iterpool;
   svn_boolean_t again;
   int i;
+  apr_hash_index_t *hi;
 
   /* Get a list of all deleted targets. */
   deleted_targets = apr_array_make(scratch_pool, 0, sizeof(patch_target_t *));
@@ -2504,7 +2485,8 @@ delete_empty_dirs(apr_array_header_t *ta
     return SVN_NO_ERROR;
 
   /* Look for empty parent directories of deleted targets. */
-  empty_dirs = apr_array_make(scratch_pool, 0, sizeof(const char *));
+  empty_dirs = apr_hash_make(scratch_pool);
+  non_empty_dirs = apr_hash_make(scratch_pool);
   iterpool = svn_pool_create(scratch_pool);
   for (i = 0; i < targets_info->nelts; i++)
     {
@@ -2519,17 +2501,24 @@ delete_empty_dirs(apr_array_header_t *ta
 
       target_info = APR_ARRAY_IDX(targets_info, i, patch_target_info_t *);
       parent = svn_dirent_dirname(target_info->local_abspath, iterpool);
+
+      if (apr_hash_get(non_empty_dirs, parent, APR_HASH_KEY_STRING))
+        continue;
+      else if (apr_hash_get(empty_dirs, parent, APR_HASH_KEY_STRING))
+        continue;
+
       SVN_ERR(check_dir_empty(&parent_empty, parent, ctx->wc_ctx,
                               deleted_targets, NULL, iterpool));
       if (parent_empty)
-        {
-          APR_ARRAY_PUSH(empty_dirs, const char *) =
-            apr_pstrdup(scratch_pool, parent);
-        }
+        apr_hash_set(empty_dirs, apr_pstrdup(scratch_pool, parent),
+                     APR_HASH_KEY_STRING, "");
+      else
+        apr_hash_set(non_empty_dirs, apr_pstrdup(scratch_pool, parent),
+                     APR_HASH_KEY_STRING, "");
     }
 
   /* We have nothing to do if there aren't any empty directories. */
-  if (empty_dirs->nelts == 0)
+  if (apr_hash_count(empty_dirs) == 0)
     {
       svn_pool_destroy(iterpool);
       return SVN_NO_ERROR;
@@ -2538,7 +2527,7 @@ delete_empty_dirs(apr_array_header_t *ta
   /* Determine the minimal set of empty directories we need to delete. */
   do
     {
-      apr_array_header_t *empty_dirs_copy;
+      apr_hash_t *empty_dirs_copy;
 
       svn_pool_clear(iterpool);
 
@@ -2548,32 +2537,43 @@ delete_empty_dirs(apr_array_header_t *ta
       /* Rebuild the empty dirs list, replacing empty dirs which have
        * an empty parent with their parent. */
       again = FALSE;
-      empty_dirs_copy = apr_array_copy(iterpool, empty_dirs);
-      apr_array_clear(empty_dirs);
-      for (i = 0; i < empty_dirs_copy->nelts; i++)
+      empty_dirs_copy = apr_hash_copy(iterpool, empty_dirs);
+      SVN_ERR(svn_hash__clear(empty_dirs, iterpool));
+
+      for (hi = apr_hash_first(iterpool, empty_dirs_copy);
+           hi;
+           hi = apr_hash_next(hi))
         {
           svn_boolean_t parent_empty;
           const char *empty_dir;
           const char *parent;
 
-          empty_dir = APR_ARRAY_IDX(empty_dirs_copy, i, const char *);
+          empty_dir = svn__apr_hash_index_key(hi);
           parent = svn_dirent_dirname(empty_dir, iterpool);
+
+          if (apr_hash_get(empty_dirs, parent, APR_HASH_KEY_STRING))
+            continue;
+
           SVN_ERR(check_dir_empty(&parent_empty, parent, ctx->wc_ctx,
                                   deleted_targets, empty_dirs_copy,
                                   iterpool));
           if (parent_empty)
             {
               again = TRUE;
-              push_if_unique(empty_dirs, parent, scratch_pool);
+              apr_hash_set(empty_dirs, apr_pstrdup(scratch_pool, parent),
+                           APR_HASH_KEY_STRING, "");
             }
           else
-            push_if_unique(empty_dirs, empty_dir, scratch_pool);
+            apr_hash_set(empty_dirs, apr_pstrdup(scratch_pool, empty_dir),
+                         APR_HASH_KEY_STRING, "");
         }
     }
   while (again);
 
   /* Finally, delete empty directories. */
-  for (i = 0; i < empty_dirs->nelts; i++)
+  for (hi = apr_hash_first(scratch_pool, empty_dirs);
+       hi;
+       hi = apr_hash_next(hi))
     {
       const char *empty_dir;
 
@@ -2582,7 +2582,12 @@ delete_empty_dirs(apr_array_header_t *ta
       if (ctx->cancel_func)
         SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
 
-      empty_dir = APR_ARRAY_IDX(empty_dirs, i, const char *);
+      empty_dir = svn__apr_hash_index_key(hi);
+      if (! dry_run)
+        SVN_ERR(svn_wc_delete4(ctx->wc_ctx, empty_dir, FALSE, FALSE,
+                               ctx->cancel_func, ctx->cancel_baton,
+                               NULL, NULL, /* no duplicate notification */
+                               iterpool));
       if (ctx->notify_func2)
         {
           svn_wc_notify_t *notify;
@@ -2591,11 +2596,6 @@ delete_empty_dirs(apr_array_header_t *ta
                                         iterpool);
           (*ctx->notify_func2)(ctx->notify_baton2, notify, iterpool);
         }
-      if (! dry_run)
-        SVN_ERR(svn_wc_delete4(ctx->wc_ctx, empty_dir, FALSE, FALSE,
-                               ctx->cancel_func, ctx->cancel_baton,
-                               NULL, NULL, /* no duplicate notification */
-                               iterpool));
     }
   svn_pool_destroy(iterpool);
 
@@ -2643,13 +2643,13 @@ apply_patches(void *baton,
 {
   svn_patch_t *patch;
   apr_pool_t *iterpool;
-  apr_file_t *patch_file;
+  svn_patch_file_t *patch_file;
   apr_array_header_t *targets_info;
   apply_patches_baton_t *btn = baton;
 
   /* Try to open the patch file. */
-  SVN_ERR(svn_io_file_open(&patch_file, btn->patch_abspath,
-                           APR_READ | APR_BINARY, 0, scratch_pool));
+  SVN_ERR(svn_diff_open_patch_file(&patch_file, btn->patch_abspath,
+                                   scratch_pool));
 
   /* Apply patches. */
   targets_info = apr_array_make(scratch_pool, 0,
@@ -2707,8 +2707,6 @@ apply_patches(void *baton,
                 }
               SVN_ERR(send_patch_notification(target, btn->ctx, iterpool));
             }
-
-          SVN_ERR(svn_diff_close_patch(patch, iterpool));
         }
     }
   while (patch);
@@ -2717,7 +2715,7 @@ apply_patches(void *baton,
   SVN_ERR(delete_empty_dirs(targets_info, btn->ctx, btn->dry_run,
                             scratch_pool));
 
-  SVN_ERR(svn_io_file_close(patch_file, iterpool));
+  SVN_ERR(svn_diff_close_patch_file(patch_file, iterpool));
   svn_pool_destroy(iterpool);
 
   return SVN_NO_ERROR;

Modified: subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/repos_diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/repos_diff.c?rev=1058221&r1=1058220&r2=1058221&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/repos_diff.c (original)
+++ subversion/branches/ignore-mergeinfo-log/subversion/libsvn_client/repos_diff.c Wed Jan 12 16:29:32 2011
@@ -32,6 +32,8 @@
  * each file have been created the diff callback is invoked to display
  * the difference between the two files.  */
 
+#include <apr_uri.h>
+
 #include "svn_hash.h"
 #include "svn_wc.h"
 #include "svn_pools.h"
@@ -66,6 +68,10 @@ struct edit_baton {
   /* RA_SESSION is the open session for making requests to the RA layer */
   svn_ra_session_t *ra_session;
 
+  /* TRUE if RA_SESSION is open to a repository URL using the http or https
+     scheme. */
+  svn_boolean_t is_dav_session;
+
   /* The rev1 from the '-r Rev1:Rev2' command line option */
   svn_revnum_t revision;
 
@@ -1168,9 +1174,9 @@ change_file_prop(void *file_baton,
   if (b->skip)
     return SVN_NO_ERROR;
 
-  /* Issue #3657 'phantom svn:eol-style changes cause spurious merge text
-     conflicts'.  When communicating with the repository via ra_serf and
-     ra_neon, the change_dir_prop and change_file_prop svn_delta_editor_t
+  /* Issue #3657 'dav update report handler in skelta mode can cause
+     spurious conflicts'.  When communicating with the repository via ra_serf
+     and ra_neon, the change_dir_prop and change_file_prop svn_delta_editor_t
      callbacks are called (obviously) when a directory or file property has
      changed between the start and end of the edit.  Less obvious however,
      is that these callbacks may be made describing *all* of the properties
@@ -1178,11 +1184,24 @@ change_file_prop(void *file_baton,
      (Specifically ra_neon does this for diff/merge and ra_serf does it
      for diff/merge/update/switch).
 
-     Normally this is fairly harmless, but if it appears that the
-     svn:eol-style property has changed on a file, then we can get spurious
-     text conflicts (i.e. Issue #3657).  To prevent this, we populate
-     FILE_BATON->PRISTINE_PROPS only with actual property changes. */
-  if (value)
+     This means that the change_[file|dir]_prop svn_delta_editor_t callbacks
+     may be made where there are no property changes (i.e. a noop change of
+     NAME from VALUE to VALUE).  Normally this is harmless, but during a
+     merge it can result in spurious conflicts if the WC's pristine property
+     NAME has a value other than VALUE.  In an ideal world the mod_dav_svn
+     update report handler, when in 'skelta' mode and describing changes to
+     a path on which a property has changed, wouldn't ask the client to later
+     fetch all properties and figure out what has changed itself.  The server
+     already knows which properties have changed!
+
+     Regardless, such a change is not yet implemented, and even when it is,
+     the client should DTRT with regard to older servers which behave this
+     way.  Hence this little hack:  We populate FILE_BATON->PROPCHANGES only
+     with *actual* property changes.
+
+     See http://subversion.tigris.org/issues/show_bug.cgi?id=3657#desc9 and
+     http://svn.haxx.se/dev/archive-2010-08/0351.shtml for more details. */
+  if (value && b->edit_baton->is_dav_session)
     {
       const char *current_prop = svn_prop_get_value(b->pristine_props, name);
       if (current_prop && strcmp(current_prop, value->data) == 0)
@@ -1210,6 +1229,15 @@ change_dir_prop(void *dir_baton,
   if (db->skip)
     return SVN_NO_ERROR;
 
+  /* See the comment re issue #3657 in the change_file_prop() callback. */
+  if (value && db->edit_baton->is_dav_session)
+    {
+      const char *current_prop = svn_prop_get_value(db->pristine_props,
+                                                    name);
+      if (current_prop && strcmp(current_prop, value->data) == 0)
+        return SVN_NO_ERROR;
+    }
+
   propchange = apr_array_push(db->propchanges);
   propchange->name = apr_pstrdup(db->pool, name);
   propchange->value = value ? svn_string_dup(value, db->pool) : NULL;
@@ -1309,6 +1337,10 @@ svn_client__get_diff_editor(const char *
   svn_delta_editor_t *tree_editor = svn_delta_default_editor(subpool);
   struct edit_baton *eb = apr_palloc(subpool, sizeof(*eb));
   const char *target_abspath;
+  const char *session_url;
+  apr_status_t status;
+  apr_uri_t apr_uri;
+
   SVN_ERR(svn_dirent_get_absolute(&target_abspath, target, pool));
 
   eb->target = target;
@@ -1317,6 +1349,23 @@ svn_client__get_diff_editor(const char *
   eb->diff_cmd_baton = diff_cmd_baton;
   eb->dry_run = dry_run;
   eb->ra_session = ra_session;
+
+  SVN_ERR(svn_ra_get_session_url(ra_session, &session_url, subpool));
+  status = apr_uri_parse(subpool, session_url, &apr_uri);
+  if (status)
+    {
+      return svn_error_createf(SVN_ERR_BAD_URL, NULL,
+                               _("Unable to parse URL '%s'"), session_url);
+    }
+  else
+    {
+      if (svn_cstring_casecmp(apr_uri.scheme, "https") == 0
+          || svn_cstring_casecmp(apr_uri.scheme, "http") == 0)
+        eb->is_dav_session = TRUE;
+      else
+        eb->is_dav_session = FALSE;
+    }
+
   eb->revision = revision;
   eb->empty_file = NULL;
   eb->empty_hash = apr_hash_make(subpool);

Modified: subversion/branches/ignore-mergeinfo-log/subversion/libsvn_delta/xdelta.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo-log/subversion/libsvn_delta/xdelta.c?rev=1058221&r1=1058220&r2=1058221&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo-log/subversion/libsvn_delta/xdelta.c (original)
+++ subversion/branches/ignore-mergeinfo-log/subversion/libsvn_delta/xdelta.c Wed Jan 12 16:29:32 2011
@@ -38,61 +38,56 @@
    explicit permission to use it under these terms at 8:02pm on
    Friday, February 11th, 2005.  */
 
-#define ADLER32_MASK      0x0000ffff
-#define ADLER32_CHAR_MASK 0x000000ff
-
 /* Size of the blocks we compute checksums for. This was chosen out of
-   thin air.  Monotone used 64, xdelta1 used 64, rsync uses 128.  */
+   thin air.  Monotone used 64, xdelta1 used 64, rsync uses 128.
+   However, later optimizations assume it to be 256 or less.
+ */
 #define MATCH_BLOCKSIZE 64
 
-/* Structure to store the state of our adler32 checksum.  */
-struct adler32
-{
-  apr_uint32_t s1;
-  apr_uint32_t s2;
-};
-
 /* Feed C_IN into the adler32 checksum and remove C_OUT at the same time.
  * This function may (and will) only be called for characters that are
  * MATCH_BLOCKSIZE positions apart.
+ *
+ * Please note that the lower 16 bits cannot overflow in neither direction.
+ * Therefore, we don't need to split the value into separate values for
+ * sum(char) and sum(sum(char)).
  */
-static APR_INLINE void
-adler32_replace(struct adler32 *ad, const char c_out, const char c_in)
+static APR_INLINE apr_uint32_t
+adler32_replace(apr_uint32_t adler32, const char c_out, const char c_in)
 {
-  apr_uint32_t s1 = ad->s1;
-  apr_uint32_t s2 = ad->s2;
-
-  s2 -= (MATCH_BLOCKSIZE * (((apr_uint32_t) c_out) & ADLER32_CHAR_MASK));
-
-  s1 -= ((apr_uint32_t) (c_out)) & ADLER32_CHAR_MASK;
-  s1 += ((apr_uint32_t) (c_in)) & ADLER32_CHAR_MASK;
+  adler32 -= (MATCH_BLOCKSIZE * 0x10000u * ((unsigned char) c_out));
 
-  s2 += s1;
+  adler32 -= (unsigned char)c_out;
+  adler32 += (unsigned char)c_in;
 
-  ad->s1 = s1 & ADLER32_MASK;
-  ad->s2 = s2 & ADLER32_MASK;
+  return adler32 + adler32 * 0x10000;
 }
 
-/* Return the current adler32 checksum in the adler32 structure.  */
+/* Calculate an peudo-adler32 checksum for MATCH_BLOCKSIZE bytes starting
+   at DATA.  Return the checksum value.  */
 
 static APR_INLINE apr_uint32_t
-adler32_sum(const struct adler32 *ad)
+init_adler32(const char *data)
 {
-  return (ad->s2 << 16) | (ad->s1);
-}
-
-/* Initialize an adler32 checksum structure with DATA, which has length
-   DATALEN.  Return the initialized structure.  */
+  const unsigned char *input = (const unsigned char *)data;
+  const unsigned char *last = input + MATCH_BLOCKSIZE;
 
-static APR_INLINE struct adler32 *
-init_adler32(struct adler32 *ad, const char *data)
-{
-  apr_uint32_t adler32 = svn__adler32(0, data, MATCH_BLOCKSIZE);
+  apr_uint32_t s1 = 0;
+  apr_uint32_t s2 = 0;
 
-  ad->s1 = adler32 & ADLER32_MASK;
-  ad->s2 = (adler32 >> 16) & ADLER32_MASK;
+  for (; input < last; input += 8)
+    {
+      s1 += input[0]; s2 += s1;
+      s1 += input[1]; s2 += s1;
+      s1 += input[2]; s2 += s1;
+      s1 += input[3]; s2 += s1;
+      s1 += input[4]; s2 += s1;
+      s1 += input[5]; s2 += s1;
+      s1 += input[6]; s2 += s1;
+      s1 += input[7]; s2 += s1;
+    }
 
-  return ad;
+  return s2 * 0x10000 + s1;
 }
 
 /* Information for a block of the delta source.  The length of the
@@ -175,7 +170,6 @@ init_blocks_table(const char *data,
                   apr_pool_t *pool)
 {
   apr_size_t i;
-  struct adler32 adler;
   apr_size_t nblocks;
   apr_size_t nslots = 1;
 
@@ -200,10 +194,7 @@ init_blocks_table(const char *data,
      not use that shorter block for deltification (only indirectly
      as an extension of some previous block). */
   for (i = 0; i + MATCH_BLOCKSIZE <= datalen; i += MATCH_BLOCKSIZE)
-    {
-      apr_uint32_t adlersum = adler32_sum(init_adler32(&adler, data + i));
-      add_block(blocks, adlersum, i);
-    }
+    add_block(blocks, init_adler32(data + i), i);
 }
 
 /* Return the lowest position at which A and B differ. If no difference
@@ -246,7 +237,7 @@ match_length(const char *a, const char *
  */
 static apr_size_t
 find_match(const struct blocks *blocks,
-           const struct adler32 *rolling,
+           const apr_uint32_t rolling,
            const char *a,
            apr_size_t asize,
            const char *b,
@@ -255,34 +246,33 @@ find_match(const struct blocks *blocks,
            apr_size_t *aposp,
            apr_size_t pending_insert_start)
 {
-  apr_uint32_t sum = adler32_sum(rolling);
-  apr_size_t tpos, bpos = *bposp;
+  apr_size_t apos, bpos = *bposp;
   apr_size_t delta, max_delta;
 
-  tpos = find_block(blocks, sum, b + bpos);
+  apos = find_block(blocks, rolling, b + bpos);
 
   /* See if we have a match.  */
-  if (tpos == (apr_size_t)-1)
+  if (apos == (apr_size_t)-1)
     return 0;
 
   /* Extend the match forward as far as possible */
-  max_delta = asize - tpos - MATCH_BLOCKSIZE < bsize - bpos - MATCH_BLOCKSIZE
-            ? asize - tpos - MATCH_BLOCKSIZE
+  max_delta = asize - apos - MATCH_BLOCKSIZE < bsize - bpos - MATCH_BLOCKSIZE
+            ? asize - apos - MATCH_BLOCKSIZE
             : bsize - bpos - MATCH_BLOCKSIZE;
-  delta = match_length(a + tpos + MATCH_BLOCKSIZE,
+  delta = match_length(a + apos + MATCH_BLOCKSIZE,
                        b + bpos + MATCH_BLOCKSIZE,
                        max_delta);
 
   /* See if we can extend backwards (max MATCH_BLOCKSIZE-1 steps because A's
      content has been sampled only every MATCH_BLOCKSIZE positions).  */
-  while (tpos > 0 && bpos > pending_insert_start && a[tpos-1] == b[bpos-1])
+  while (apos > 0 && bpos > pending_insert_start && a[apos-1] == b[bpos-1])
     {
-      --tpos;
+      --apos;
       --bpos;
       ++delta;
     }
 
-  *aposp = tpos;
+  *aposp = apos;
   *bposp = bpos;
 
   return MATCH_BLOCKSIZE + delta;
@@ -322,7 +312,7 @@ compute_delta(svn_txdelta__ops_baton_t *
               apr_pool_t *pool)
 {
   struct blocks blocks;
-  struct adler32 rolling;
+  apr_uint32_t rolling;
   apr_size_t lo = 0, pending_insert_start = 0;
 
   /* If the size of the target is smaller than the match blocksize, just
@@ -338,14 +328,14 @@ compute_delta(svn_txdelta__ops_baton_t *
   init_blocks_table(a, asize, &blocks, pool);
 
   /* Initialize our rolling checksum.  */
-  init_adler32(&rolling, b);
+  rolling = init_adler32(b);
   while (lo < bsize)
     {
       apr_size_t matchlen = 0;
       apr_size_t apos;
 
       if (lo + MATCH_BLOCKSIZE <= bsize)
-        matchlen = find_match(&blocks, &rolling, a, asize, b, bsize,
+        matchlen = find_match(&blocks, rolling, a, asize, b, bsize,
                               &lo, &apos, pending_insert_start);
 
       /* If we didn't find a real match, insert the byte at the target
@@ -355,7 +345,7 @@ compute_delta(svn_txdelta__ops_baton_t *
           /* move block one position forward. Short blocks at the end of
              the buffer cannot be used as the beginning of a new match */
           if (lo + MATCH_BLOCKSIZE < bsize)
-            adler32_replace(&rolling, b[lo], b[lo + MATCH_BLOCKSIZE]);
+            rolling = adler32_replace(rolling, b[lo], b[lo+MATCH_BLOCKSIZE]);
 
           lo++;
         }
@@ -378,7 +368,7 @@ compute_delta(svn_txdelta__ops_baton_t *
            * Ignore short buffers at the end of B.
            */
           if (lo + MATCH_BLOCKSIZE <= bsize)
-            init_adler32(&rolling, b + lo);
+            rolling = init_adler32(b + lo);
         }
     }