svn_error_t * svn_repos_fs_begin_txn_for_update(svn_fs_txn_t **txn_p, svn_repos_t *repos, svn_revnum_t rev, const char *author, apr_pool_t *pool) { /* ### someday, we might run a read-hook here. */ /* Begin the transaction. */ SVN_ERR(svn_fs_begin_txn2(txn_p, repos->fs, rev, 0, pool)); /* We pass the author to the filesystem by adding it as a property on the txn. */ /* User (author). */ if (author) { svn_string_t val; val.data = author; val.len = strlen(author); SVN_ERR(svn_fs_change_txn_prop(*txn_p, SVN_PROP_REVISION_AUTHOR, &val, pool)); } return SVN_NO_ERROR; }
svn_error_t * svn_repos_fs_commit_txn(const char **conflict_p, svn_repos_t *repos, svn_revnum_t *new_rev, svn_fs_txn_t *txn, apr_pool_t *pool) { svn_error_t *err, *err2; const char *txn_name; apr_hash_t *props; apr_pool_t *iterpool; apr_hash_index_t *hi; apr_hash_t *hooks_env; *new_rev = SVN_INVALID_REVNUM; /* Parse the hooks-env file (if any). */ SVN_ERR(svn_repos__parse_hooks_env(&hooks_env, repos->hooks_env_path, pool, pool)); /* Run pre-commit hooks. */ SVN_ERR(svn_fs_txn_name(&txn_name, txn, pool)); SVN_ERR(svn_repos__hooks_pre_commit(repos, hooks_env, txn_name, pool)); /* Remove any ephemeral transaction properties. */ SVN_ERR(svn_fs_txn_proplist(&props, txn, pool)); iterpool = svn_pool_create(pool); for (hi = apr_hash_first(pool, props); hi; hi = apr_hash_next(hi)) { const void *key; apr_hash_this(hi, &key, NULL, NULL); svn_pool_clear(iterpool); if (strncmp(key, SVN_PROP_TXN_PREFIX, (sizeof(SVN_PROP_TXN_PREFIX) - 1)) == 0) { SVN_ERR(svn_fs_change_txn_prop(txn, key, NULL, iterpool)); } } svn_pool_destroy(iterpool); /* Commit. */ err = svn_fs_commit_txn(conflict_p, new_rev, txn, pool); if (! SVN_IS_VALID_REVNUM(*new_rev)) return err; /* Run post-commit hooks. */ if ((err2 = svn_repos__hooks_post_commit(repos, hooks_env, *new_rev, txn_name, pool))) { err2 = svn_error_create (SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED, err2, _("Commit succeeded, but post-commit hook failed")); } return svn_error_compose_create(err, err2); }
static svn_error_t * set_revision_property(void *baton, const char *name, const svn_string_t *value) { struct revision_baton *rb = baton; /* If we're skipping this revision, we're done here. */ if (rb->skipped) return SVN_NO_ERROR; if (rb->rev > 0) { if (rb->pb->validate_props) SVN_ERR(svn_repos_fs_change_txn_prop(rb->txn, name, value, rb->pool)); else SVN_ERR(svn_fs_change_txn_prop(rb->txn, name, value, rb->pool)); /* Remember any datestamp that passes through! (See comment in close_revision() below.) */ if (! strcmp(name, SVN_PROP_REVISION_DATE)) rb->datestamp = svn_string_dup(value, rb->pool); } else if (rb->rev == 0) { /* Special case: set revision 0 properties when loading into an 'empty' filesystem. */ struct parse_baton *pb = rb->pb; svn_revnum_t youngest_rev; SVN_ERR(svn_fs_youngest_rev(&youngest_rev, pb->fs, rb->pool)); if (youngest_rev == 0) SVN_ERR(change_rev_prop(pb->repos, 0, name, value, pb->validate_props, rb->pool)); } return SVN_NO_ERROR; }