On the 'svnsync-atomic-author' branch:

Let svnsync set svn:author and svn:date in the commit itself when the
destination supports it, instead of patching them up with a post-commit
revprop change. This makes mirroring a revision atomic for ra_local
destinations and removes the window where a mirrored revision briefly
carries the wrong author and date.

See discussion: https://lists.apache.org/thread/qnxqd4whjp62rk2pgndt8xyp40oqnom2

Introduce SVN_RA_CAPABILITY_COMMIT_PRESERVES_AUTHOR_DATE, advertised by
ra_local and wired through the standard capability negotiation for svn://
and http:// so future servers can opt in without client changes. Rev the
repos-layer commit APIs to carry transaction flags (SVN_FS_TXN_CLIENT_DATE).

* subversion/include/svn_ra.h
  (SVN_RA_CAPABILITY_COMMIT_PRESERVES_AUTHOR_DATE): New capability.
  (svn_ra_get_commit_editor3): Allow svn:author/svn:date in REVPROP_TABLE
    when the session advertises the new capability.

* subversion/include/svn_ra_svn.h
  (SVN_RA_SVN_CAP_COMMIT_PRESERVES_AUTHOR_DATE): New wire capability.

* subversion/include/svn_dav.h
  (SVN_DAV_NS_DAV_SVN_COMMIT_PRESERVES_AUTHOR_DATE): New OPTIONS header token.

* subversion/include/svn_repos.h
  (svn_repos_get_commit_editor6, svn_repos_fs_begin_txn_for_commit3): New,
    taking TXN_FLAGS.
  (svn_repos_get_commit_editor5, svn_repos_fs_begin_txn_for_commit2):
    Deprecate.

* subversion/include/private/svn_repos_private.h
  (svn_repos__get_commit_ev2): Take TXN_FLAGS.

* subversion/libsvn_repos/commit.c
  (edit_baton): Add TXN_FLAGS.
  (open_root): Pass them to svn_repos_fs_begin_txn_for_commit3().
  (svn_repos_get_commit_editor6, svn_repos__get_commit_ev2): Accept and
    forward TXN_FLAGS.

* subversion/libsvn_repos/fs-wrap.c
  (svn_repos_fs_begin_txn_for_commit3): New revision of ..._commit2(),
    OR-ing TXN_FLAGS into SVN_FS_TXN_CHECK_LOCKS.
  (svn_repos_fs_begin_txn_for_commit): Move to deprecated.c.

* subversion/libsvn_repos/deprecated.c
  (svn_repos_get_commit_editor5, svn_repos_fs_begin_txn_for_commit2,
   svn_repos_fs_begin_txn_for_commit): Implement as wrappers.

* subversion/libsvn_ra_local/ra_plugin.c
  (prepare_commit_revprops): New helper: default svn:author to the session
    username only when absent, and request SVN_FS_TXN_CLIENT_DATE iff the
 * is committed; otherwise it will be overwritten with the commit
 *
 * @since New in 1.16.

                                   svn_repos_t *repos,
t32_t txn_flags,
                                   apr_pool_t *pool);


/** Like svn_repos_fs_begin_txn_for_commit3(), but with @a flags
/** Like svn_repos_fs_begin_txn_for_commit3(), but with @a txn_flags
 * set to #SVN_FS_TXN_CHECK_LOCKS only.
 *
 * @note @a revprop_table may contain an #SVN_PROP_REVISION_DATE property,

  Read 1 file

● Update(subversion\libsvn_repos\fs-wrap.c)
Added 1 line, removed 1 line
                                   svn_repos_t *repos,
                                   svn_revnum_t rev,
_t *pool)
{
  apr_array_header_t *revprops;

● Update(subversion\libsvn_repos\fs-wrap.c)
Added 1 line, removed 1 line
  /* 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, repos->fs, rev,
                            SVN_FS_TXN_CHECK_LOCKS | flags, pool));
                            SVN_FS_TXN_CHECK_LOCKS | txn_flags, poo
  err = svn_fs_txn_name(&txn_name, txn, pool);
  if (err)
    return svn_error_compose_create(err, svn_fs_abort_txn(txn, pool));

Fix 5c — state commit_callback nullability on editor6 directly (replacing the stale pre-1.6 parenthetical):

● Update(subversion\include\svn_repos.h)
Added 1 line, removed 2 lines
 * returns an error, that error will be returned from @c close_edit,
 * otherwise if there was a post-commit hook failure, then that error
 * will be returned with code SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED.
 * (Note that prior to Subversion 1.6, @a commit_callback cannot be @c NULL;
 * if you don't need a callback, pass a dummy function.)
 * @a commit_callback may be @c NULL.
 *
 * Calling @a (*editor)->abort_edit aborts the commit, and will also
 * abort the commit transaction unless @a txn was supplied (not @c
You've hit your session limit · resets 9:50pm (Europe/London)
/upgrade or /usage-credits to finish what you’re working on.

✻ Baked for 5m 21s

❯ Can you put together a brief commit message for this change

Here's a commit message in the Apache Subversion log-message convention (summary paragraph plus per-file annotations), ready for svn commit -F:

On the 'svnsync-atomic-author' branch:

Let svnsync set svn:author and svn:date in the commit itself when the
destination supports it, instead of patching them up with a post-commit
revprop change.  This makes mirroring a revision atomic for ra_local
destinations and removes the window where a mirrored revision briefly
ent changes.  Rev the
repos-layer commit APIs to carry transaction flags (SVN_FS_TXN_CLIENT_DATE).

* subversion/include/svn_ra.h
  (SVN_RA_CAPABILITY_COMMIT_PRESERVES_AUTHOR_DATE): New capability.
  (svn_ra_get_commit_editor3): Allow svn:author/svn:date in REVPROP_TABLE
    when the session advertises the new capability.

* subversion/include/svn_ra_svn.h
  (SVN_RA_SVN_CAP_COMMIT_PRESERVES_AUTHOR_DATE): New wire capability.

* subversion/include/svn_dav.h
  (SVN_DAV_NS_DAV_SVN_COMMIT_PRESERVES_AUTHOR_DATE): New OPTIONS header token.

* subversion/include/svn_repos.h
  (svn_repos_get_commit_editor6, svn_repos_fs_begin_txn_for_commit3): New,
    taking TXN_FLAGS.
  (svn_repos_get_commit_editor5, svn_repos_fs_begin_txn_for_commit2):

* subversion/libsvn_repos/commit.c
  (edit_baton): Add TXN_FLAGS.
  (open_root): Pass them to svn_repos_fs_begin_txn_for_commit3().
  (svn_repos_get_commit_editor6, svn_repos__get_commit_ev2): Accept and
    forward TXN_FLAGS.

* subversion/libsvn_repos/fs-wrap.c
  (svn_repos_fs_begin_txn_for_commit3): New revision of ..._commit2(),
    OR-ing TXN_FLAGS into SVN_FS_TXN_CHECK_LOCKS.
  (svn_repos_fs_begin_txn_for_commit): Move to deprecated.c.

* subversion/libsvn_repos/deprecated.c
  (svn_repos_get_commit_editor5, svn_repos_fs_begin_txn_for_commit2,
   svn_repos_fs_begin_txn_for_commit): Implement as wrappers.

* subversion/libsvn_ra_local/ra_plugin.c

  (svn_ra_local__get_commit_editor, svn_ra_local__get_commit_ev2): Use it.
  (svn_ra_local__has_capability): Advertise the new capability.

* subversion/libsvn_ra_svn/client.c
  (ra_svn_has_capability): Map the new capability to its wire word.

* subversion/libsvn_ra_serf/options.c
  (capabilities_headers_iterator_callback, options_response_handler):
    Parse and pre-seed the new capability.

* subversion/mod_dav_svn/activity.c (dav_svn__create_txn),
  subversion/mod_dav_svn/lock.c (append_locks),
  subversion/svnserve/serve.c (commit):
    Track the API revs; no functional change.

* subversion/svnsync/svnsync.c
 once per sync how
    revprops split between the commit and a follow-up revprop update.
  (replay_rev_started, replay_rev_finished, do_synchronize): Use that
    decision; skip the follow-up pass entirely when the commit carries
    author/date.

* subversion/tests/libsvn_repos/repos-test.c
  (commit_add_file, commit_editor_preserve_revprops): New test for both
    SVN_FS_TXN_CLIENT_DATE polarities via the commit editor.

* subversion/tests/cmdline/svnsync_tests.py
  (sync_to_local_preserves_author_date): New test: an ra_local sync
    preserves author/date with no post-commit revprop copy.

git-svn-id: https://svn.apache.org/repos/asf/subversion/branches/svnsync-atomic-author@1935862 13f79535-47bb-0310-9956-ffa450edef68
17 files changed