You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by pb...@apache.org on 2012/08/24 12:38:23 UTC

svn commit: r1376886 - in /subversion/branches/inheritable-props: ./ subversion/include/ subversion/libsvn_fs/ subversion/libsvn_fs_base/ subversion/libsvn_fs_fs/ subversion/libsvn_repos/ subversion/libsvn_subr/ subversion/svnadmin/ subversion/tests/cm...

Author: pburba
Date: Fri Aug 24 10:38:22 2012
New Revision: 1376886

URL: http://svn.apache.org/viewvc?rev=1376886&view=rev
Log:
On the inheritable-props branch: Sync with ^/subversion/trunk through
r1376885.

Modified:
    subversion/branches/inheritable-props/   (props changed)
    subversion/branches/inheritable-props/subversion/include/svn_fs.h
    subversion/branches/inheritable-props/subversion/include/svn_repos.h
    subversion/branches/inheritable-props/subversion/libsvn_fs/fs-loader.c
    subversion/branches/inheritable-props/subversion/libsvn_fs/fs-loader.h
    subversion/branches/inheritable-props/subversion/libsvn_fs_base/fs.c
    subversion/branches/inheritable-props/subversion/libsvn_fs_fs/fs.c
    subversion/branches/inheritable-props/subversion/libsvn_fs_fs/fs_fs.c
    subversion/branches/inheritable-props/subversion/libsvn_fs_fs/rep-cache-db.sql
    subversion/branches/inheritable-props/subversion/libsvn_fs_fs/rep-cache.c
    subversion/branches/inheritable-props/subversion/libsvn_fs_fs/rep-cache.h
    subversion/branches/inheritable-props/subversion/libsvn_fs_fs/tree.c
    subversion/branches/inheritable-props/subversion/libsvn_repos/commit.c
    subversion/branches/inheritable-props/subversion/libsvn_repos/fs-wrap.c
    subversion/branches/inheritable-props/subversion/libsvn_repos/hooks.c
    subversion/branches/inheritable-props/subversion/libsvn_repos/repos.c
    subversion/branches/inheritable-props/subversion/libsvn_repos/repos.h
    subversion/branches/inheritable-props/subversion/libsvn_subr/dirent_uri.c
    subversion/branches/inheritable-props/subversion/svnadmin/main.c
    subversion/branches/inheritable-props/subversion/tests/cmdline/commit_tests.py
    subversion/branches/inheritable-props/subversion/tests/cmdline/svntest/actions.py
    subversion/branches/inheritable-props/subversion/tests/libsvn_subr/dirent_uri-test.c

Propchange: subversion/branches/inheritable-props/
------------------------------------------------------------------------------
  Merged /subversion/trunk:r1376156-1376885

Modified: subversion/branches/inheritable-props/subversion/include/svn_fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/include/svn_fs.h?rev=1376886&r1=1376885&r2=1376886&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/include/svn_fs.h (original)
+++ subversion/branches/inheritable-props/subversion/include/svn_fs.h Fri Aug 24 10:38:22 2012
@@ -402,6 +402,24 @@ svn_fs_recover(const char *path,
                apr_pool_t *pool);
 
 
+/**
+ * Take an exclusive lock on @a fs to prevent commits and then invoke
+ * @a freeze_body passing @a baton.
+ *
+ * @note The BDB backend doesn't implement this feature so most
+ * callers should not call this function directly but should use the
+ * higher level #svn_repos_freeze instead.
+ *
+ * @since New in 1.8.
+ */
+svn_error_t *
+svn_fs_freeze(svn_fs_t *fs,
+              svn_error_t *(*freeze_body)(void *baton, apr_pool_t *pool),
+              void *baton,
+              apr_pool_t *pool);
+              
+
+
 /** Subversion filesystems based on Berkeley DB.
  *
  * The following functions are specific to Berkeley DB filesystems.

Modified: subversion/branches/inheritable-props/subversion/include/svn_repos.h
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/include/svn_repos.h?rev=1376886&r1=1376885&r2=1376886&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/include/svn_repos.h (original)
+++ subversion/branches/inheritable-props/subversion/include/svn_repos.h Fri Aug 24 10:38:22 2012
@@ -653,6 +653,20 @@ svn_error_t *
 svn_repos_recover(const char *path,
                   apr_pool_t *pool);
 
+/**
+ * Take an exclusive lock on @a path to prevent commits and then
+ * invoke @a freeze_body passing @a baton.  The repository may be
+ * readable by Subversion while frozen, or it may be unreadable,
+ * depending on which FS backend the repository uses.
+ *
+ * @since New in 1.8.
+ */
+svn_error_t *
+svn_repos_freeze(const char *path,
+                 svn_error_t *(*freeze_body)(void *baton, apr_pool_t *pool),
+                 void *baton,
+                 apr_pool_t *pool);
+
 /** This function is a wrapper around svn_fs_berkeley_logfiles(),
  * returning log file paths relative to the root of the repository.
  *
@@ -715,12 +729,6 @@ const char *
 svn_repos_start_commit_hook(svn_repos_t *repos,
                             apr_pool_t *pool);
 
-/** Return the path to @a repos's init-commit hook, allocated in @a pool.
- * @since New in 1.8 */
-const char *
-svn_repos_init_commit_hook(svn_repos_t *repos,
-                           apr_pool_t *pool);
-
 /** Return the path to @a repos's pre-commit hook, allocated in @a pool. */
 const char *
 svn_repos_pre_commit_hook(svn_repos_t *repos,

Modified: subversion/branches/inheritable-props/subversion/libsvn_fs/fs-loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_fs/fs-loader.c?rev=1376886&r1=1376885&r2=1376886&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_fs/fs-loader.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_fs/fs-loader.c Fri Aug 24 10:38:22 2012
@@ -624,6 +624,17 @@ svn_fs_recover(const char *path,
                                          pool));
 }
 
+svn_error_t *
+svn_fs_freeze(svn_fs_t *fs,
+              svn_error_t *(*freeze_body)(void *baton, apr_pool_t *pool),
+              void *baton,
+              apr_pool_t *pool)
+{
+  SVN_ERR(fs->vtable->freeze(fs, freeze_body, baton, pool));
+
+  return SVN_NO_ERROR;
+}
+
 
 /* --- Berkeley-specific functions --- */
 

Modified: subversion/branches/inheritable-props/subversion/libsvn_fs/fs-loader.h
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_fs/fs-loader.h?rev=1376886&r1=1376885&r2=1376886&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_fs/fs-loader.h (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_fs/fs-loader.h Fri Aug 24 10:38:22 2012
@@ -202,6 +202,9 @@ typedef struct fs_vtable_t
                             svn_fs_get_locks_callback_t get_locks_func,
                             void *get_locks_baton,
                             apr_pool_t *pool);
+  svn_error_t *(*freeze)(svn_fs_t *fs,
+                         svn_error_t *(*freeze_body)(void *, apr_pool_t *),
+                         void *baton, apr_pool_t *pool);
   svn_error_t *(*bdb_set_errcall)(svn_fs_t *fs,
                                   void (*handler)(const char *errpfx,
                                                   char *msg));

Modified: subversion/branches/inheritable-props/subversion/libsvn_fs_base/fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_fs_base/fs.c?rev=1376886&r1=1376885&r2=1376886&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_fs_base/fs.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_fs_base/fs.c Fri Aug 24 10:38:22 2012
@@ -471,6 +471,14 @@ bdb_write_config(svn_fs_t *fs)
   return svn_io_file_close(dbconfig_file, fs->pool);
 }
 
+static svn_error_t *
+base_bdb_freeze(svn_fs_t *fs,
+                svn_error_t *(*freeze_body)(void *, apr_pool_t *),
+                void *baton,
+                apr_pool_t *pool)
+{
+  SVN__NOT_IMPLEMENTED();
+}
 
 
 /* Creating a new filesystem */
@@ -492,6 +500,7 @@ static fs_vtable_t fs_vtable = {
   svn_fs_base__unlock,
   svn_fs_base__get_lock,
   svn_fs_base__get_locks,
+  base_bdb_freeze,
   base_bdb_set_errcall,
 };
 

Modified: subversion/branches/inheritable-props/subversion/libsvn_fs_fs/fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_fs_fs/fs.c?rev=1376886&r1=1376885&r2=1376886&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_fs_fs/fs.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_fs_fs/fs.c Fri Aug 24 10:38:22 2012
@@ -38,6 +38,7 @@
 #include "tree.h"
 #include "lock.h"
 #include "id.h"
+#include "rep-cache.h"
 #include "svn_private_config.h"
 #include "private/svn_fs_util.h"
 
@@ -123,6 +124,46 @@ fs_set_errcall(svn_fs_t *fs,
   return SVN_NO_ERROR;
 }
 
+struct fs_freeze_baton_t {
+  svn_fs_t *fs;
+  svn_error_t *(*freeze_body)(void *, apr_pool_t *);
+  void *baton;
+};
+
+static svn_error_t *
+fs_freeze_body(void *baton,
+               apr_pool_t *pool)
+{
+  struct fs_freeze_baton_t *b = baton;
+  svn_boolean_t exists;
+
+  SVN_ERR(svn_fs_fs__exists_rep_cache(&exists, b->fs, pool));
+  if (exists)
+    SVN_ERR(svn_fs_fs__lock_rep_cache(b->fs, pool));
+
+  SVN_ERR(b->freeze_body(b->baton, pool));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+fs_freeze(svn_fs_t *fs,
+          svn_error_t *(*freeze_body)(void *, apr_pool_t *),
+          void *baton,
+          apr_pool_t *pool)
+{
+  struct fs_freeze_baton_t b;
+
+  b.fs = fs;
+  b.freeze_body = freeze_body;
+  b.baton = baton;
+
+  SVN_ERR(svn_fs__check_fs(fs, TRUE));
+  SVN_ERR(svn_fs_fs__with_write_lock(fs, fs_freeze_body, &b, pool));
+
+  return SVN_NO_ERROR;
+}
+
 
 
 /* The vtable associated with a specific open filesystem. */
@@ -143,6 +184,7 @@ static fs_vtable_t fs_vtable = {
   svn_fs_fs__unlock,
   svn_fs_fs__get_lock,
   svn_fs_fs__get_locks,
+  fs_freeze,
   fs_set_errcall
 };
 

Modified: subversion/branches/inheritable-props/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_fs_fs/fs_fs.c?rev=1376886&r1=1376885&r2=1376886&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_fs_fs/fs_fs.c Fri Aug 24 10:38:22 2012
@@ -3681,8 +3681,19 @@ get_revision_proplist(apr_hash_t **propl
    * non-packed shard.  If that fails, we will fall through to packed
    * shard reads. */
   if (!is_packed_revprop(fs, rev))
-    SVN_ERR(read_non_packed_revprop(proplist_p, fs, rev, generation,
-                                    pool));
+    {
+      svn_error_t *err = read_non_packed_revprop(proplist_p, fs, rev,
+                                                 generation, pool);
+      if (err)
+        {
+          if (!APR_STATUS_IS_ENOENT(err->apr_err)
+              || ffd->format < SVN_FS_FS__MIN_PACKED_REVPROP_FORMAT)
+            return svn_error_trace(err);
+
+          svn_error_clear(err);
+          *proplist_p = NULL; /* in case read_non_packed_revprop changed it */
+        }
+    }
 
   /* if revprop packing is available and we have not read the revprops, yet,
    * try reading them from a packed shard.  If that fails, REV is most

Modified: subversion/branches/inheritable-props/subversion/libsvn_fs_fs/rep-cache-db.sql
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_fs_fs/rep-cache-db.sql?rev=1376886&r1=1376885&r2=1376886&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_fs_fs/rep-cache-db.sql (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_fs_fs/rep-cache-db.sql Fri Aug 24 10:38:22 2012
@@ -57,3 +57,11 @@ FROM rep_cache
 -- STMT_DEL_REPS_YOUNGER_THAN_REV
 DELETE FROM rep_cache
 WHERE revision > ?1
+
+/* An INSERT takes an SQLite reserved lock that prevents other writes
+   but doesn't block reads.  The incomplete transaction means that no
+   permanent change is made to the database and the transaction is
+   removed when the database is closed.  */
+-- STMT_LOCK_REP
+BEGIN TRANSACTION;
+INSERT INTO rep_cache VALUES ('dummy', 0, 0, 0, 0)

Modified: subversion/branches/inheritable-props/subversion/libsvn_fs_fs/rep-cache.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_fs_fs/rep-cache.c?rev=1376886&r1=1376885&r2=1376886&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_fs_fs/rep-cache.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_fs_fs/rep-cache.c Fri Aug 24 10:38:22 2012
@@ -351,3 +351,17 @@ svn_fs_fs__del_rep_reference(svn_fs_t *f
 
   return SVN_NO_ERROR;
 }
+
+svn_error_t *
+svn_fs_fs__lock_rep_cache(svn_fs_t *fs,
+                          apr_pool_t *pool)
+{
+  fs_fs_data_t *ffd = fs->fsap_data;
+
+  if (! ffd->rep_cache_db)
+    SVN_ERR(svn_fs_fs__open_rep_cache(fs, pool));
+
+  SVN_ERR(svn_sqlite__exec_statements(ffd->rep_cache_db, STMT_LOCK_REP));
+
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/inheritable-props/subversion/libsvn_fs_fs/rep-cache.h
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_fs_fs/rep-cache.h?rev=1376886&r1=1376885&r2=1376886&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_fs_fs/rep-cache.h (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_fs_fs/rep-cache.h Fri Aug 24 10:38:22 2012
@@ -88,6 +88,12 @@ svn_fs_fs__del_rep_reference(svn_fs_t *f
                              svn_revnum_t youngest,
                              apr_pool_t *pool);
 
+/* Start a transaction to take an SQLite reserved lock that prevents
+   other writes. */
+svn_error_t *
+svn_fs_fs__lock_rep_cache(svn_fs_t *fs,
+                          apr_pool_t *pool);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: subversion/branches/inheritable-props/subversion/libsvn_fs_fs/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_fs_fs/tree.c?rev=1376886&r1=1376885&r2=1376886&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_fs_fs/tree.c Fri Aug 24 10:38:22 2012
@@ -44,7 +44,6 @@
 #include "svn_private_config.h"
 #include "svn_pools.h"
 #include "svn_error.h"
-#include "svn_dirent_uri.h"
 #include "svn_path.h"
 #include "svn_mergeinfo.h"
 #include "svn_fs.h"
@@ -230,7 +229,7 @@ find_descendents_in_cache(void *baton,
   struct fdic_baton *b = baton;
   const char *item_path = key;
 
-  if (svn_dirent_is_ancestor(b->path, item_path))
+  if (svn_fspath__skip_ancestor(b->path, item_path))
     APR_ARRAY_PUSH(b->list, const char *) = apr_pstrdup(b->pool, item_path);
 
   return SVN_NO_ERROR;

Modified: subversion/branches/inheritable-props/subversion/libsvn_repos/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_repos/commit.c?rev=1376886&r1=1376885&r2=1376886&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_repos/commit.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_repos/commit.c Fri Aug 24 10:38:22 2012
@@ -1334,12 +1334,8 @@ svn_repos__get_commit_ev2(svn_editor_t *
   /* Can the user modify the repository at all?  */
   /* ### check against AUTHZ.  */
 
-  /* Okay... some access is allowed. Let's run the start-commit hook.  */
   author = apr_hash_get(revprops, SVN_PROP_REVISION_AUTHOR,
                         APR_HASH_KEY_STRING);
-  SVN_ERR(svn_repos__hooks_start_commit(repos, author ? author->data : NULL,
-                                        repos->client_capabilities,
-                                        scratch_pool));
 
   eb = apr_palloc(result_pool, sizeof(*eb));
   eb->repos = repos;
@@ -1357,6 +1353,11 @@ svn_repos__get_commit_ev2(svn_editor_t *
   /* The TXN has been created. Go ahead and apply all revision properties.  */
   SVN_ERR(apply_revprops(repos->fs, eb->txn_name, revprops, scratch_pool));
 
+  /* Okay... some access is allowed. Let's run the start-commit hook.  */
+  SVN_ERR(svn_repos__hooks_start_commit(repos, author ? author->data : NULL,
+                                        repos->client_capabilities,
+                                        eb->txn_name, scratch_pool));
+
   /* Wrap the FS editor within our editor.  */
   SVN_ERR(svn_editor_create(editor, eb, cancel_func, cancel_baton,
                             result_pool, scratch_pool));

Modified: subversion/branches/inheritable-props/subversion/libsvn_repos/fs-wrap.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_repos/fs-wrap.c?rev=1376886&r1=1376885&r2=1376886&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_repos/fs-wrap.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_repos/fs-wrap.c Fri Aug 24 10:38:22 2012
@@ -90,11 +90,8 @@ svn_repos_fs_begin_txn_for_commit2(svn_f
                                       SVN_PROP_REVISION_AUTHOR,
                                       APR_HASH_KEY_STRING);
 
-  /* Run start-commit hooks. */
-  SVN_ERR(svn_repos__hooks_start_commit(repos, author ? author->data : NULL,
-                                        repos->client_capabilities, pool));
-
-  /* Begin the transaction, ask for the fs to do on-the-fly lock checks. */
+  /* Begin the transaction, ask for the fs to do on-the-fly lock checks.
+     We fetch its name, too, so the start-commit hook can use it.  */
   SVN_ERR(svn_fs_begin_txn2(txn_p, repos->fs, rev,
                             SVN_FS_TXN_CHECK_LOCKS, pool));
   SVN_ERR(svn_fs_txn_name(&txn_name, *txn_p, pool));
@@ -105,7 +102,11 @@ svn_repos_fs_begin_txn_for_commit2(svn_f
   revprops = svn_prop_hash_to_array(revprop_table, pool);
   SVN_ERR(svn_repos_fs_change_txn_props(*txn_p, revprops, pool));
 
-  return svn_error_trace(svn_repos__hooks_init_commit(repos, txn_name, pool));
+  /* Run start-commit hooks. */
+  SVN_ERR(svn_repos__hooks_start_commit(repos, author ? author->data : NULL,
+                                        repos->client_capabilities, txn_name,
+                                        pool));
+  return SVN_NO_ERROR;
 }
 
 

Modified: subversion/branches/inheritable-props/subversion/libsvn_repos/hooks.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_repos/hooks.c?rev=1376886&r1=1376885&r2=1376886&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_repos/hooks.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_repos/hooks.c Fri Aug 24 10:38:22 2012
@@ -124,7 +124,6 @@ check_hook_result(const char *name, cons
     {
       const char *action;
       if (strcmp(name, "start-commit") == 0
-          || strcmp(name, "init-commit") == 0
           || strcmp(name, "pre-commit") == 0)
         action = _("Commit");
       else if (strcmp(name, "pre-revprop-change") == 0)
@@ -358,6 +357,7 @@ svn_error_t *
 svn_repos__hooks_start_commit(svn_repos_t *repos,
                               const char *user,
                               const apr_array_header_t *capabilities,
+                              const char *txn_name,
                               apr_pool_t *pool)
 {
   const char *hook = svn_repos_start_commit_hook(repos, pool);
@@ -369,7 +369,7 @@ svn_repos__hooks_start_commit(svn_repos_
     }
   else if (hook)
     {
-      const char *args[5];
+      const char *args[6];
       char *capabilities_string;
 
       if (capabilities)
@@ -389,7 +389,8 @@ svn_repos__hooks_start_commit(svn_repos_
       args[1] = svn_dirent_local_style(svn_repos_path(repos, pool), pool);
       args[2] = user ? user : "";
       args[3] = capabilities_string;
-      args[4] = NULL;
+      args[4] = txn_name;
+      args[5] = NULL;
 
       SVN_ERR(run_hook_cmd(NULL, SVN_REPOS__HOOK_START_COMMIT, hook, args,
                            repos->hooks_env, NULL, pool));
@@ -398,34 +399,6 @@ svn_repos__hooks_start_commit(svn_repos_
   return SVN_NO_ERROR;
 }
 
-svn_error_t *
-svn_repos__hooks_init_commit(svn_repos_t *repos,
-                             const char *txn_name,
-                             apr_pool_t *pool)
-{
-  const char *hook = svn_repos_init_commit_hook(repos, pool);
-  svn_boolean_t broken_link;
-
-  if ((hook = check_hook_cmd(hook, &broken_link, pool)) && broken_link)
-    {
-      return hook_symlink_error(hook);
-    }
-  else if (hook)
-    {
-      const char *args[4];
-
-      args[0] = hook;
-      args[1] = svn_dirent_local_style(svn_repos_path(repos, pool), pool);
-      args[2] = txn_name;
-      args[3] = NULL;
-
-      SVN_ERR(run_hook_cmd(NULL, SVN_REPOS__HOOK_INIT_COMMIT, hook, args,
-                           repos->hooks_env, NULL, pool));
-    }
-
-  return SVN_NO_ERROR;
-}
-
 /* Set *HANDLE to an open filehandle for a temporary file (i.e.,
    automatically deleted when closed), into which the LOCK_TOKENS have
    been written out in the format described in the pre-commit hook

Modified: subversion/branches/inheritable-props/subversion/libsvn_repos/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_repos/repos.c?rev=1376886&r1=1376885&r2=1376886&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_repos/repos.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_repos/repos.c Fri Aug 24 10:38:22 2012
@@ -111,13 +111,6 @@ svn_repos_start_commit_hook(svn_repos_t 
 
 
 const char *
-svn_repos_init_commit_hook(svn_repos_t *repos, apr_pool_t *pool)
-{
-  return svn_dirent_join(repos->hook_path, SVN_REPOS__HOOK_INIT_COMMIT, pool);
-}
-
-
-const char *
 svn_repos_pre_commit_hook(svn_repos_t *repos, apr_pool_t *pool)
 {
   return svn_dirent_join(repos->hook_path, SVN_REPOS__HOOK_PRE_COMMIT, pool);
@@ -318,16 +311,17 @@ create_hooks(svn_repos_t *repos, apr_poo
 ""                                                                           NL
 "# START-COMMIT HOOK"                                                        NL
 "#"                                                                          NL
-"# The start-commit hook is invoked before a Subversion txn is created"      NL
-"# in the process of doing a commit.  Subversion runs this hook"             NL
-"# by invoking a program (script, executable, binary, etc.) named"           NL
-"# '"SCRIPT_NAME"' (for which this file is a template)"                      NL
-"# with the following ordered arguments:"                                    NL
+"# The start-commit hook is invoked immediately after a Subversion txn is"   NL
+"# created and populated with initial revprops in the process of doing a"    NL
+"# commit. Subversion runs this hook by invoking a program (script, "        NL
+"# executable, binary, etc.) named '"SCRIPT_NAME"' (for which this file"     NL
+"# is a template) with the following ordered arguments:"                     NL
 "#"                                                                          NL
 "#   [1] REPOS-PATH   (the path to this repository)"                         NL
 "#   [2] USER         (the authenticated user attempting to commit)"         NL
 "#   [3] CAPABILITIES (a colon-separated list of capabilities reported"      NL
 "#                     by the client; see note below)"                       NL
+"#   [4] TXN-NAME     (the name of the commit txn just created)"             NL
 "#"                                                                          NL
 "# Note: The CAPABILITIES parameter is new in Subversion 1.5, and 1.5"       NL
 "# clients will typically report at least the \""                            \
@@ -359,6 +353,10 @@ create_hooks(svn_repos_t *repos, apr_poo
 "# '"SCRIPT_NAME".bat' or '"SCRIPT_NAME".exe',"                              NL
 "# but the basic idea is the same."                                          NL
 "# "                                                                         NL
+"# COMPATIBILITY NOTE:  Prior to Subversion 1.8, the start-commit hook was"  NL
+"# invoked before the commit txn was even created, and it did not accept"    NL
+"# the TXN-NAME argument at all."                                            NL
+"# "                                                                         NL
 HOOKS_ENVIRONMENT_TEXT
 "# "                                                                         NL
 "# Here is an example hook script, for a Unix /bin/sh interpreter."          NL
@@ -382,93 +380,6 @@ PREWRITTEN_HOOKS_TEXT
     SVN_ERR(svn_io_set_file_executable(this_path, TRUE, FALSE, pool));
   }  /* end start-commit hook */
 
-  /* Init-commit hook. */
-  {
-    this_path = apr_psprintf(pool, "%s%s",
-                             svn_repos_init_commit_hook(repos, pool),
-                             SVN_REPOS__HOOK_DESC_EXT);
-
-#define SCRIPT_NAME SVN_REPOS__HOOK_INIT_COMMIT
-
-    contents =
-"#!/bin/sh"                                                                  NL
-""                                                                           NL
-"# INIT-COMMIT HOOK"                                                         NL
-"#"                                                                          NL
-"# The init-commit hook is invoked immediate after a Subversion commit txn"  NL
-"# is created and initialized.  Subversion runs this hook by invoking a"     NL
-"# program (script, executable, binary, etc.) named '"SCRIPT_NAME"' (for"    NL
-"# which this file is a template), with the following ordered arguments:"    NL
-"#"                                                                          NL
-"#   [1] REPOS-PATH   (the path to this repository)"                         NL
-"#   [2] TXN-NAME     (the name of the commit txn just created)"             NL
-"#"                                                                          NL
-"# The default working directory for the invocation is undefined, so"        NL
-"# the program should set one explicitly if it cares."                       NL
-"#"                                                                          NL
-"# If the hook program exits with success, the commit txn remains active;"   NL
-"# but if it exits with failure (non-zero), the txn is aborted, no commit"   NL
-"# takes place, and STDERR is returned to the client.   The hook"            NL
-"# program can use the 'svnlook' utility to help it examine the txn."        NL
-"#"                                                                          NL
-"# On a Unix system, the normal procedure is to have '"SCRIPT_NAME"'"        NL
-"# invoke other programs to do the real work, though it may do the"          NL
-"# work itself too."                                                         NL
-"#"                                                                          NL
-"#   ***  NOTE: THE HOOK PROGRAM MUST NOT MODIFY THE TXN, EXCEPT  ***"       NL
-"#   ***  FOR REVISION PROPERTIES (like svn:log or svn:author).   ***"       NL
-"#"                                                                          NL
-"#   This is why we recommend using the read-only 'svnlook' utility."        NL
-"#   In the future, Subversion may enforce the rule that pre-commit"         NL
-"#   hooks should not modify the versioned data in txns, or else come"       NL
-"#   up with a mechanism to make it safe to do so (by informing the"         NL
-"#   committing client of the changes).  However, right now neither"         NL
-"#   mechanism is implemented, so hook writers just have to be careful."     NL
-"#"                                                                          NL
-"# Note that '"SCRIPT_NAME"' must be executable by the user(s) who will"     NL
-"# invoke it (typically the user httpd runs as), and that user must"         NL
-"# have filesystem-level permission to access the repository."               NL
-"#"                                                                          NL
-"# On a Windows system, you should name the hook program"                    NL
-"# '"SCRIPT_NAME".bat' or '"SCRIPT_NAME".exe',"                              NL
-"# but the basic idea is the same."                                          NL
-"#"                                                                          NL
-"# WARNING: The degree of txn \"initialization\" may differ depending on"    NL
-"# how the commit process is being driven.  For example, some older"         NL
-"# Subversion clients (notably pre-1.7 clients committing over HTTP) will"   NL
-"# not have yet attached some metadata -- such as the commit log message --" NL
-"# to the txn by the time this hook runs.  Hook authors should therefore"    NL
-"# not assume that a txn which lacks a log message at this stage of the  "   NL
-"# commit will necessarily still lack a log message by the time the commit"  NL
-"# completes."                                                               NL
-"#"                                                                          NL
-HOOKS_ENVIRONMENT_TEXT
-"# "                                                                         NL
-"# Here is an example hook script, for a Unix /bin/sh interpreter."          NL
-PREWRITTEN_HOOKS_TEXT
-""                                                                           NL
-""                                                                           NL
-"REPOS=\"$1\""                                                               NL
-"TXN=\"$2\""                                                                 NL
-""                                                                           NL
-"# If a log message is present, make sure it mentions an issue tracker id."  NL
-"SVNLOOK=" SVN_BINDIR "/svnlook"                                             NL
-"if $SVNLOOK log -t \"$TXN\" \"$REPOS\" | \\"                                NL
-"   grep \"[a-zA-Z0-9]\" > /dev/null; then \\"                               NL
-"       $SVNLOOK log -t \"$TXN\" \"$REPOS\" | \\"                            NL
-"           grep -E \"issue [0-9]+\" > /dev/null || exit 1; fi"              NL
-""                                                                           NL
-"# All checks passed, so allow the commit to proceed."                       NL
-"exit 0"                                                                     NL;
-
-#undef SCRIPT_NAME
-    SVN_ERR_W(svn_io_file_create(this_path, contents, pool),
-              _("Creating init-commit hook"));
-
-    SVN_ERR(svn_io_set_file_executable(this_path, TRUE, FALSE, pool));
-  }  /* end init-commit hook */
-
-
   /* Pre-commit hook. */
   {
     this_path = apr_psprintf(pool, "%s%s",
@@ -1779,6 +1690,47 @@ svn_repos_recover4(const char *path,
   return SVN_NO_ERROR;
 }
 
+/* For BDB we fall back on BDB's repos layer lock which means that the
+   repository is unreadable while frozen.
+
+   For FSFS we delegate to the FS layer which uses the FSFS write-lock
+   and an SQLite reserved lock which means the repository is readable
+   while frozen. */
+svn_error_t *
+svn_repos_freeze(const char *path,
+                 svn_error_t *(*freeze_body)(void *, apr_pool_t *),
+                 void *baton,
+                 apr_pool_t *pool)
+{
+  svn_repos_t *repos;
+
+  /* Using a subpool as the only way to unlock the repos lock used by
+     BDB is to clear the pool used to take the lock. */
+  apr_pool_t *subpool = svn_pool_create(pool);
+
+  SVN_ERR(get_repos(&repos, path,
+                    TRUE  /* exclusive */,
+                    FALSE /* non-blocking */,
+                    FALSE /* open-fs */,
+                    NULL, subpool));
+
+  if (strcmp(repos->fs_type, SVN_FS_TYPE_BDB) == 0)
+    {
+      svn_error_t *err = freeze_body(baton, subpool);
+      svn_pool_destroy(subpool);
+      return err;
+    }
+  else
+    {
+      SVN_ERR(svn_fs_open(&repos->fs, repos->db_path, NULL, subpool));
+      SVN_ERR(svn_fs_freeze(svn_repos_fs(repos), freeze_body, baton, subpool));
+    }
+
+  svn_pool_destroy(subpool);
+
+  return SVN_NO_ERROR;
+}
+
 svn_error_t *svn_repos_db_logfiles(apr_array_header_t **logfiles,
                                    const char *path,
                                    svn_boolean_t only_unused,

Modified: subversion/branches/inheritable-props/subversion/libsvn_repos/repos.h
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_repos/repos.h?rev=1376886&r1=1376885&r2=1376886&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_repos/repos.h (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_repos/repos.h Fri Aug 24 10:38:22 2012
@@ -70,7 +70,6 @@ extern "C" {
 
 /* In the repository hooks directory, look for these files. */
 #define SVN_REPOS__HOOK_START_COMMIT    "start-commit"
-#define SVN_REPOS__HOOK_INIT_COMMIT     "init-commit"
 #define SVN_REPOS__HOOK_PRE_COMMIT      "pre-commit"
 #define SVN_REPOS__HOOK_POST_COMMIT     "post-commit"
 #define SVN_REPOS__HOOK_READ_SENTINEL   "read-sentinels"
@@ -154,25 +153,21 @@ struct svn_repos_t
    allocations.  If the hook fails, return SVN_ERR_REPOS_HOOK_FAILURE.
 
    USER is the authenticated name of the user starting the commit.
+
    CAPABILITIES is a list of 'const char *' capability names (using
    SVN_RA_CAPABILITY_*) that the client has self-reported.  Note that
    there is no guarantee the client is telling the truth: the hook
-   should not make security assumptions based on the capabilities. */
+   should not make security assumptions based on the capabilities.
+
+   TXN_NAME is the name of the commit transaction that's just been
+   created. */
 svn_error_t *
 svn_repos__hooks_start_commit(svn_repos_t *repos,
                               const char *user,
                               const apr_array_header_t *capabilities,
+                              const char *txn_name,
                               apr_pool_t *pool);
 
-/* Run the init-commit hook for REPOS.  Use POOL for any temporary
-   allocations.  If the hook fails, return SVN_ERR_REPOS_HOOK_FAILURE.
-
-   TXN_NAME is the name of the transaction that is being committed.  */
-svn_error_t *
-svn_repos__hooks_init_commit(svn_repos_t *repos,
-                             const char *txn_name,
-                             apr_pool_t *pool);
-
 /* Run the pre-commit hook for REPOS.  Use POOL for any temporary
    allocations.  If the hook fails, return SVN_ERR_REPOS_HOOK_FAILURE.
 

Modified: subversion/branches/inheritable-props/subversion/libsvn_subr/dirent_uri.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_subr/dirent_uri.c?rev=1376886&r1=1376885&r2=1376886&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_subr/dirent_uri.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_subr/dirent_uri.c Fri Aug 24 10:38:22 2012
@@ -1401,7 +1401,7 @@ svn_dirent_skip_ancestor(const char *par
   apr_size_t len = strlen(parent_dirent);
   apr_size_t root_len;
 
-  if (0 != memcmp(parent_dirent, child_dirent, len))
+  if (0 != strncmp(parent_dirent, child_dirent, len))
     return NULL; /* parent_dirent is no ancestor of child_dirent */
 
   if (child_dirent[len] == 0)
@@ -1459,7 +1459,7 @@ svn_relpath_skip_ancestor(const char *pa
   if (len == 0)
     return child_relpath;
 
-  if (0 != memcmp(parent_relpath, child_relpath, len))
+  if (0 != strncmp(parent_relpath, child_relpath, len))
     return NULL; /* parent_relpath is no ancestor of child_relpath */
 
   if (child_relpath[len] == 0)
@@ -1482,7 +1482,7 @@ uri_skip_ancestor(const char *parent_uri
   assert(svn_uri_is_canonical(parent_uri, NULL));
   assert(svn_uri_is_canonical(child_uri, NULL));
 
-  if (0 != memcmp(parent_uri, child_uri, len))
+  if (0 != strncmp(parent_uri, child_uri, len))
     return NULL; /* parent_uri is no ancestor of child_uri */
 
   if (child_uri[len] == 0)

Modified: subversion/branches/inheritable-props/subversion/svnadmin/main.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/svnadmin/main.c?rev=1376886&r1=1376885&r2=1376886&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/svnadmin/main.c (original)
+++ subversion/branches/inheritable-props/subversion/svnadmin/main.c Fri Aug 24 10:38:22 2012
@@ -150,6 +150,7 @@ static svn_opt_subcommand_t
   subcommand_create,
   subcommand_deltify,
   subcommand_dump,
+  subcommand_freeze,
   subcommand_help,
   subcommand_hotcopy,
   subcommand_load,
@@ -336,6 +337,11 @@ static const svn_opt_subcommand_desc2_t 
     "changed in those revisions.)\n"),
   {'r', svnadmin__incremental, svnadmin__deltas, 'q', 'M'} },
 
+  {"freeze", subcommand_freeze, {0}, N_
+   ("usage: svnadmin freeze REPOS_PATH PROGRAM [ARG...]\n\n"
+    "Run PROGRAM passing ARGS while holding a write-lock on REPOS_PATH.\n"),
+   {0} },
+
   {"help", subcommand_help, {"?", "h"}, N_
    ("usage: svnadmin help [SUBCOMMAND...]\n\n"
     "Describe the usage of this program or its subcommands.\n"),
@@ -969,6 +975,66 @@ subcommand_dump(apr_getopt_t *os, void *
   return SVN_NO_ERROR;
 }
 
+struct freeze_baton_t {
+  const char *command;
+  const char **args;
+  int status;
+};
+
+static svn_error_t *
+freeze_body(void *baton,
+            apr_pool_t *pool)
+{
+  struct freeze_baton_t *b = baton;
+  apr_status_t apr_err;
+  apr_file_t *infile, *outfile, *errfile;
+
+  apr_err = apr_file_open_stdin(&infile, pool);
+  if (apr_err)
+    return svn_error_wrap_apr(apr_err, "Can't open stdin");
+  apr_err = apr_file_open_stdout(&outfile, pool);
+  if (apr_err)
+    return svn_error_wrap_apr(apr_err, "Can't open stdout");
+  apr_err = apr_file_open_stderr(&errfile, pool);
+  if (apr_err)
+    return svn_error_wrap_apr(apr_err, "Can't open stderr");
+
+  SVN_ERR(svn_io_run_cmd(NULL, b->command, b->args, &b->status,
+                         NULL, TRUE,
+                         infile, outfile, errfile, pool));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+subcommand_freeze(apr_getopt_t *os, void *baton, apr_pool_t *pool)
+{
+  struct svnadmin_opt_state *opt_state = baton;
+  apr_array_header_t *args;
+  int i;
+  struct freeze_baton_t b;
+
+  SVN_ERR(svn_opt_parse_all_args(&args, os, pool));
+
+  if (!args->nelts)
+    return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, 0,
+                            _("No program provided"));
+
+  b.command = APR_ARRAY_IDX(args, 0, const char *);
+  b.args = apr_palloc(pool, sizeof(char *) * args->nelts + 1);
+  for (i = 0; i < args->nelts; ++i)
+    b.args[i] = APR_ARRAY_IDX(args, i, const char *);
+  b.args[args->nelts] = NULL;
+
+  SVN_ERR(svn_repos_freeze(opt_state->repository_path, freeze_body, &b, pool));
+
+  /* Make any non-zero status visible to the user. */
+  if (b.status)
+    exit(b.status);
+
+  return SVN_NO_ERROR;
+}
+
 
 /* This implements `svn_opt_subcommand_t'. */
 static svn_error_t *

Modified: subversion/branches/inheritable-props/subversion/tests/cmdline/commit_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/tests/cmdline/commit_tests.py?rev=1376886&r1=1376885&r2=1376886&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/tests/cmdline/commit_tests.py (original)
+++ subversion/branches/inheritable-props/subversion/tests/cmdline/commit_tests.py Fri Aug 24 10:38:22 2012
@@ -2940,47 +2940,7 @@ def commit_moved_dir_with_nested_mod_in_
               'Last Changed Rev'  : '2',
              }
   svntest.actions.run_and_verify_info([expected], E_copied)
-
-#----------------------------------------------------------------------
-def init_commit_hook_test(sbox):
-  "init-commit hook failure case testing"
-
-  sbox.build()
-
-  # Get paths to the working copy and repository
-  wc_dir = sbox.wc_dir
-  repo_dir = sbox.repo_dir
-
-  # Create a hook that outputs a message to stderr and returns exit code 1
-  # Include a non-XML-safe message as history shows there've been
-  # problems with such in hooks (see issue #3553).
-  error_msg = "Text with <angle brackets> & ampersand"
-  svntest.actions.create_failing_hook(repo_dir, "init-commit", error_msg)
-
-  # Modify iota just so there is something to commit.
-  iota_path = sbox.ospath('iota')
-  svntest.main.file_append(iota_path, "More stuff in iota")
-
-  # Commit, expect error code 1
-  exit_code, actual_stdout, actual_stderr = svntest.main.run_svn(
-    1, 'ci', '--quiet', '-m', 'log msg', wc_dir)
-
-  # No stdout expected
-  svntest.verify.compare_and_display_lines('Init-commit hook test',
-                                           'STDOUT', [], actual_stdout)
-
-  # Compare only the last two lines of stderr since the preceding ones
-  # contain source code file and line numbers.
-  if len(actual_stderr) > 2:
-    actual_stderr = actual_stderr[-2:]
-  expected_stderr = [ "svn: E165001: " +
-                        svntest.actions.hook_failure_message('init-commit'),
-                      error_msg + "\n",
-                    ]
-  svntest.verify.compare_and_display_lines('Init-commit hook test',
-                                           'STDERR',
-                                           expected_stderr, actual_stderr)
-
+  
   
 ########################################################################
 # Run the tests
@@ -3053,7 +3013,6 @@ test_list = [ None,
               commit_add_subadd,
               commit_danglers,
               commit_moved_dir_with_nested_mod_in_subdir,
-              init_commit_hook_test,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/inheritable-props/subversion/tests/cmdline/svntest/actions.py
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/tests/cmdline/svntest/actions.py?rev=1376886&r1=1376885&r2=1376886&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/tests/cmdline/svntest/actions.py (original)
+++ subversion/branches/inheritable-props/subversion/tests/cmdline/svntest/actions.py Fri Aug 24 10:38:22 2012
@@ -1921,7 +1921,7 @@ def hook_failure_message(hook_name):
   if svntest.main.options.server_minor_version < 5:
     return "'%s' hook failed with error output:\n" % hook_name
   else:
-    if hook_name in ["start-commit", "pre-commit", "init-commit"]:
+    if hook_name in ["start-commit", "pre-commit"]:
       action = "Commit"
     elif hook_name == "pre-revprop-change":
       action = "Revprop change"

Modified: subversion/branches/inheritable-props/subversion/tests/libsvn_subr/dirent_uri-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/tests/libsvn_subr/dirent_uri-test.c?rev=1376886&r1=1376885&r2=1376886&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/tests/libsvn_subr/dirent_uri-test.c (original)
+++ subversion/branches/inheritable-props/subversion/tests/libsvn_subr/dirent_uri-test.c Fri Aug 24 10:38:22 2012
@@ -1364,6 +1364,9 @@ static const testcase_ancestor_t dirent_
     { "foo.",           "foo./.bar",        ".bar" },
     { "X:foo",          "X:bar",            NULL },
     { "../foo",         "..",               NULL },
+    { "/foo/bar/zig",   "/foo",             NULL },
+    { "/foo/bar/zig",   "/foo/ba",          NULL },
+    { "/foo/bar/zig",   "/foo/bar/zi",      NULL },
 #ifdef SVN_USE_DOS_PATHS
     { "",               "C:",               NULL },
     { "",               "C:foo",            NULL },
@@ -1384,6 +1387,9 @@ static const testcase_ancestor_t dirent_
     { "X:/foo",         "X:/",              NULL },
     { "A:/foo",         "A:/foo/bar",       "bar" },
     { "A:/foo",         "A:/foot",          NULL },
+    { "A:/foo/bar/zig", "A:/foo",           NULL },
+    { "A:/foo/bar/zig", "A:/foo/ba",        NULL },
+    { "A:/foo/bar/zig", "A:/foo/bar/zi",    NULL },
     { "//srv",          "//srv/share",      NULL },
     { "//srv",          "//srv/shr/fld",    NULL },
     { "//srv/shr",      "//srv",            NULL },
@@ -1393,6 +1399,7 @@ static const testcase_ancestor_t dirent_
     { "//srv/s r",      "//srv/s r/fld",    "fld" },
     { "//srv/shr/fld",  "//srv/shr",        NULL },
     { "//srv/shr/fld",  "//srv2/shr/fld",   NULL },
+    { "//srv/shr/fld",  "//srv/shr/f",      NULL },
     { "/",              "//srv/share",      NULL },
 #else /* !SVN_USE_DOS_PATHS */
     { "",               "C:",               "C:" },
@@ -1458,6 +1465,8 @@ static const testcase_ancestor_t uri_anc
     { "http://",        "http://test",      NULL },
     { "http://server",  "http://server/q",  "q" },
     { "svn://server",   "http://server/q",  NULL },
+    { "http://foo/bar", "http://foo",       NULL },
+    { "http://foo/bar", "http://foo/ba",    NULL },
   };
 
 static svn_error_t *