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 *