You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by da...@apache.org on 2012/03/05 10:25:33 UTC

svn commit: r1296975 [6/12] - in /subversion/branches/revprop-packing: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ build/win32/ notes/ notes/api-errata/1.7/ subversion/bindings/javahl/native/ subversion/bindings/javahl/tests/...

Modified: subversion/branches/revprop-packing/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_ra_serf/ra_serf.h?rev=1296975&r1=1296974&r2=1296975&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_ra_serf/ra_serf.h Mon Mar  5 09:25:25 2012
@@ -148,6 +148,9 @@ struct svn_ra_serf__session_t {
   svn_cancel_func_t cancel_func;
   void *cancel_baton;
 
+  /* Ev2 shim callbacks */
+  svn_delta_shim_callbacks_t *shim_callbacks;
+
   /* Error that we've received but not yet returned upstream. */
   svn_error_t *pending_error;
 
@@ -1454,6 +1457,11 @@ svn_ra_serf__error_on_status(int status_
                              const char *path,
                              const char *location);
 
+svn_error_t *
+svn_ra_serf__register_editor_shim_callbacks(svn_ra_session_t *session,
+                                    svn_delta_shim_callbacks_t *callbacks);
+
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: subversion/branches/revprop-packing/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_ra_serf/serf.c?rev=1296975&r1=1296974&r2=1296975&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_ra_serf/serf.c Mon Mar  5 09:25:25 2012
@@ -1157,7 +1157,8 @@ static const svn_ra__vtable_t serf_vtabl
   svn_ra_serf__replay,
   svn_ra_serf__has_capability,
   svn_ra_serf__replay_range,
-  svn_ra_serf__get_deleted_rev
+  svn_ra_serf__get_deleted_rev,
+  svn_ra_serf__register_editor_shim_callbacks
 };
 
 svn_error_t *

Modified: subversion/branches/revprop-packing/subversion/libsvn_ra_serf/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_ra_serf/update.c?rev=1296975&r1=1296974&r2=1296975&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_ra_serf/update.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_ra_serf/update.c Mon Mar  5 09:25:25 2012
@@ -1691,7 +1691,9 @@ start_report(svn_ra_serf__xml_parser_t *
         }
       else
         {
-          SVN_ERR_MALFUNCTION();
+          return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
+                                   _("Unknown tag '%s' while at state %d"),
+                                   name.name, state);
         }
 
     }
@@ -1766,7 +1768,9 @@ start_report(svn_ra_serf__xml_parser_t *
         }
       else
         {
-          SVN_ERR_MALFUNCTION();
+          return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
+                                   _("Unknown tag '%s' while at state %d"),
+                                   name.name, state);
         }
     }
   else if (state == IGNORE_PROP_NAME)

Modified: subversion/branches/revprop-packing/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_ra_serf/util.c?rev=1296975&r1=1296974&r2=1296975&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_ra_serf/util.c Mon Mar  5 09:25:25 2012
@@ -38,6 +38,7 @@
 #include "svn_private_config.h"
 #include "svn_string.h"
 #include "svn_xml.h"
+#include "../libsvn_ra/ra_loader.h"
 #include "private/svn_dep_compat.h"
 #include "private/svn_fspath.h"
 
@@ -2466,3 +2467,13 @@ svn_ra_serf__error_on_status(int status_
 
   return SVN_NO_ERROR;
 }
+
+svn_error_t *
+svn_ra_serf__register_editor_shim_callbacks(svn_ra_session_t *ra_session,
+                                    svn_delta_shim_callbacks_t *callbacks)
+{
+  svn_ra_serf__session_t *session = ra_session->priv;
+
+  session->shim_callbacks = callbacks;
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/revprop-packing/subversion/libsvn_ra_svn/client.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_ra_svn/client.c?rev=1296975&r1=1296974&r2=1296975&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_ra_svn/client.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_ra_svn/client.c Mon Mar  5 09:25:25 2012
@@ -2496,6 +2496,18 @@ ra_svn_get_deleted_rev(svn_ra_session_t 
   return svn_ra_svn_read_cmd_response(conn, pool, "r", revision_deleted);
 }
 
+static svn_error_t *
+ra_svn_register_editor_shim_callbacks(svn_ra_session_t *session,
+                                      svn_delta_shim_callbacks_t *callbacks)
+{
+  svn_ra_svn__session_baton_t *sess_baton = session->priv;
+  svn_ra_svn_conn_t *conn = sess_baton->conn;
+
+  conn->shim_callbacks = callbacks;
+
+  return SVN_NO_ERROR;
+}
+
 
 static const svn_ra__vtable_t ra_svn_vtable = {
   svn_ra_svn_version,
@@ -2532,7 +2544,8 @@ static const svn_ra__vtable_t ra_svn_vta
   ra_svn_replay,
   ra_svn_has_capability,
   ra_svn_replay_range,
-  ra_svn_get_deleted_rev
+  ra_svn_get_deleted_rev,
+  ra_svn_register_editor_shim_callbacks
 };
 
 svn_error_t *

Modified: subversion/branches/revprop-packing/subversion/libsvn_ra_svn/cyrus_auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_ra_svn/cyrus_auth.c?rev=1296975&r1=1296974&r2=1296975&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_ra_svn/cyrus_auth.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_ra_svn/cyrus_auth.c Mon Mar  5 09:25:25 2012
@@ -125,7 +125,7 @@ static int check_result(svn_error_t *err
       svn_error_clear(err);
       return -1;
     }
-    
+
   return 0;
 }
 
@@ -180,9 +180,9 @@ svn_ra_svn__sasl_common_init(apr_pool_t 
                  sasl_mutex_free_cb);
   free_mutexes = apr_array_make(sasl_pool, 0, sizeof(svn_mutex__t *));
   return svn_mutex__init(&array_mutex, TRUE, sasl_pool);
-    
+
 #endif /* APR_HAS_THREADS */
-  
+
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/revprop-packing/subversion/libsvn_ra_svn/editorp.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_ra_svn/editorp.c?rev=1296975&r1=1296974&r2=1296975&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_ra_svn/editorp.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_ra_svn/editorp.c Mon Mar  5 09:25:25 2012
@@ -408,8 +408,6 @@ void svn_ra_svn_get_editor(const svn_del
 {
   svn_delta_editor_t *ra_svn_editor = svn_delta_default_editor(pool);
   ra_svn_edit_baton_t *eb;
-  svn_delta_shim_callbacks_t *shim_callbacks =
-                                    svn_delta_shim_callbacks_default(pool);
 
   eb = apr_palloc(pool, sizeof(*eb));
   eb->conn = conn;
@@ -439,7 +437,7 @@ void svn_ra_svn_get_editor(const svn_del
   *edit_baton = eb;
 
   svn_error_clear(svn_editor__insert_shims(editor, edit_baton, *editor,
-                                           *edit_baton, shim_callbacks,
+                                           *edit_baton, conn->shim_callbacks,
                                            pool, pool));
 }
 

Modified: subversion/branches/revprop-packing/subversion/libsvn_ra_svn/marshal.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_ra_svn/marshal.c?rev=1296975&r1=1296974&r2=1296975&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_ra_svn/marshal.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_ra_svn/marshal.c Mon Mar  5 09:25:25 2012
@@ -125,6 +125,14 @@ svn_error_t *svn_ra_svn_set_capabilities
   return SVN_NO_ERROR;
 }
 
+svn_error_t *
+svn_ra_svn__set_shim_callbacks(svn_ra_svn_conn_t *conn,
+                               svn_delta_shim_callbacks_t *shim_callbacks)
+{
+  conn->shim_callbacks = shim_callbacks;
+  return SVN_NO_ERROR;
+}
+
 svn_boolean_t svn_ra_svn_has_capability(svn_ra_svn_conn_t *conn,
                                         const char *capability)
 {

Modified: subversion/branches/revprop-packing/subversion/libsvn_ra_svn/ra_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_ra_svn/ra_svn.h?rev=1296975&r1=1296974&r2=1296975&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_ra_svn/ra_svn.h (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_ra_svn/ra_svn.h Mon Mar  5 09:25:25 2012
@@ -87,6 +87,7 @@ struct svn_ra_svn_conn_st {
   apr_hash_t *capabilities;
   int compression_level;
   char *remote_ip;
+  svn_delta_shim_callbacks_t *shim_callbacks;
   apr_pool_t *pool;
 };
 

Modified: subversion/branches/revprop-packing/subversion/libsvn_repos/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_repos/commit.c?rev=1296975&r1=1296974&r2=1296975&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_repos/commit.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_repos/commit.c Mon Mar  5 09:25:25 2012
@@ -783,21 +783,45 @@ abort_edit(void *edit_baton,
 
 
 static svn_error_t *
-prop_fetch_func(apr_hash_t **props,
-                void *baton,
-                const char *path,
-                svn_revnum_t base_revision,
-                apr_pool_t *result_pool,
-                apr_pool_t *scratch_pool)
+rationalize_shim_path(const char **fs_path,
+                      struct edit_baton *eb,
+                      const char *path,
+                      apr_pool_t *result_pool,
+                      apr_pool_t *scratch_pool)
+{
+  if (svn_path_is_url(path))
+    {
+      /* This is a copyfrom URL. */
+      path = svn_uri_skip_ancestor(eb->repos_url, path, scratch_pool);
+      *fs_path = svn_fspath__canonicalize(path, scratch_pool);
+    }
+  else
+    {
+      /* This is a base-relative path. */
+      if (path[0] != '/')
+        /* Get an absolute path for use in the FS. */
+        *fs_path = svn_fspath__join(eb->base_path, path, scratch_pool);
+      else
+        *fs_path = path;
+    }
+
+  return SVN_NO_ERROR;
+}
+
+
+static svn_error_t *
+fetch_props_func(apr_hash_t **props,
+                 void *baton,
+                 const char *path,
+                 svn_revnum_t base_revision,
+                 apr_pool_t *result_pool,
+                 apr_pool_t *scratch_pool)
 {
   struct edit_baton *eb = baton;
   svn_fs_root_t *fs_root;
   svn_error_t *err;
 
-  if (path[0] != '/')
-    /* Get an absolute path for use in the FS. */
-    path = svn_fspath__join(eb->base_path, path, scratch_pool);
-
+  SVN_ERR(rationalize_shim_path(&path, eb, path, scratch_pool, scratch_pool));
   SVN_ERR(svn_fs_revision_root(&fs_root, eb->fs,
                                svn_fs_txn_base_revision(eb->txn),
                                scratch_pool));
@@ -815,7 +839,7 @@ prop_fetch_func(apr_hash_t **props,
 }
 
 static svn_error_t *
-kind_fetch_func(svn_kind_t *kind,
+fetch_kind_func(svn_kind_t *kind,
                 void *baton,
                 const char *path,
                 svn_revnum_t base_revision,
@@ -828,27 +852,14 @@ kind_fetch_func(svn_kind_t *kind,
   if (!SVN_IS_VALID_REVNUM(base_revision))
     base_revision = svn_fs_txn_base_revision(eb->txn);
 
-  if (svn_path_is_url(path))
-    {
-      /* This is a copyfrom URL. */
-      path = svn_uri_skip_ancestor(eb->repos_url, path, scratch_pool);
-      path = svn_fspath__canonicalize(path, scratch_pool);
-    }
-  else
-    {
-      /* This is a base-relative path. */
-      if (path[0] != '/')
-        /* Get an absolute path for use in the FS. */
-        path = svn_fspath__join(eb->base_path, path, scratch_pool);
-    }
-
+  SVN_ERR(rationalize_shim_path(&path, eb, path, scratch_pool, scratch_pool));
   SVN_ERR(svn_fs_revision_root(&fs_root, eb->fs, base_revision, scratch_pool));
 
   SVN_ERR(svn_fs_check_path(&node_kind, fs_root, path, scratch_pool));
   *kind = svn__kind_from_node_kind(node_kind, FALSE);
 
   return SVN_NO_ERROR;
-} 
+}
 
 static svn_error_t *
 fetch_base_func(const char **filename,
@@ -868,20 +879,7 @@ fetch_base_func(const char **filename,
   if (!SVN_IS_VALID_REVNUM(base_revision))
     base_revision = svn_fs_txn_base_revision(eb->txn);
 
-  if (svn_path_is_url(path))
-    {
-      /* This is a copyfrom URL. */
-      path = svn_uri_skip_ancestor(eb->repos_url, path, scratch_pool);
-      path = svn_fspath__canonicalize(path, scratch_pool);
-    }
-  else
-    {
-      /* This is a base-relative path. */
-      if (path[0] != '/')
-        /* Get an absolute path for use in the FS. */
-        path = svn_fspath__join(eb->base_path, path, scratch_pool);
-    }
-
+  SVN_ERR(rationalize_shim_path(&path, eb, path, scratch_pool, scratch_pool));
   SVN_ERR(svn_fs_revision_root(&fs_root, eb->fs, base_revision, scratch_pool));
 
   err = svn_fs_file_contents(&contents, fs_root, path, scratch_pool);
@@ -977,8 +975,8 @@ svn_repos_get_commit_editor5(const svn_d
   *edit_baton = eb;
   *editor = e;
 
-  shim_callbacks->fetch_props_func = prop_fetch_func;
-  shim_callbacks->fetch_kind_func = kind_fetch_func;
+  shim_callbacks->fetch_props_func = fetch_props_func;
+  shim_callbacks->fetch_kind_func = fetch_kind_func;
   shim_callbacks->fetch_base_func = fetch_base_func;
   shim_callbacks->fetch_baton = eb;
 

Modified: subversion/branches/revprop-packing/subversion/libsvn_repos/dump.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_repos/dump.c?rev=1296975&r1=1296974&r2=1296975&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_repos/dump.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_repos/dump.c Mon Mar  5 09:25:25 2012
@@ -864,8 +864,14 @@ fetch_props_func(apr_hash_t **props,
 {
   struct edit_baton *eb = baton;
   svn_error_t *err;
+  svn_fs_root_t *fs_root;
+
+  if (!SVN_IS_VALID_REVNUM(base_revision))
+    base_revision = eb->current_rev - 1;
 
-  err = svn_fs_node_proplist(props, eb->fs_root, path, result_pool);
+  SVN_ERR(svn_fs_revision_root(&fs_root, eb->fs, base_revision, scratch_pool));
+
+  err = svn_fs_node_proplist(props, fs_root, path, result_pool);
   if (err && err->apr_err == SVN_ERR_FS_NOT_FOUND)
     {
       svn_error_clear(err);
@@ -890,10 +896,9 @@ fetch_kind_func(svn_kind_t *kind,
   svn_fs_root_t *fs_root;
 
   if (!SVN_IS_VALID_REVNUM(base_revision))
-    fs_root = eb->fs_root;
-  else
-    SVN_ERR(svn_fs_revision_root(&fs_root, eb->fs, base_revision,
-                                 scratch_pool));
+    base_revision = eb->current_rev - 1;
+
+  SVN_ERR(svn_fs_revision_root(&fs_root, eb->fs, base_revision, scratch_pool));
 
   SVN_ERR(svn_fs_check_path(&node_kind, fs_root, path, scratch_pool));
   *kind = svn__kind_from_node_kind(node_kind, FALSE);
@@ -917,10 +922,9 @@ fetch_base_func(const char **filename,
   svn_fs_root_t *fs_root;
 
   if (!SVN_IS_VALID_REVNUM(base_revision))
-    fs_root = eb->fs_root;
-  else
-    SVN_ERR(svn_fs_revision_root(&fs_root, eb->fs, base_revision,
-                                 scratch_pool));
+    base_revision = eb->current_rev - 1;
+
+  SVN_ERR(svn_fs_revision_root(&fs_root, eb->fs, base_revision, scratch_pool));
 
   err = svn_fs_file_contents(&contents, fs_root, path, scratch_pool);
   if (err && err->apr_err == SVN_ERR_FS_NOT_FOUND)
@@ -1391,10 +1395,9 @@ svn_repos_verify_fs2(svn_repos_t *repos,
                                "(youngest revision is %ld)"),
                              end_rev, youngest);
 
-  /* Verify global/auxiliary data before verifying revisions. */
-  if (start_rev == 0)
-    SVN_ERR(svn_fs_verify(svn_fs_path(fs, pool), cancel_func, cancel_baton,
-                          pool));
+  /* Verify global/auxiliary data and backend-specific data first. */
+  SVN_ERR(svn_fs_verify(svn_fs_path(fs, pool), cancel_func, cancel_baton,
+                        start_rev, end_rev, pool));
 
   /* Create a notify object that we can reuse within the loop. */
   if (notify_func)
@@ -1415,7 +1418,7 @@ svn_repos_verify_fs2(svn_repos_t *repos,
       /* Get cancellable dump editor, but with our close_directory handler. */
       SVN_ERR(get_dump_editor((const svn_delta_editor_t **)&dump_editor,
                               &dump_edit_baton, fs, rev, "",
-                              svn_stream_empty(pool),
+                              svn_stream_empty(iterpool),
                               NULL, NULL,
                               verify_close_directory,
                               notify_func, notify_baton,
@@ -1432,6 +1435,10 @@ svn_repos_verify_fs2(svn_repos_t *repos,
       SVN_ERR(svn_repos_replay2(to_root, "", SVN_INVALID_REVNUM, FALSE,
                                 cancel_editor, cancel_edit_baton,
                                 NULL, NULL, iterpool));
+      /* While our editor close_edit implementation is a no-op, we still
+         do this for completeness. */
+      SVN_ERR(cancel_editor->close_edit(cancel_edit_baton, iterpool));
+
       SVN_ERR(svn_fs_revision_proplist(&props, fs, rev, iterpool));
 
       if (notify_func)

Modified: subversion/branches/revprop-packing/subversion/libsvn_repos/fs-wrap.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_repos/fs-wrap.c?rev=1296975&r1=1296974&r2=1296975&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_repos/fs-wrap.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_repos/fs-wrap.c Mon Mar  5 09:25:25 2012
@@ -61,7 +61,7 @@ svn_repos_fs_commit_txn(const char **con
     return err;
 
   /* Run post-commit hooks. */
-  if ((err2 = svn_repos__hooks_post_commit(repos, *new_rev, pool)))
+  if ((err2 = svn_repos__hooks_post_commit(repos, *new_rev, txn_name, pool)))
     {
       err2 = svn_error_create
                (SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED, err2,

Modified: subversion/branches/revprop-packing/subversion/libsvn_repos/hooks.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_repos/hooks.c?rev=1296975&r1=1296974&r2=1296975&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_repos/hooks.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_repos/hooks.c Mon Mar  5 09:25:25 2012
@@ -159,6 +159,37 @@ check_hook_result(const char *name, cons
                           failure_message->data);
 }
 
+/* Copy the environment given as key/value pairs of ENV_HASH into
+ * an array of C strings allocated in RESULT_POOL.
+ * If the hook environment is empty, return NULL.
+ * Use SCRATCH_POOL for temporary allocations. */
+static const char **
+env_from_env_hash(apr_hash_t *env_hash,
+                  apr_pool_t *result_pool,
+                  apr_pool_t *scratch_pool)
+{
+  apr_hash_index_t *hi;
+  const char **env;
+  const char **envp;
+
+  if (!env_hash || apr_hash_count(env_hash) == 0)
+    return NULL;
+
+  env = apr_palloc(result_pool,
+                   sizeof(const char *) * (apr_hash_count(env_hash) + 1));
+  envp = env;
+  for (hi = apr_hash_first(scratch_pool, env_hash); hi; hi = apr_hash_next(hi))
+    {
+      *envp = apr_psprintf(result_pool, "%s=%s",
+                           (const char *)svn__apr_hash_index_key(hi),
+                           (const char *)svn__apr_hash_index_val(hi));
+      envp++;
+    }
+  *envp = NULL;
+
+  return env;
+}
+
 /* NAME, CMD and ARGS are the name, path to and arguments for the hook
    program that is to be run.  The hook's exit status will be checked,
    and if an error occurred the hook's stderr output will be added to
@@ -174,6 +205,7 @@ run_hook_cmd(svn_string_t **result,
              const char *name,
              const char *cmd,
              const char **args,
+             apr_hash_t *hooks_env,
              apr_file_t *stdin_handle,
              apr_pool_t *pool)
 {
@@ -196,9 +228,10 @@ run_hook_cmd(svn_string_t **result,
             (apr_err, _("Can't create null stdout for hook '%s'"), cmd);
     }
 
-  err = svn_io_start_cmd2(&cmd_proc, ".", cmd, args, FALSE,
-                          FALSE, stdin_handle, result != NULL, null_handle,
-                          TRUE, NULL, pool);
+  err = svn_io_start_cmd3(&cmd_proc, ".", cmd, args,
+                          env_from_env_hash(hooks_env, pool, pool),
+                          FALSE, FALSE, stdin_handle, result != NULL,
+                          null_handle, TRUE, NULL, pool);
 
   if (err)
     {
@@ -358,8 +391,8 @@ svn_repos__hooks_start_commit(svn_repos_
       args[3] = capabilities_string;
       args[4] = NULL;
 
-      SVN_ERR(run_hook_cmd(NULL, SVN_REPOS__HOOK_START_COMMIT, hook, args, NULL,
-                           pool));
+      SVN_ERR(run_hook_cmd(NULL, SVN_REPOS__HOOK_START_COMMIT, hook, args,
+                           repos->hooks_env, NULL, pool));
     }
 
   return SVN_NO_ERROR;
@@ -438,7 +471,7 @@ svn_repos__hooks_pre_commit(svn_repos_t 
                                  APR_READ, APR_OS_DEFAULT, pool));
 
       SVN_ERR(run_hook_cmd(NULL, SVN_REPOS__HOOK_PRE_COMMIT, hook, args,
-                           stdin_handle, pool));
+                           repos->hooks_env, stdin_handle, pool));
     }
 
   return SVN_NO_ERROR;
@@ -448,6 +481,7 @@ svn_repos__hooks_pre_commit(svn_repos_t 
 svn_error_t  *
 svn_repos__hooks_post_commit(svn_repos_t *repos,
                              svn_revnum_t rev,
+                             const char *txn_name,
                              apr_pool_t *pool)
 {
   const char *hook = svn_repos_post_commit_hook(repos, pool);
@@ -459,15 +493,16 @@ svn_repos__hooks_post_commit(svn_repos_t
     }
   else if (hook)
     {
-      const char *args[4];
+      const char *args[5];
 
       args[0] = hook;
       args[1] = svn_dirent_local_style(svn_repos_path(repos, pool), pool);
       args[2] = apr_psprintf(pool, "%ld", rev);
-      args[3] = NULL;
+      args[3] = txn_name;
+      args[4] = NULL;
 
-      SVN_ERR(run_hook_cmd(NULL, SVN_REPOS__HOOK_POST_COMMIT, hook, args, NULL,
-                           pool));
+      SVN_ERR(run_hook_cmd(NULL, SVN_REPOS__HOOK_POST_COMMIT, hook, args,
+                           repos->hooks_env, NULL, pool));
     }
 
   return SVN_NO_ERROR;
@@ -514,8 +549,8 @@ svn_repos__hooks_pre_revprop_change(svn_
       args[5] = action_string;
       args[6] = NULL;
 
-      SVN_ERR(run_hook_cmd(NULL, SVN_REPOS__HOOK_PRE_REVPROP_CHANGE, hook, args,
-                           stdin_handle, pool));
+      SVN_ERR(run_hook_cmd(NULL, SVN_REPOS__HOOK_PRE_REVPROP_CHANGE, hook,
+                           args, repos->hooks_env, stdin_handle, pool));
 
       SVN_ERR(svn_io_file_close(stdin_handle, pool));
     }
@@ -577,7 +612,7 @@ svn_repos__hooks_post_revprop_change(svn
       args[6] = NULL;
 
       SVN_ERR(run_hook_cmd(NULL, SVN_REPOS__HOOK_POST_REVPROP_CHANGE, hook,
-                           args, stdin_handle, pool));
+                           args, repos->hooks_env, stdin_handle, pool));
 
       SVN_ERR(svn_io_file_close(stdin_handle, pool));
     }
@@ -615,8 +650,8 @@ svn_repos__hooks_pre_lock(svn_repos_t *r
       args[5] = steal_lock ? "1" : "0";
       args[6] = NULL;
 
-      SVN_ERR(run_hook_cmd(&buf, SVN_REPOS__HOOK_PRE_LOCK, hook, args, NULL,
-                           pool));
+      SVN_ERR(run_hook_cmd(&buf, SVN_REPOS__HOOK_PRE_LOCK, hook, args,
+                           repos->hooks_env, NULL, pool));
 
       if (token)
         /* No validation here; the FS will take care of that. */
@@ -660,7 +695,7 @@ svn_repos__hooks_post_lock(svn_repos_t *
       args[4] = NULL;
 
       SVN_ERR(run_hook_cmd(NULL, SVN_REPOS__HOOK_POST_LOCK, hook, args,
-                           stdin_handle, pool));
+                           repos->hooks_env, stdin_handle, pool));
 
       SVN_ERR(svn_io_file_close(stdin_handle, pool));
     }
@@ -696,8 +731,8 @@ svn_repos__hooks_pre_unlock(svn_repos_t 
       args[5] = break_lock ? "1" : "0";
       args[6] = NULL;
 
-      SVN_ERR(run_hook_cmd(NULL, SVN_REPOS__HOOK_PRE_UNLOCK, hook, args, NULL,
-                           pool));
+      SVN_ERR(run_hook_cmd(NULL, SVN_REPOS__HOOK_PRE_UNLOCK, hook, args,
+                           repos->hooks_env, NULL, pool));
     }
 
   return SVN_NO_ERROR;
@@ -734,7 +769,7 @@ svn_repos__hooks_post_unlock(svn_repos_t
       args[4] = NULL;
 
       SVN_ERR(run_hook_cmd(NULL, SVN_REPOS__HOOK_POST_UNLOCK, hook, args,
-                           stdin_handle, pool));
+                           repos->hooks_env, stdin_handle, pool));
 
       SVN_ERR(svn_io_file_close(stdin_handle, pool));
     }

Modified: subversion/branches/revprop-packing/subversion/libsvn_repos/load-fs-vtable.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_repos/load-fs-vtable.c?rev=1296975&r1=1296974&r2=1296975&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_repos/load-fs-vtable.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_repos/load-fs-vtable.c Mon Mar  5 09:25:25 2012
@@ -487,7 +487,7 @@ new_revision_record(void **revision_bato
      several separate operations. It is highly susceptible to race conditions.
      Calculate the revision 'offset' for finding copyfrom sources.
      It might be positive or negative. */
-  rb->rev_offset = (apr_int32_t) (rb->rev) - (head_rev + 1);
+  rb->rev_offset = (apr_int32_t) ((rb->rev) - (head_rev + 1));
 
   if ((rb->rev > 0) && (! rb->skipped))
     {
@@ -506,7 +506,7 @@ new_revision_record(void **revision_bato
       if (!SVN_IS_VALID_REVNUM(pb->oldest_old_rev))
         pb->oldest_old_rev = rb->rev;
     }
-  
+
   /* If we're skipping this revision, try to notify someone. */
   if (rb->skipped && pb->notify_func)
     {
@@ -900,19 +900,28 @@ close_revision(void *baton)
   const char *conflict_msg = NULL;
   svn_revnum_t committed_rev;
   svn_error_t *err;
+  const char *txn_name;
 
   /* If we're skipping this revision or it has an invalid revision
      number, we're done here. */
   if (rb->skipped || (rb->rev <= 0))
     return SVN_NO_ERROR;
 
+  /* Get the txn name, if it will be needed. */
+  if (pb->use_pre_commit_hook || pb->use_post_commit_hook)
+    {
+      err = svn_fs_txn_name(&txn_name, rb->txn, rb->pool);
+      if (err)
+        {
+          svn_error_clear(svn_fs_abort_txn(rb->txn, rb->pool));
+          return svn_error_trace(err);
+        }
+    }
+
   /* Run the pre-commit hook, if so commanded. */
   if (pb->use_pre_commit_hook)
     {
-      const char *txn_name;
-      err = svn_fs_txn_name(&txn_name, rb->txn, rb->pool);
-      if (! err)
-        err = svn_repos__hooks_pre_commit(pb->repos, txn_name, rb->pool);
+      err = svn_repos__hooks_pre_commit(pb->repos, txn_name, rb->pool);
       if (err)
         {
           svn_error_clear(svn_fs_abort_txn(rb->txn, rb->pool));
@@ -945,7 +954,7 @@ close_revision(void *baton)
   if (pb->use_post_commit_hook)
     {
       if ((err = svn_repos__hooks_post_commit(pb->repos, committed_rev,
-                                              rb->pool)))
+                                              txn_name, rb->pool)))
         return svn_error_create
           (SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED, err,
            _("Commit succeeded, but post-commit hook failed"));

Modified: subversion/branches/revprop-packing/subversion/libsvn_repos/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_repos/log.c?rev=1296975&r1=1296974&r2=1296975&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_repos/log.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_repos/log.c Mon Mar  5 09:25:25 2012
@@ -264,6 +264,43 @@ detect_changed(apr_hash_t **changed,
                                              : svn_tristate_false;
       item->props_modified = change->prop_mod ? svn_tristate_true
                                               : svn_tristate_false;
+
+      /* Pre-1.6 revision files don't store the change path kind, so fetch
+         it manually. */
+      if (item->node_kind == svn_node_unknown)
+        {
+          svn_fs_root_t *check_root = root;
+          const char *check_path = path;
+
+          /* Deleted items don't exist so check earlier revision.  We
+             know the parent must exist and could be a copy */
+          if (change->change_kind == svn_fs_path_change_delete)
+            {
+              svn_fs_history_t *history;
+              svn_revnum_t prev_rev;
+              const char *parent_path, *name;
+
+              svn_fspath__split(&parent_path, &name, path, subpool);
+
+              SVN_ERR(svn_fs_node_history(&history, root, parent_path,
+                                          subpool));
+
+              /* Two calls because the first call returns the original
+                 revision as the deleted child means it is 'interesting' */
+              SVN_ERR(svn_fs_history_prev(&history, history, TRUE, subpool));
+              SVN_ERR(svn_fs_history_prev(&history, history, TRUE, subpool));
+
+              SVN_ERR(svn_fs_history_location(&parent_path, &prev_rev, history,
+                                              subpool));
+              SVN_ERR(svn_fs_revision_root(&check_root, fs, prev_rev, subpool));
+              check_path = svn_fspath__join(parent_path, name, subpool);
+            }
+
+          SVN_ERR(svn_fs_check_path(&item->node_kind, check_root, check_path,
+                                    subpool));
+        }
+
+
       if ((action == 'A') || (action == 'R'))
         {
           const char *copyfrom_path;
@@ -1115,7 +1152,6 @@ send_log(svn_revnum_t rev,
       && log_target_history_as_mergeinfo
       && apr_hash_count(log_target_history_as_mergeinfo))
     {
-      svn_boolean_t path_is_in_history = FALSE;
       apr_hash_index_t *hi;
       apr_pool_t *subpool = svn_pool_create(pool);
 
@@ -1128,10 +1164,12 @@ send_log(svn_revnum_t rev,
            hi;
            hi = apr_hash_next(hi))
         {
+          svn_boolean_t path_is_in_history = FALSE;
           const char *changed_path = svn__apr_hash_index_key(hi);
           apr_hash_index_t *hi2;
           apr_pool_t *inner_subpool = svn_pool_create(subpool);
 
+          /* Look at each path on the log target's mergeinfo. */
           for (hi2 = apr_hash_first(inner_subpool,
                                     log_target_history_as_mergeinfo);
                hi2;
@@ -1142,6 +1180,8 @@ send_log(svn_revnum_t rev,
               apr_array_header_t *rangelist =
                 svn__apr_hash_index_val(hi2);
 
+              /* Check whether CHANGED_PATH at revision REV is a child of
+                 a (path, revision) tuple in LOG_TARGET_HISTORY_AS_MERGEINFO. */
               if (svn_fspath__skip_ancestor(mergeinfo_path, changed_path))
                 {
                   int i;
@@ -1771,7 +1811,7 @@ store_search(svn_mergeinfo_t processed,
                                                   sizeof(svn_merge_range_t*));
       svn_merge_range_t *range = apr_palloc(processed_pool,
                                             sizeof(svn_merge_range_t));
-      
+
       range->start = start;
       range->end = end;
       range->inheritable = TRUE;
@@ -2228,17 +2268,40 @@ svn_repos_get_logs4(svn_repos_t *repos,
       int i;
       apr_pool_t *iterpool = svn_pool_create(pool);
 
+      /* If we are provided an authz callback function, use it to
+         verify that the user has read access to the root path in the
+         first of our revisions.
+
+         ### FIXME:  Strictly speaking, we should be checking this
+         ### access in every revision along the line.  But currently,
+         ### there are no known authz implementations which concern
+         ### themselves with per-revision access.  */
+      if (authz_read_func)
+        {
+          svn_boolean_t readable;
+          svn_fs_root_t *rev_root;
+
+          SVN_ERR(svn_fs_revision_root(&rev_root, fs,
+                                       descending_order ? end : start, pool));
+          SVN_ERR(authz_read_func(&readable, rev_root, "",
+                                  authz_read_baton, pool));
+          if (! readable)
+            return svn_error_create(SVN_ERR_AUTHZ_UNREADABLE, NULL, NULL);
+        }
+
       send_count = end - start + 1;
       if (limit && send_count > limit)
         send_count = limit;
       for (i = 0; i < send_count; ++i)
         {
-          svn_revnum_t rev = start + i;
+          svn_revnum_t rev;
 
           svn_pool_clear(iterpool);
 
           if (descending_order)
             rev = end - i;
+          else
+            rev = start + i;
           SVN_ERR(send_log(rev, fs, NULL, NULL, discover_changed_paths, FALSE,
                            FALSE, revprops, FALSE, receiver,
                            receiver_baton, authz_read_func,

Modified: subversion/branches/revprop-packing/subversion/libsvn_repos/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_repos/replay.c?rev=1296975&r1=1296974&r2=1296975&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_repos/replay.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_repos/replay.c Mon Mar  5 09:25:25 2012
@@ -352,6 +352,116 @@ is_within_base_path(const char *path, co
   return FALSE;
 }
 
+/* Given PATH deleted under ROOT, return in READABLE whether the path was
+   readable prior to the deletion.  Consult COPIES (a stack of 'struct
+   copy_info') and AUTHZ_READ_FUNC. */
+static svn_error_t *
+was_readable(svn_boolean_t *readable,
+             svn_fs_root_t *root,
+             const char *path,
+             apr_array_header_t *copies,
+             svn_repos_authz_func_t authz_read_func,
+             void *authz_read_baton,
+             apr_pool_t *result_pool,
+             apr_pool_t *scratch_pool)
+{
+  svn_fs_root_t *inquire_root;
+  const char *inquire_path;
+  struct copy_info *info = NULL;
+  const char *relpath;
+
+  /* Short circuit. */
+  if (! authz_read_func)
+    {
+      *readable = TRUE;
+      return SVN_NO_ERROR;
+    }
+
+  if (copies->nelts != 0)
+    info = APR_ARRAY_IDX(copies, copies->nelts - 1, struct copy_info *);
+
+  /* Are we under a copy? */
+  if (info && (relpath = svn_relpath_skip_ancestor(info->path, path)))
+    {
+      SVN_ERR(svn_fs_revision_root(&inquire_root, svn_fs_root_fs(root),
+                                   info->copyfrom_rev, scratch_pool));
+      inquire_path = svn_fspath__join(info->copyfrom_path, relpath,
+                                      scratch_pool);
+    }
+  else
+    {
+      /* Compute the revision that ROOT is based on.  (Note that ROOT is not
+         r0's root, since this function is only called for deletions.)
+         ### Need a more succinct way to express this */
+      svn_revnum_t inquire_rev = SVN_INVALID_REVNUM;
+      if (svn_fs_is_txn_root(root))
+        inquire_rev = svn_fs_txn_root_base_revision(root);
+      if (svn_fs_is_revision_root(root))
+        inquire_rev =  svn_fs_revision_root_revision(root)-1;
+      SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(inquire_rev));
+
+      SVN_ERR(svn_fs_revision_root(&inquire_root, svn_fs_root_fs(root),
+                                   inquire_rev, scratch_pool));
+      inquire_path = path;
+    }
+
+  SVN_ERR(authz_read_func(readable, inquire_root, inquire_path,
+                          authz_read_baton, result_pool));
+
+  return SVN_NO_ERROR;
+}
+
+/* Initialize COPYFROM_ROOT, COPYFROM_PATH, and COPYFROM_REV with the
+   revision root, fspath, and revnum of the copyfrom of CHANGE, which
+   corresponds to PATH under ROOT.  If the copyfrom info is valid
+   (i.e., is not (NULL, SVN_INVALID_REVNUM)), then initialize SRC_READABLE
+   too, consulting AUTHZ_READ_FUNC and AUTHZ_READ_BATON if provided. */
+static svn_error_t *
+fill_copyfrom(svn_fs_root_t **copyfrom_root,
+              const char **copyfrom_path,
+              svn_revnum_t *copyfrom_rev,
+              svn_boolean_t *src_readable,
+              svn_fs_root_t *root,
+              svn_fs_path_change2_t *change,
+              svn_repos_authz_func_t authz_read_func,
+              void *authz_read_baton,
+              const char *path,
+              apr_pool_t *result_pool,
+              apr_pool_t *scratch_pool)
+{
+  if (! change->copyfrom_known)
+    {
+      SVN_ERR(svn_fs_copied_from(&(change->copyfrom_rev),
+                                 &(change->copyfrom_path),
+                                 root, path, result_pool));
+      change->copyfrom_known = TRUE;
+    }
+  *copyfrom_rev = change->copyfrom_rev;
+  *copyfrom_path = change->copyfrom_path;
+
+  if (*copyfrom_path && SVN_IS_VALID_REVNUM(*copyfrom_rev))
+    {
+      SVN_ERR(svn_fs_revision_root(copyfrom_root,
+                                   svn_fs_root_fs(root),
+                                   *copyfrom_rev, result_pool));
+
+      if (authz_read_func)
+        {
+          SVN_ERR(authz_read_func(src_readable, *copyfrom_root,
+                                  *copyfrom_path,
+                                  authz_read_baton, result_pool));
+        }
+      else
+        *src_readable = TRUE;
+    }
+  else
+    {
+      *copyfrom_root = NULL;
+      /* SRC_READABLE left uninitialized */
+    }
+  return SVN_NO_ERROR;
+}
+
 static svn_error_t *
 path_driver_cb_func(void **dir_baton,
                     void *parent_baton,
@@ -368,7 +478,6 @@ path_driver_cb_func(void **dir_baton,
   void *file_baton = NULL;
   svn_revnum_t copyfrom_rev;
   const char *copyfrom_path;
-  svn_boolean_t src_readable = TRUE;
   svn_fs_root_t *source_root = cb->compare_root;
   const char *source_fspath = NULL;
   const char *base_path = cb->base_path;
@@ -384,9 +493,9 @@ path_driver_cb_func(void **dir_baton,
   while (cb->copies->nelts > 0
          && ! svn_dirent_is_ancestor(APR_ARRAY_IDX(cb->copies,
                                                    cb->copies->nelts - 1,
-                                                   struct copy_info).path,
+                                                   struct copy_info *)->path,
                                      edit_path))
-    cb->copies->nelts--;
+    apr_array_pop(cb->copies);
 
   change = apr_hash_get(cb->changed_paths, edit_path, APR_HASH_KEY_STRING);
   if (! change)
@@ -419,8 +528,18 @@ path_driver_cb_func(void **dir_baton,
 
   /* Handle any deletions. */
   if (do_delete)
-    SVN_ERR(editor->delete_entry(edit_path, SVN_INVALID_REVNUM,
-                                 parent_baton, pool));
+    {
+      svn_boolean_t readable;
+
+      /* Issue #4121: delete under under a copy, of a path that was unreadable
+         at its pre-copy location. */
+      SVN_ERR(was_readable(&readable, root, edit_path, cb->copies,
+                            cb->authz_read_func, cb->authz_read_baton,
+                            pool, pool));
+      if (readable)
+        SVN_ERR(editor->delete_entry(edit_path, SVN_INVALID_REVNUM,
+                                     parent_baton, pool));
+    }
 
   /* Fetch the node kind if it makes sense to do so. */
   if (! do_delete || do_add)
@@ -437,31 +556,14 @@ path_driver_cb_func(void **dir_baton,
   /* Handle any adds/opens. */
   if (do_add)
     {
-      svn_fs_root_t *copyfrom_root = NULL;
-      /* Was this node copied? */
-      if (! change->copyfrom_known)
-        {
-          SVN_ERR(svn_fs_copied_from(&(change->copyfrom_rev),
-                                     &(change->copyfrom_path),
-                                     root, edit_path, pool));
-          change->copyfrom_known = TRUE;
-        }
-      copyfrom_rev = change->copyfrom_rev;
-      copyfrom_path = change->copyfrom_path;
+      svn_boolean_t src_readable;
+      svn_fs_root_t *copyfrom_root;
 
-      if (copyfrom_path && SVN_IS_VALID_REVNUM(copyfrom_rev))
-        {
-          SVN_ERR(svn_fs_revision_root(&copyfrom_root,
-                                       svn_fs_root_fs(root),
-                                       copyfrom_rev, pool));
-
-          if (cb->authz_read_func)
-            {
-              SVN_ERR(cb->authz_read_func(&src_readable, copyfrom_root,
-                                          copyfrom_path,
-                                          cb->authz_read_baton, pool));
-            }
-        }
+      /* Was this node copied? */
+      SVN_ERR(fill_copyfrom(&copyfrom_root, &copyfrom_path, &copyfrom_rev,
+                            &src_readable, root, change,
+                            cb->authz_read_func, cb->authz_read_baton,
+                            edit_path, pool, pool));
 
       /* If we have a copyfrom path, and we can't read it or we're just
          ignoring it, or the copyfrom rev is prior to the low water mark
@@ -511,11 +613,13 @@ path_driver_cb_func(void **dir_baton,
              (possibly nested) copy operation. */
           if (change->node_kind == svn_node_dir)
             {
-              struct copy_info *info = &APR_ARRAY_PUSH(cb->copies,
-                                                       struct copy_info);
+              struct copy_info *info = apr_pcalloc(cb->pool, sizeof(*info));
+
               info->path = apr_pstrdup(cb->pool, edit_path);
               info->copyfrom_path = apr_pstrdup(cb->pool, copyfrom_path);
               info->copyfrom_rev = copyfrom_rev;
+
+              APR_ARRAY_PUSH(cb->copies, struct copy_info *) = info;
             }
 
           /* Save the source so that we can use it later, when we
@@ -531,11 +635,13 @@ path_driver_cb_func(void **dir_baton,
              past... */
           if (change->node_kind == svn_node_dir && cb->copies->nelts > 0)
             {
-              struct copy_info *info = &APR_ARRAY_PUSH(cb->copies,
-                                                       struct copy_info);
+              struct copy_info *info = apr_pcalloc(cb->pool, sizeof(*info));
+
               info->path = apr_pstrdup(cb->pool, edit_path);
               info->copyfrom_path = NULL;
               info->copyfrom_rev = SVN_INVALID_REVNUM;
+
+              APR_ARRAY_PUSH(cb->copies, struct copy_info *) = info;
             }
           source_root = NULL;
           source_fspath = NULL;
@@ -568,9 +674,9 @@ path_driver_cb_func(void **dir_baton,
          delta source. */
       if (cb->copies->nelts > 0)
         {
-          struct copy_info *info = &APR_ARRAY_IDX(cb->copies,
-                                                  cb->copies->nelts - 1,
-                                                  struct copy_info);
+          struct copy_info *info = APR_ARRAY_IDX(cb->copies,
+                                                 cb->copies->nelts - 1,
+                                                 struct copy_info *);
           if (info->copyfrom_path)
             {
               const char *relpath = svn_relpath_skip_ancestor(info->path,
@@ -597,45 +703,31 @@ path_driver_cb_func(void **dir_baton,
     {
       if (change->prop_mod)
         {
-          if (cb->compare_root)
-            {
-              apr_array_header_t *prop_diffs;
-              apr_hash_t *old_props;
-              apr_hash_t *new_props;
-              int i;
-
-              if (source_root)
-                SVN_ERR(svn_fs_node_proplist(&old_props, source_root,
-                                             source_fspath, pool));
-              else
-                old_props = apr_hash_make(pool);
-
-              SVN_ERR(svn_fs_node_proplist(&new_props, root, edit_path, pool));
-
-              SVN_ERR(svn_prop_diffs(&prop_diffs, new_props, old_props,
-                                     pool));
-
-              for (i = 0; i < prop_diffs->nelts; ++i)
-                {
-                  svn_prop_t *pc = &APR_ARRAY_IDX(prop_diffs, i, svn_prop_t);
-                   if (change->node_kind == svn_node_dir)
-                     SVN_ERR(editor->change_dir_prop(*dir_baton, pc->name,
-                                                     pc->value, pool));
-                   else if (change->node_kind == svn_node_file)
-                     SVN_ERR(editor->change_file_prop(file_baton, pc->name,
-                                                      pc->value, pool));
-                }
-            }
+          apr_array_header_t *prop_diffs;
+          apr_hash_t *old_props;
+          apr_hash_t *new_props;
+          int i;
+
+          if (source_root)
+            SVN_ERR(svn_fs_node_proplist(&old_props, source_root,
+                                         source_fspath, pool));
           else
+            old_props = apr_hash_make(pool);
+
+          SVN_ERR(svn_fs_node_proplist(&new_props, root, edit_path, pool));
+
+          SVN_ERR(svn_prop_diffs(&prop_diffs, new_props, old_props,
+                                 pool));
+
+          for (i = 0; i < prop_diffs->nelts; ++i)
             {
-              /* Just do a dummy prop change to signal that there are *any*
-                 propmods. */
-              if (change->node_kind == svn_node_dir)
-                SVN_ERR(editor->change_dir_prop(*dir_baton, "", NULL,
-                                                pool));
-              else if (change->node_kind == svn_node_file)
-                SVN_ERR(editor->change_file_prop(file_baton, "", NULL,
-                                                 pool));
+              svn_prop_t *pc = &APR_ARRAY_IDX(prop_diffs, i, svn_prop_t);
+               if (change->node_kind == svn_node_dir)
+                 SVN_ERR(editor->change_dir_prop(*dir_baton, pc->name,
+                                                 pc->value, pool));
+               else if (change->node_kind == svn_node_file)
+                 SVN_ERR(editor->change_file_prop(file_baton, pc->name,
+                                                  pc->value, pool));
             }
         }
 
@@ -806,7 +898,7 @@ svn_repos_replay2(svn_fs_root_t *root,
                                    pool));
     }
 
-  cb_baton.copies = apr_array_make(pool, 4, sizeof(struct copy_info));
+  cb_baton.copies = apr_array_make(pool, 4, sizeof(struct copy_info *));
   cb_baton.pool = pool;
 
   /* Determine the revision to use throughout the edit, and call

Modified: subversion/branches/revprop-packing/subversion/libsvn_repos/reporter.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_repos/reporter.c?rev=1296975&r1=1296974&r2=1296975&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_repos/reporter.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_repos/reporter.c Mon Mar  5 09:25:25 2012
@@ -898,6 +898,21 @@ update_entry(report_baton_t *b, svn_revn
       SVN_ERR(svn_repos_deleted_rev(svn_fs_root_fs(b->t_root), t_path,
                                     s_rev, b->t_rev, &deleted_rev,
                                     pool));
+
+      if (!SVN_IS_VALID_REVNUM(deleted_rev))
+        {
+          /* Two possibilities: either the thing doesn't exist in S_REV; or
+             it wasn't deleted between S_REV and B->T_REV.  In the first case,
+             I think we should leave DELETED_REV as SVN_INVALID_REVNUM, but
+             in the second, it should be set to B->T_REV-1 for the call to
+             delete_entry() below. */
+          svn_node_kind_t kind;
+
+          SVN_ERR(svn_fs_check_path(&kind, b->t_root, t_path, pool));
+          if (kind != svn_node_none)
+            deleted_rev = b->t_rev - 1;
+        }
+
       SVN_ERR(b->editor->delete_entry(e_path, deleted_rev, dir_baton,
                                       pool));
       s_path = NULL;

Modified: subversion/branches/revprop-packing/subversion/libsvn_repos/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_repos/repos.c?rev=1296975&r1=1296974&r2=1296975&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_repos/repos.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_repos/repos.c Mon Mar  5 09:25:25 2012
@@ -165,6 +165,12 @@ svn_repos_post_revprop_change_hook(svn_r
                        pool);
 }
 
+void
+svn_repos_hooks_setenv(svn_repos_t *repos,
+                       apr_hash_t *hooks_env)
+{
+  repos->hooks_env = hooks_env;
+}
 
 static svn_error_t *
 create_repos_dir(const char *path, apr_pool_t *pool)
@@ -736,6 +742,7 @@ PREWRITTEN_HOOKS_TEXT
 "#"                                                                          NL
 "#   [1] REPOS-PATH   (the path to this repository)"                         NL
 "#   [2] REV          (the number of the revision just committed)"           NL
+"#   [3] TXN-NAME     (the name of the transaction that has become REV)"     NL
 "#"                                                                          NL
 "# The default working directory for the invocation is undefined, so"        NL
 "# the program should set one explicitly if it cares."                       NL
@@ -765,6 +772,7 @@ PREWRITTEN_HOOKS_TEXT
 ""                                                                           NL
 "REPOS=\"$1\""                                                               NL
 "REV=\"$2\""                                                                 NL
+"TXN_NAME=\"$3\""                                                            NL
                                                                              NL
 "mailer.py commit \"$REPOS\" \"$REV\" /path/to/mailer.conf"                  NL;
 
@@ -1040,7 +1048,17 @@ create_conf(svn_repos_t *repos, apr_pool
 "### to the effective key length for encryption (e.g. 128 means 128-bit"     NL
 "### encryption). The values below are the defaults."                        NL
 "# min-encryption = 0"                                                       NL
-"# max-encryption = 256"                                                     NL;
+"# max-encryption = 256"                                                     NL
+""                                                                           NL
+"[hooks-env]"                                                                NL
+"### Options in this section define environment variables for use by"        NL
+"### hook scripts run by svnserve."                                          NL
+#ifdef WIN32
+"# PATH = C:\\Program Files\\Subversion\\bin"                                NL
+#else
+"# PATH = /bin:/sbin:/usr/bin:/usr/sbin"                                     NL
+#endif
+"# LC_CTYPE = en_US.UTF-8"                                                   NL;
 
     SVN_ERR_W(svn_io_file_create(svn_repos_svnserve_conf(repos, pool),
                                  svnserve_conf_contents, pool),

Modified: subversion/branches/revprop-packing/subversion/libsvn_repos/repos.h
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_repos/repos.h?rev=1296975&r1=1296974&r2=1296975&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_repos/repos.h (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_repos/repos.h Mon Mar  5 09:25:25 2012
@@ -140,6 +140,10 @@ struct svn_repos_t
      sufficiently well-informed internal code may just compare against
      those constants' addresses, therefore). */
   apr_hash_t *repository_capabilities;
+
+  /* The environment inherited to hook scripts. If NULL, hooks run
+   * in an empty environment. */
+  apr_hash_t *hooks_env;
 };
 
 
@@ -175,6 +179,7 @@ svn_repos__hooks_pre_commit(svn_repos_t 
 svn_error_t *
 svn_repos__hooks_post_commit(svn_repos_t *repos,
                              svn_revnum_t rev,
+                             const char *txn_name,
                              apr_pool_t *pool);
 
 /* Run the pre-revprop-change hook for REPOS.  Use POOL for any

Modified: subversion/branches/revprop-packing/subversion/libsvn_subr/auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_subr/auth.c?rev=1296975&r1=1296974&r2=1296975&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_subr/auth.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_subr/auth.c Mon Mar  5 09:25:25 2012
@@ -35,13 +35,20 @@
 #include "svn_dso.h"
 #include "svn_version.h"
 
-/* The good way to think of this machinery is as a set of tables.
+/* AN OVERVIEW
+   ===========
 
-   - Each type of credentials selects a single table.
+   A good way to think of this machinery is as a set of tables.
 
-   - In a given table, each row is a 'provider' capable of returning
-     the same type of credentials.  Each column represents a
-     provider's repeated attempts to provide credentials.
+     - Each type of credentials selects a single table.
+
+     - In a given table, each row is a 'provider' capable of returning
+       the same type of credentials.  Each column represents a
+       provider's repeated attempts to provide credentials.
+
+
+   Fetching Credentials from Providers
+   -----------------------------------
 
    When the caller asks for a particular type of credentials, the
    machinery in this file walks over the appropriate table.  It starts
@@ -55,6 +62,23 @@
 
    Note that the caller cannot see the table traversal, and thus has
    no idea when we switch providers.
+
+
+   Storing Credentials with Providers
+   ----------------------------------
+
+   When the server has validated a set of credentials, and when
+   credential caching is enabled, we have the chance to store those
+   credentials for later use.  The provider which provided the working
+   credentials is the first one given the opportunity to (re)cache
+   those credentials.  Its save_credentials() function is invoked with
+   the working credentials.  If that provider reports that it
+   successfully stored the credentials, we're done.  Otherwise, we
+   walk the providers (rows) for that type of credentials in order
+   from the top of the table, allowing each in turn the opportunity to
+   store the credentials.  When one reports that it has done so
+   successfully -- or when we run out of providers (rows) to try --
+   the table walk ends.
 */
 
 

Modified: subversion/branches/revprop-packing/subversion/libsvn_subr/cache-inprocess.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_subr/cache-inprocess.c?rev=1296975&r1=1296974&r2=1296975&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_subr/cache-inprocess.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_subr/cache-inprocess.c Mon Mar  5 09:25:25 2012
@@ -201,7 +201,7 @@ inprocess_cache_get_internal(char **buff
 
       *size = entry->size;
     }
-    
+
   return SVN_NO_ERROR;
 }
 
@@ -213,16 +213,17 @@ inprocess_cache_get(void **value_p,
                     apr_pool_t *result_pool)
 {
   inprocess_cache_t *cache = cache_void;
-  char* buffer;
+  char* buffer = NULL;
   apr_size_t size;
 
-  SVN_MUTEX__WITH_LOCK(cache->mutex,
-                       inprocess_cache_get_internal(&buffer,
-                                                    &size,
-                                                    cache,
-                                                    key,
-                                                    result_pool));
-    
+  if (key)
+    SVN_MUTEX__WITH_LOCK(cache->mutex,
+                         inprocess_cache_get_internal(&buffer,
+                                                      &size,
+                                                      cache,
+                                                      key,
+                                                      result_pool));
+
   /* deserialize the buffer content. Usually, this will directly
      modify the buffer content directly.
    */
@@ -400,11 +401,12 @@ inprocess_cache_set(void *cache_void,
 {
   inprocess_cache_t *cache = cache_void;
 
-  SVN_MUTEX__WITH_LOCK(cache->mutex,
-                       inprocess_cache_set_internal(cache,
-                                                    key,
-                                                    value,
-                                                    scratch_pool));
+  if (key)
+    SVN_MUTEX__WITH_LOCK(cache->mutex,
+                         inprocess_cache_set_internal(cache,
+                                                      key,
+                                                      value,
+                                                      scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -443,7 +445,7 @@ inprocess_cache_iter(svn_boolean_t *comp
   b.user_baton = user_baton;
 
   SVN_MUTEX__WITH_LOCK(cache->mutex,
-                       svn_iter_apr_hash(completed, cache->hash, 
+                       svn_iter_apr_hash(completed, cache->hash,
                                          iter_cb, &b, scratch_pool));
 
   return SVN_NO_ERROR;
@@ -482,14 +484,17 @@ inprocess_cache_get_partial(void **value
 {
   inprocess_cache_t *cache = cache_void;
 
-  SVN_MUTEX__WITH_LOCK(cache->mutex,
-                       inprocess_cache_get_partial_internal(value_p,
-                                                            found,
-                                                            cache,
-                                                            key,
-                                                            func,
-                                                            baton,
-                                                            result_pool));
+  if (key)
+    SVN_MUTEX__WITH_LOCK(cache->mutex,
+                         inprocess_cache_get_partial_internal(value_p,
+                                                              found,
+                                                              cache,
+                                                              key,
+                                                              func,
+                                                              baton,
+                                                              result_pool));
+  else
+    *found = FALSE;
 
   return SVN_NO_ERROR;
 }
@@ -526,12 +531,13 @@ inprocess_cache_set_partial(void *cache_
 {
   inprocess_cache_t *cache = cache_void;
 
-  SVN_MUTEX__WITH_LOCK(cache->mutex,
-                       inprocess_cache_set_partial_internal(cache,
-                                                            key,
-                                                            func,
-                                                            baton,
-                                                            scratch_pool));
+  if (key)
+    SVN_MUTEX__WITH_LOCK(cache->mutex,
+                         inprocess_cache_set_partial_internal(cache,
+                                                              key,
+                                                              func,
+                                                              baton,
+                                                              scratch_pool));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/revprop-packing/subversion/libsvn_subr/cache-membuffer.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_subr/cache-membuffer.c?rev=1296975&r1=1296974&r2=1296975&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_subr/cache-membuffer.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_subr/cache-membuffer.c Mon Mar  5 09:25:25 2012
@@ -136,6 +136,13 @@
  */
 #define NO_OFFSET APR_UINT64_MAX
 
+/* To save space in our group structure, we only use 32 bit size values
+ * and, therefore, limit the size of each entry to just below 4GB.
+ * Supporting larger items is not a good idea as the data transfer
+ * to and from the cache would block other threads for a very long time.
+ */
+#define MAX_ITEM_SIZE ((apr_uint32_t)(0 - ITEM_ALIGNMENT))
+
 /* Debugging / corruption detection support.
  * If you define this macro, the getter functions will performed expensive
  * checks on the item data, requested keys and entry types. If there is
@@ -395,6 +402,11 @@ struct svn_membuffer_t
    */
   apr_uint64_t data_used;
 
+  /* Largest entry size that we would accept.  For total cache sizes
+   * less than 4TB (sic!), this is determined by the total cache size.
+   */
+  apr_uint64_t max_entry_size;
+
 
   /* Number of used dictionary entries, i.e. number of cached items.
    * In conjunction with hit_count, this is used calculate the average
@@ -589,6 +601,9 @@ get_group_index(svn_membuffer_t **cache,
   svn_checksum_t *checksum;
   svn_error_t *err;
 
+  if (key == NULL)
+    return NO_INDEX;
+
   err = svn_checksum(&checksum, svn_checksum_md5, key, len, pool);
   if (err != NULL)
   {
@@ -946,6 +961,7 @@ svn_cache__membuffer_cache_create(svn_me
   apr_uint32_t group_count;
   apr_uint32_t group_init_size;
   apr_uint64_t data_size;
+  apr_uint64_t max_entry_size;
 
   /* Determine a reasonable number of cache segments. Segmentation is
    * only useful for multi-threaded / multi-core servers as it reduces
@@ -989,8 +1005,19 @@ svn_cache__membuffer_cache_create(svn_me
    */
   data_size = total_size - directory_size;
 
+  /* For cache sizes > 4TB, individual cache segments will be larger
+   * than 16GB allowing for >4GB entries.  But caching chunks larger
+   * than 4GB is simply not supported.
+   */
+  max_entry_size = data_size / 4 > MAX_ITEM_SIZE
+                 ? MAX_ITEM_SIZE
+                 : data_size / 4;
+  
   /* to keep the entries small, we use 32 bit indices only
-   * -> we need to ensure that no more then 4G entries exist
+   * -> we need to ensure that no more then 4G entries exist.
+   * 
+   * Note, that this limit could only be exceeded in a very
+   * theoretical setup with about 1EB of cache.
    */
   group_count = directory_size / sizeof(entry_group_t);
   if (group_count >= (APR_UINT32_MAX / GROUP_SIZE))
@@ -1021,6 +1048,7 @@ svn_cache__membuffer_cache_create(svn_me
       c[seg].data = secure_aligned_alloc(pool, (apr_size_t)data_size, FALSE);
       c[seg].current_data = 0;
       c[seg].data_used = 0;
+      c[seg].max_entry_size = max_entry_size;
 
       c[seg].used_entries = 0;
       c[seg].hit_count = 0;
@@ -1052,14 +1080,14 @@ svn_cache__membuffer_cache_create(svn_me
 
 
 /* Try to insert the serialized item given in BUFFER with SIZE into
- * the group GROUP_INDEX of CACHE and uniquely identify it by hash 
- * value TO_FIND. 
- * 
+ * the group GROUP_INDEX of CACHE and uniquely identify it by hash
+ * value TO_FIND.
+ *
  * However, there is no guarantee that it will actually be put into
  * the cache. If there is already some data associated with TO_FIND,
  * it will be removed from the cache even if the new data cannot
  * be inserted.
- * 
+ *
  * Note: This function requires the caller to serialization access.
  * Don't call it directly, call membuffer_cache_get_partial instead.
  */
@@ -1075,7 +1103,7 @@ membuffer_cache_set_internal(svn_membuff
   /* if necessary, enlarge the insertion window.
    */
   if (   buffer != NULL
-      && cache->data_size / 4 > size
+      && cache->max_entry_size >= size
       && ensure_data_insertable(cache, size))
     {
       /* Remove old data for this key, if that exists.
@@ -1162,11 +1190,11 @@ membuffer_cache_set(svn_membuffer_t *cac
 }
 
 /* Look for the cache entry in group GROUP_INDEX of CACHE, identified
- * by the hash value TO_FIND. If no item has been stored for KEY, 
+ * by the hash value TO_FIND. If no item has been stored for KEY,
  * *BUFFER will be NULL. Otherwise, return a copy of the serialized
- * data in *BUFFER and return its size in *ITEM_SIZE. Allocations will 
+ * data in *BUFFER and return its size in *ITEM_SIZE. Allocations will
  * be done in POOL.
- * 
+ *
  * Note: This function requires the caller to serialization access.
  * Don't call it directly, call membuffer_cache_get_partial instead.
  */
@@ -1192,10 +1220,10 @@ membuffer_cache_get_internal(svn_membuff
        */
       *buffer = NULL;
       *item_size = 0;
-  
+
       return SVN_NO_ERROR;
     }
-    
+
   size = ALIGN_VALUE(entry->size);
   *buffer = ALIGN_POINTER(apr_palloc(result_pool, size + ITEM_ALIGNMENT-1));
   memcpy(*buffer, (const char*)cache->data + entry->offset, size);
@@ -1222,7 +1250,7 @@ membuffer_cache_get_internal(svn_membuff
   cache->total_hits++;
 
   *item_size = entry->size;
-  
+
   return SVN_NO_ERROR;
 }
 
@@ -1272,18 +1300,18 @@ membuffer_cache_get(svn_membuffer_t *cac
       *item = NULL;
       return SVN_NO_ERROR;
     }
-    
+
   return deserializer(item, buffer, size, result_pool);
 }
 
 /* Look for the cache entry in group GROUP_INDEX of CACHE, identified
  * by the hash value TO_FIND. FOUND indicates whether that entry exists.
  * If not found, *ITEM will be NULL.
- * 
- * Otherwise, the DESERIALIZER is called with that entry and the BATON 
+ *
+ * Otherwise, the DESERIALIZER is called with that entry and the BATON
  * provided and will extract the desired information. The result is set
  * in *ITEM. Allocations will be done in POOL.
- * 
+ *
  * Note: This function requires the caller to serialization access.
  * Don't call it directly, call membuffer_cache_get_partial instead.
  */
@@ -1304,7 +1332,7 @@ membuffer_cache_get_partial_internal(svn
     {
       *item = NULL;
       *found = FALSE;
-      
+
       return SVN_NO_ERROR;
     }
   else
@@ -1363,11 +1391,12 @@ membuffer_cache_get_partial(svn_membuffe
 
   group_index = get_group_index(&cache, key, key_len, to_find, result_pool);
 
-  SVN_MUTEX__WITH_LOCK(cache->mutex,
-                       membuffer_cache_get_partial_internal
-                           (cache, group_index, to_find, item, found,
-                            deserializer, baton, DEBUG_CACHE_MEMBUFFER_TAG
-                            result_pool));
+  if (group_index != NO_INDEX)
+    SVN_MUTEX__WITH_LOCK(cache->mutex,
+                         membuffer_cache_get_partial_internal
+                             (cache, group_index, to_find, item, found,
+                              deserializer, baton, DEBUG_CACHE_MEMBUFFER_TAG
+                              result_pool));
 
   return SVN_NO_ERROR;
 }
@@ -1375,10 +1404,10 @@ membuffer_cache_get_partial(svn_membuffe
 /* Look for the cache entry in group GROUP_INDEX of CACHE, identified
  * by the hash value TO_FIND. If no entry has been found, the function
  * returns without modifying the cache.
- * 
+ *
  * Otherwise, FUNC is called with that entry and the BATON provided
  * and may modify the cache entry. Allocations will be done in POOL.
- * 
+ *
  * Note: This function requires the caller to serialization access.
  * Don't call it directly, call membuffer_cache_set_partial instead.
  */
@@ -1448,7 +1477,7 @@ membuffer_cache_set_partial_internal(svn
               /* Remove the old entry and try to make space for the new one.
                */
               drop_entry(cache, entry);
-              if (   (cache->data_size / 4 > size)
+              if (   (cache->max_entry_size >= size)
                   && ensure_data_insertable(cache, size))
                 {
                   /* Write the new entry.
@@ -1499,11 +1528,12 @@ membuffer_cache_set_partial(svn_membuffe
    */
   group_index = get_group_index(&cache, key, key_len, to_find, scratch_pool);
 
-  SVN_MUTEX__WITH_LOCK(cache->mutex,
-                       membuffer_cache_set_partial_internal
-                           (cache, group_index, to_find, func, baton,
-                            DEBUG_CACHE_MEMBUFFER_TAG_ARG
-                            scratch_pool));
+  if (group_index != NO_INDEX)
+    SVN_MUTEX__WITH_LOCK(cache->mutex,
+                         membuffer_cache_set_partial_internal
+                             (cache, group_index, to_find, func, baton,
+                              DEBUG_CACHE_MEMBUFFER_TAG_ARG
+                              scratch_pool));
 
   /* done here -> unlock the cache
    */
@@ -1597,14 +1627,22 @@ combine_key(const void *prefix,
             apr_size_t *full_key_len,
             apr_pool_t *pool)
 {
-  if (key_len == APR_HASH_KEY_STRING)
-    key_len = strlen((const char *) key);
+  if (key == NULL)
+    {
+      *full_key = NULL;
+      *full_key_len = 0;
+    }
+  else
+    {
+      if (key_len == APR_HASH_KEY_STRING)
+        key_len = strlen((const char *) key);
 
-  *full_key_len = prefix_len + key_len;
-  *full_key = apr_palloc(pool, *full_key_len);
+      *full_key_len = prefix_len + key_len;
+      *full_key = apr_palloc(pool, *full_key_len);
 
-  memcpy(*full_key, prefix, prefix_len);
-  memcpy((char *)*full_key + prefix_len, key, key_len);
+      memcpy(*full_key, prefix, prefix_len);
+      memcpy((char *)*full_key + prefix_len, key, key_len);
+    }
 }
 
 /* Implement svn_cache__vtable_t.get (not thread-safe)
@@ -1810,8 +1848,7 @@ svn_membuffer_cache_is_cachable(void *ca
    * must be small enough to be stored in a 32 bit value.
    */
   svn_membuffer_cache_t *cache = cache_void;
-  return (size < cache->membuffer->data_size / 4)
-      && (size < APR_UINT32_MAX - ITEM_ALIGNMENT);
+  return size <= cache->membuffer->max_entry_size;
 }
 
 /* Add statistics of SEGMENT to INFO.
@@ -1859,7 +1896,7 @@ svn_membuffer_cache_get_info(void *cache
   for (i = 0; i < cache->membuffer->segment_count; ++i)
     {
       svn_membuffer_t *segment = cache->membuffer + i;
-      SVN_MUTEX__WITH_LOCK(segment->mutex, 
+      SVN_MUTEX__WITH_LOCK(segment->mutex,
                            svn_membuffer_get_segment_info(segment, info));
     }
 
@@ -1889,13 +1926,13 @@ svn_membuffer_cache_get_synced(void **va
                                apr_pool_t *result_pool)
 {
   svn_membuffer_cache_t *cache = cache_void;
-  SVN_MUTEX__WITH_LOCK(cache->mutex, 
+  SVN_MUTEX__WITH_LOCK(cache->mutex,
                        svn_membuffer_cache_get(value_p,
                                                found,
                                                cache_void,
                                                key,
                                                result_pool));
-  
+
   return SVN_NO_ERROR;
 }
 
@@ -1908,12 +1945,12 @@ svn_membuffer_cache_set_synced(void *cac
                                apr_pool_t *scratch_pool)
 {
   svn_membuffer_cache_t *cache = cache_void;
-  SVN_MUTEX__WITH_LOCK(cache->mutex, 
+  SVN_MUTEX__WITH_LOCK(cache->mutex,
                        svn_membuffer_cache_set(cache_void,
                                                key,
                                                value,
                                                scratch_pool));
-  
+
   return SVN_NO_ERROR;
 }
 
@@ -1929,7 +1966,7 @@ svn_membuffer_cache_get_partial_synced(v
                                        apr_pool_t *result_pool)
 {
   svn_membuffer_cache_t *cache = cache_void;
-  SVN_MUTEX__WITH_LOCK(cache->mutex, 
+  SVN_MUTEX__WITH_LOCK(cache->mutex,
                        svn_membuffer_cache_get_partial(value_p,
                                                        found,
                                                        cache_void,
@@ -1937,7 +1974,7 @@ svn_membuffer_cache_get_partial_synced(v
                                                        func,
                                                        baton,
                                                        result_pool));
-  
+
   return SVN_NO_ERROR;
 }
 
@@ -1951,13 +1988,13 @@ svn_membuffer_cache_set_partial_synced(v
                                        apr_pool_t *scratch_pool)
 {
   svn_membuffer_cache_t *cache = cache_void;
-  SVN_MUTEX__WITH_LOCK(cache->mutex, 
+  SVN_MUTEX__WITH_LOCK(cache->mutex,
                        svn_membuffer_cache_set_partial(cache_void,
                                                        key,
                                                        func,
                                                        baton,
                                                        scratch_pool));
-  
+
   return SVN_NO_ERROR;
 }
 
@@ -1999,8 +2036,10 @@ deserialize_svn_stringbuf(void **item,
                           apr_size_t buffer_size,
                           apr_pool_t *result_pool)
 {
-  svn_string_t *value_str = apr_palloc(result_pool, sizeof(svn_string_t));
+  svn_stringbuf_t *value_str = apr_palloc(result_pool, sizeof(svn_stringbuf_t));
 
+  value_str->pool = result_pool;
+  value_str->blocksize = buffer_size;
   value_str->data = buffer;
   value_str->len = buffer_size-1;
   *item = value_str;
@@ -2042,7 +2081,7 @@ svn_cache__create_membuffer_cache(svn_ca
   cache->alloc_counter = 0;
 
   SVN_ERR(svn_mutex__init(&cache->mutex, thread_safe, pool));
-  
+
   /* for performance reasons, we don't actually store the full prefix but a
    * hash value of it
    */
@@ -2063,7 +2102,7 @@ svn_cache__create_membuffer_cache(svn_ca
 
   /* initialize the generic cache wrapper
    */
-  wrapper->vtable = thread_safe ? &membuffer_cache_synced_vtable 
+  wrapper->vtable = thread_safe ? &membuffer_cache_synced_vtable
                                 : &membuffer_cache_vtable;
   wrapper->cache_internal = cache;
   wrapper->error_handler = 0;

Modified: subversion/branches/revprop-packing/subversion/libsvn_subr/cache-memcache.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_subr/cache-memcache.c?rev=1296975&r1=1296974&r2=1296975&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_subr/cache-memcache.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_subr/cache-memcache.c Mon Mar  5 09:25:25 2012
@@ -141,8 +141,15 @@ memcache_internal_get(char **data,
   memcache_t *cache = cache_void;
   apr_status_t apr_err;
   const char *mc_key;
-  apr_pool_t *subpool = svn_pool_create(pool);
+  apr_pool_t *subpool;
+
+  if (key == NULL)
+    {
+      *found = FALSE;
+      return SVN_NO_ERROR;
+    }
 
+  subpool = svn_pool_create(pool);
   SVN_ERR(build_key(&mc_key, cache, key, subpool));
 
   apr_err = apr_memcache_getp(cache->memcache,
@@ -244,6 +251,9 @@ memcache_set(void *cache_void,
   apr_size_t data_len;
   svn_error_t *err;
 
+  if (key == NULL)
+    return SVN_NO_ERROR;
+
   if (cache->serialize_func)
     {
       SVN_ERR((cache->serialize_func)(&data, &data_len, value, subpool));

Modified: subversion/branches/revprop-packing/subversion/libsvn_subr/checksum.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_subr/checksum.c?rev=1296975&r1=1296974&r2=1296975&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_subr/checksum.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_subr/checksum.c Mon Mar  5 09:25:25 2012
@@ -423,3 +423,27 @@ svn_checksum_mismatch_err(const svn_chec
                 svn_checksum_to_cstring_display(expected, scratch_pool),
                 svn_checksum_to_cstring_display(actual, scratch_pool));
 }
+
+svn_boolean_t
+svn_checksum_is_empty_checksum(svn_checksum_t *checksum)
+{
+  /* By definition, the NULL checksum matches all others, including the
+     empty one. */
+  if (!checksum)
+    return TRUE;
+
+  switch (checksum->kind)
+    {
+      case svn_checksum_md5:
+        return svn_md5__digests_match(checksum->digest,
+                                      svn_md5__empty_string_digest());
+
+      case svn_checksum_sha1:
+        return svn_sha1__digests_match(checksum->digest,
+                                       svn_sha1__empty_string_digest());
+
+      default:
+        /* We really shouldn't get here, but if we do... */
+        return FALSE;
+    }
+}

Modified: subversion/branches/revprop-packing/subversion/libsvn_subr/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_subr/deprecated.c?rev=1296975&r1=1296974&r2=1296975&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_subr/deprecated.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_subr/deprecated.c Mon Mar  5 09:25:25 2012
@@ -780,8 +780,9 @@ svn_io_start_cmd2(apr_proc_t *cmd_proc,
                   apr_file_t *errfile,
                   apr_pool_t *pool)
 {
-  return svn_io_start_cmd3(cmd_proc, path, cmd, args, NULL, inherit, FALSE,
-                           infile, FALSE, outfile, FALSE, errfile, pool);
+  return svn_io_start_cmd3(cmd_proc, path, cmd, args, NULL, inherit,
+                           infile_pipe, infile, outfile_pipe, outfile,
+                           errfile_pipe, errfile, pool);
 }
 
 svn_error_t *

Modified: subversion/branches/revprop-packing/subversion/libsvn_subr/gpg_agent.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_subr/gpg_agent.c?rev=1296975&r1=1296974&r2=1296975&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_subr/gpg_agent.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_subr/gpg_agent.c Mon Mar  5 09:25:25 2012
@@ -154,8 +154,9 @@ send_option(int sd, char *buf, size_t n,
 
 /* Implementation of svn_auth__password_get_t that retrieves the password
    from gpg-agent */
-static svn_boolean_t
-password_get_gpg_agent(const char **password,
+static svn_error_t *
+password_get_gpg_agent(svn_boolean_t *done,
+                       const char **password,
                        apr_hash_t *creds,
                        const char *realmstring,
                        const char *username,
@@ -168,7 +169,7 @@ password_get_gpg_agent(const char **pass
   const char *p = NULL;
   char *ep = NULL;
   char *buffer;
-  
+
   apr_array_header_t *socket_details;
   const char *request = NULL;
   const char *cache_id = NULL;
@@ -182,6 +183,8 @@ password_get_gpg_agent(const char **pass
   char *password_prompt;
   char *realm_prompt;
 
+  *done = FALSE;
+
   gpg_agent_info = getenv("GPG_AGENT_INFO");
   if (gpg_agent_info != NULL)
     {
@@ -190,7 +193,7 @@ password_get_gpg_agent(const char **pass
       socket_name = APR_ARRAY_IDX(socket_details, 0, const char *);
     }
   else
-    return FALSE;
+    return SVN_NO_ERROR;
 
   if (socket_name != NULL)
     {
@@ -200,29 +203,29 @@ password_get_gpg_agent(const char **pass
 
       sd = socket(AF_UNIX, SOCK_STREAM, 0);
       if (sd == -1)
-        return FALSE;
-    
+        return SVN_NO_ERROR;
+
       if (connect(sd, (struct sockaddr *)&addr, sizeof(addr)) == -1)
         {
           close(sd);
-          return FALSE;
+          return SVN_NO_ERROR;
         }
     }
   else
-    return FALSE;
+    return SVN_NO_ERROR;
 
   /* Receive the connection status from the gpg-agent daemon. */
   buffer = apr_palloc(pool, BUFFER_SIZE);
   if (!receive_from_gpg_agent(sd, buffer, BUFFER_SIZE))
     {
       close(sd);
-      return FALSE;
+      return SVN_NO_ERROR;
     }
 
   if (strncmp(buffer, "OK", 2) != 0)
     {
       close(sd);
-      return FALSE;
+      return SVN_NO_ERROR;
     }
 
   /* The GPG-Agent documentation says:
@@ -232,19 +235,19 @@ password_get_gpg_agent(const char **pass
   if (write(sd, request, strlen(request)) == -1)
     {
       close(sd);
-      return FALSE;
+      return SVN_NO_ERROR;
     }
   if (!receive_from_gpg_agent(sd, buffer, BUFFER_SIZE))
     {
       close(sd);
-      return FALSE;
+      return SVN_NO_ERROR;
     }
   if (strncmp(buffer, "D", 1) == 0)
     p = &buffer[2];
   if (!p)
     {
       close(sd);
-      return FALSE;
+      return SVN_NO_ERROR;
     }
   ep = strchr(p, '\n');
   if (ep != NULL)
@@ -252,18 +255,18 @@ password_get_gpg_agent(const char **pass
   if (strcmp(socket_name, p) != 0)
     {
       close(sd);
-      return FALSE;
+      return SVN_NO_ERROR;
     }
   /* The agent will terminate its response with "OK". */
   if (!receive_from_gpg_agent(sd, buffer, BUFFER_SIZE))
     {
       close(sd);
-      return FALSE;
+      return SVN_NO_ERROR;
     }
   if (strncmp(buffer, "OK", 2) != 0)
     {
       close(sd);
-      return FALSE;
+      return SVN_NO_ERROR;
     }
 
   /* Send TTY_NAME to the gpg-agent daemon. */
@@ -273,13 +276,13 @@ password_get_gpg_agent(const char **pass
       if (!send_option(sd, buffer, BUFFER_SIZE, "ttyname", tty_name, pool))
         {
           close(sd);
-          return FALSE;
+          return SVN_NO_ERROR;
         }
     }
   else
     {
       close(sd);
-      return FALSE;
+      return SVN_NO_ERROR;
     }
 
   /* Send TTY_TYPE to the gpg-agent daemon. */
@@ -289,13 +292,13 @@ password_get_gpg_agent(const char **pass
       if (!send_option(sd, buffer, BUFFER_SIZE, "ttytype", tty_type, pool))
         {
           close(sd);
-          return FALSE;
+          return SVN_NO_ERROR;
         }
     }
   else
     {
       close(sd);
-      return FALSE;
+      return SVN_NO_ERROR;
     }
 
   /* Compute LC_CTYPE. */
@@ -311,7 +314,7 @@ password_get_gpg_agent(const char **pass
       if (!send_option(sd, buffer, BUFFER_SIZE, "lc-ctype", lc_ctype, pool))
         {
           close(sd);
-          return FALSE;
+          return SVN_NO_ERROR;
         }
     }
 
@@ -323,7 +326,7 @@ password_get_gpg_agent(const char **pass
       if (!send_option(sd, buffer, BUFFER_SIZE, "display", display, pool))
         {
           close(sd);
-          return FALSE;
+          return SVN_NO_ERROR;
         }
     }
 
@@ -348,25 +351,25 @@ password_get_gpg_agent(const char **pass
   if (write(sd, request, strlen(request)) == -1)
     {
       close(sd);
-      return FALSE;
+      return SVN_NO_ERROR;
     }
   if (!receive_from_gpg_agent(sd, buffer, BUFFER_SIZE))
     {
       close(sd);
-      return FALSE;
+      return SVN_NO_ERROR;
     }
 
   close(sd);
 
   if (strncmp(buffer, "ERR", 3) == 0)
-    return FALSE;
-  
+    return SVN_NO_ERROR;
+
   p = NULL;
   if (strncmp(buffer, "D", 1) == 0)
     p = &buffer[2];
 
   if (!p)
-    return FALSE;
+    return SVN_NO_ERROR;
 
   ep = strchr(p, '\n');
   if (ep != NULL)
@@ -374,7 +377,8 @@ password_get_gpg_agent(const char **pass
 
   *password = p;
 
-  return TRUE;
+  *done = TRUE;
+  return SVN_NO_ERROR;
 }
 
 
@@ -384,8 +388,9 @@ password_get_gpg_agent(const char **pass
    the user via the pinentry program immediately upon its provision
    (and regardless of its accuracy as passwords go), so there's
    nothing really to do here.  */
-static svn_boolean_t
-password_set_gpg_agent(apr_hash_t *creds,
+static svn_error_t *
+password_set_gpg_agent(svn_boolean_t *done,
+                       apr_hash_t *creds,
                        const char *realmstring,
                        const char *username,
                        const char *password,
@@ -393,7 +398,9 @@ password_set_gpg_agent(apr_hash_t *creds
                        svn_boolean_t non_interactive,
                        apr_pool_t *pool)
 {
-  return TRUE;
+  *done = TRUE;
+
+  return SVN_NO_ERROR;
 }
 
 

Modified: subversion/branches/revprop-packing/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_subr/io.c?rev=1296975&r1=1296974&r2=1296975&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_subr/io.c Mon Mar  5 09:25:25 2012
@@ -3280,6 +3280,15 @@ svn_io_write_unique(const char **tmp_pat
 svn_error_t *
 svn_io_file_trunc(apr_file_t *file, apr_off_t offset, apr_pool_t *pool)
 {
+  /* This is a work-around. APR would flush the write buffer
+     _after_ truncating the file causing now invalid buffered
+     data to be written behind OFFSET. */
+  SVN_ERR(do_io_file_wrapper_cleanup
+    (file, apr_file_flush(file),
+     N_("Can't flush file '%s'"),
+     N_("Can't flush stream"),
+     pool));
+
   return do_io_file_wrapper_cleanup
     (file, apr_file_trunc(file, offset),
      N_("Can't truncate file '%s'"),

Modified: subversion/branches/revprop-packing/subversion/libsvn_subr/macos_keychain.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_subr/macos_keychain.c?rev=1296975&r1=1296974&r2=1296975&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_subr/macos_keychain.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_subr/macos_keychain.c Mon Mar  5 09:25:25 2012
@@ -65,8 +65,9 @@
 
 /* Implementation of svn_auth__password_set_t that stores
    the password in the OS X KeyChain. */
-static svn_boolean_t
-keychain_password_set(apr_hash_t *creds,
+static svn_error_t *
+keychain_password_set(svn_boolean_t *done,
+                      apr_hash_t *creds,
                       const char *realmstring,
                       const char *username,
                       const char *password,
@@ -106,13 +107,16 @@ keychain_password_set(apr_hash_t *creds,
   if (non_interactive)
     SecKeychainSetUserInteractionAllowed(TRUE);
 
-  return status == 0;
+  *done = (status == 0);
+
+  return SVN_NO_ERROR;
 }
 
 /* Implementation of svn_auth__password_get_t that retrieves
    the password from the OS X KeyChain. */
-static svn_boolean_t
-keychain_password_get(const char **password,
+static svn_error_t *
+keychain_password_get(svn_boolean_t *done,
+                      const char **password,
                       apr_hash_t *creds,
                       const char *realmstring,
                       const char *username,
@@ -124,6 +128,8 @@ keychain_password_get(const char **passw
   UInt32 length;
   void *data;
 
+  *done = FALSE;
+
   if (non_interactive)
     SecKeychainSetUserInteractionAllowed(FALSE);
 
@@ -137,11 +143,12 @@ keychain_password_get(const char **passw
     SecKeychainSetUserInteractionAllowed(TRUE);
 
   if (status != 0)
-    return FALSE;
+    return SVN_NO_ERROR;
 
   *password = apr_pstrmemdup(pool, data, length);
   SecKeychainItemFreeContent(NULL, data);
-  return TRUE;
+  *done = TRUE;
+  return SVN_NO_ERROR;
 }
 
 /* Get cached encrypted credentials from the simple provider's cache. */

Modified: subversion/branches/revprop-packing/subversion/libsvn_subr/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_subr/mergeinfo.c?rev=1296975&r1=1296974&r2=1296975&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_subr/mergeinfo.c (original)
+++ subversion/branches/revprop-packing/subversion/libsvn_subr/mergeinfo.c Mon Mar  5 09:25:25 2012
@@ -1112,12 +1112,12 @@ svn_rangelist_merge2(apr_array_header_t 
                           j++;
                         }
                     }
-                  else 
+                  else
                     {
                       /* CHANGE and RANGE share the same start rev, but
                          CHANGE is considered older because its end rev
                          is older.
-                         
+
                          Insert the intersection of RANGE and CHANGE into
                          RANGELIST and then set RANGE to the non-intersecting
                          portion of RANGE. */