)]}'
{
  "commit": "e38fe913f994ac20a7b9d0ea50c5e7b14b606fa3",
  "tree": "87409016176b2e4afed45e69ec75e0da064c67b7",
  "parents": [
    "aacf58c3babe3a6924757ece71e52d5b20fec6d4"
  ],
  "author": {
    "name": "Jordan Peck",
    "email": "jpeck@apache.org",
    "time": "Fri Jul 03 20:59:45 2026 +0000"
  },
  "committer": {
    "name": "Jordan Peck",
    "email": "jpeck@apache.org",
    "time": "Fri Jul 03 20:59:45 2026 +0000"
  },
  "message": "On the \u0027svnsync-atomic-author\u0027 branch:\n\nLet svnsync set svn:author and svn:date in the commit itself when the\ndestination supports it, instead of patching them up with a post-commit\nrevprop change. This makes mirroring a revision atomic for ra_local\ndestinations and removes the window where a mirrored revision briefly\ncarries the wrong author and date.\n\nSee discussion: https://lists.apache.org/thread/qnxqd4whjp62rk2pgndt8xyp40oqnom2\n\nIntroduce SVN_RA_CAPABILITY_COMMIT_PRESERVES_AUTHOR_DATE, advertised by\nra_local and wired through the standard capability negotiation for svn://\nand http:// so future servers can opt in without client changes. Rev the\nrepos-layer commit APIs to carry transaction flags (SVN_FS_TXN_CLIENT_DATE).\n\n* subversion/include/svn_ra.h\n  (SVN_RA_CAPABILITY_COMMIT_PRESERVES_AUTHOR_DATE): New capability.\n  (svn_ra_get_commit_editor3): Allow svn:author/svn:date in REVPROP_TABLE\n    when the session advertises the new capability.\n\n* subversion/include/svn_ra_svn.h\n  (SVN_RA_SVN_CAP_COMMIT_PRESERVES_AUTHOR_DATE): New wire capability.\n\n* subversion/include/svn_dav.h\n  (SVN_DAV_NS_DAV_SVN_COMMIT_PRESERVES_AUTHOR_DATE): New OPTIONS header token.\n\n* subversion/include/svn_repos.h\n  (svn_repos_get_commit_editor6, svn_repos_fs_begin_txn_for_commit3): New,\n    taking TXN_FLAGS.\n  (svn_repos_get_commit_editor5, svn_repos_fs_begin_txn_for_commit2):\n    Deprecate.\n\n* subversion/include/private/svn_repos_private.h\n  (svn_repos__get_commit_ev2): Take TXN_FLAGS.\n\n* subversion/libsvn_repos/commit.c\n  (edit_baton): Add TXN_FLAGS.\n  (open_root): Pass them to svn_repos_fs_begin_txn_for_commit3().\n  (svn_repos_get_commit_editor6, svn_repos__get_commit_ev2): Accept and\n    forward TXN_FLAGS.\n\n* subversion/libsvn_repos/fs-wrap.c\n  (svn_repos_fs_begin_txn_for_commit3): New revision of ..._commit2(),\n    OR-ing TXN_FLAGS into SVN_FS_TXN_CHECK_LOCKS.\n  (svn_repos_fs_begin_txn_for_commit): Move to deprecated.c.\n\n* subversion/libsvn_repos/deprecated.c\n  (svn_repos_get_commit_editor5, svn_repos_fs_begin_txn_for_commit2,\n   svn_repos_fs_begin_txn_for_commit): Implement as wrappers.\n\n* subversion/libsvn_ra_local/ra_plugin.c\n  (prepare_commit_revprops): New helper: default svn:author to the session\n    username only when absent, and request SVN_FS_TXN_CLIENT_DATE iff the\n * is committed; otherwise it will be overwritten with the commit\n *\n * @since New in 1.16.\n\n                                   svn_repos_t *repos,\nt32_t txn_flags,\n                                   apr_pool_t *pool);\n\n\n/** Like svn_repos_fs_begin_txn_for_commit3(), but with @a flags\n/** Like svn_repos_fs_begin_txn_for_commit3(), but with @a txn_flags\n * set to #SVN_FS_TXN_CHECK_LOCKS only.\n *\n * @note @a revprop_table may contain an #SVN_PROP_REVISION_DATE property,\n\n  Read 1 file\n\n● Update(subversion\\libsvn_repos\\fs-wrap.c)\nAdded 1 line, removed 1 line\n                                   svn_repos_t *repos,\n                                   svn_revnum_t rev,\n_t *pool)\n{\n  apr_array_header_t *revprops;\n\n● Update(subversion\\libsvn_repos\\fs-wrap.c)\nAdded 1 line, removed 1 line\n  /* Begin the transaction, ask for the fs to do on-the-fly lock checks.\n     We fetch its name, too, so the start-commit hook can use it.  */\n  SVN_ERR(svn_fs_begin_txn2(\u0026txn, repos-\u003efs, rev,\n                            SVN_FS_TXN_CHECK_LOCKS | flags, pool));\n                            SVN_FS_TXN_CHECK_LOCKS | txn_flags, poo\n  err \u003d svn_fs_txn_name(\u0026txn_name, txn, pool);\n  if (err)\n    return svn_error_compose_create(err, svn_fs_abort_txn(txn, pool));\n\nFix 5c — state commit_callback nullability on editor6 directly (replacing the stale pre-1.6 parenthetical):\n\n● Update(subversion\\include\\svn_repos.h)\nAdded 1 line, removed 2 lines\n * returns an error, that error will be returned from @c close_edit,\n * otherwise if there was a post-commit hook failure, then that error\n * will be returned with code SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED.\n * (Note that prior to Subversion 1.6, @a commit_callback cannot be @c NULL;\n * if you don\u0027t need a callback, pass a dummy function.)\n * @a commit_callback may be @c NULL.\n *\n * Calling @a (*editor)-\u003eabort_edit aborts the commit, and will also\n * abort the commit transaction unless @a txn was supplied (not @c\nYou\u0027ve hit your session limit · resets 9:50pm (Europe/London)\n/upgrade or /usage-credits to finish what you’re working on.\n\n✻ Baked for 5m 21s\n\n❯ Can you put together a brief commit message for this change\n\nHere\u0027s a commit message in the Apache Subversion log-message convention (summary paragraph plus per-file annotations), ready for svn commit -F:\n\nOn the \u0027svnsync-atomic-author\u0027 branch:\n\nLet svnsync set svn:author and svn:date in the commit itself when the\ndestination supports it, instead of patching them up with a post-commit\nrevprop change.  This makes mirroring a revision atomic for ra_local\ndestinations and removes the window where a mirrored revision briefly\nent changes.  Rev the\nrepos-layer commit APIs to carry transaction flags (SVN_FS_TXN_CLIENT_DATE).\n\n* subversion/include/svn_ra.h\n  (SVN_RA_CAPABILITY_COMMIT_PRESERVES_AUTHOR_DATE): New capability.\n  (svn_ra_get_commit_editor3): Allow svn:author/svn:date in REVPROP_TABLE\n    when the session advertises the new capability.\n\n* subversion/include/svn_ra_svn.h\n  (SVN_RA_SVN_CAP_COMMIT_PRESERVES_AUTHOR_DATE): New wire capability.\n\n* subversion/include/svn_dav.h\n  (SVN_DAV_NS_DAV_SVN_COMMIT_PRESERVES_AUTHOR_DATE): New OPTIONS header token.\n\n* subversion/include/svn_repos.h\n  (svn_repos_get_commit_editor6, svn_repos_fs_begin_txn_for_commit3): New,\n    taking TXN_FLAGS.\n  (svn_repos_get_commit_editor5, svn_repos_fs_begin_txn_for_commit2):\n\n* subversion/libsvn_repos/commit.c\n  (edit_baton): Add TXN_FLAGS.\n  (open_root): Pass them to svn_repos_fs_begin_txn_for_commit3().\n  (svn_repos_get_commit_editor6, svn_repos__get_commit_ev2): Accept and\n    forward TXN_FLAGS.\n\n* subversion/libsvn_repos/fs-wrap.c\n  (svn_repos_fs_begin_txn_for_commit3): New revision of ..._commit2(),\n    OR-ing TXN_FLAGS into SVN_FS_TXN_CHECK_LOCKS.\n  (svn_repos_fs_begin_txn_for_commit): Move to deprecated.c.\n\n* subversion/libsvn_repos/deprecated.c\n  (svn_repos_get_commit_editor5, svn_repos_fs_begin_txn_for_commit2,\n   svn_repos_fs_begin_txn_for_commit): Implement as wrappers.\n\n* subversion/libsvn_ra_local/ra_plugin.c\n\n  (svn_ra_local__get_commit_editor, svn_ra_local__get_commit_ev2): Use it.\n  (svn_ra_local__has_capability): Advertise the new capability.\n\n* subversion/libsvn_ra_svn/client.c\n  (ra_svn_has_capability): Map the new capability to its wire word.\n\n* subversion/libsvn_ra_serf/options.c\n  (capabilities_headers_iterator_callback, options_response_handler):\n    Parse and pre-seed the new capability.\n\n* subversion/mod_dav_svn/activity.c (dav_svn__create_txn),\n  subversion/mod_dav_svn/lock.c (append_locks),\n  subversion/svnserve/serve.c (commit):\n    Track the API revs; no functional change.\n\n* subversion/svnsync/svnsync.c\n once per sync how\n    revprops split between the commit and a follow-up revprop update.\n  (replay_rev_started, replay_rev_finished, do_synchronize): Use that\n    decision; skip the follow-up pass entirely when the commit carries\n    author/date.\n\n* subversion/tests/libsvn_repos/repos-test.c\n  (commit_add_file, commit_editor_preserve_revprops): New test for both\n    SVN_FS_TXN_CLIENT_DATE polarities via the commit editor.\n\n* subversion/tests/cmdline/svnsync_tests.py\n  (sync_to_local_preserves_author_date): New test: an ra_local sync\n    preserves author/date with no post-commit revprop copy.\n\ngit-svn-id: https://svn.apache.org/repos/asf/subversion/branches/svnsync-atomic-author@1935862 13f79535-47bb-0310-9956-ffa450edef68\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "f80100ac56c1fa2e8d37d09891ccfd75af00f43b",
      "old_mode": 33188,
      "old_path": "subversion/include/private/svn_repos_private.h",
      "new_id": "3b64b7487364ff365edbdd6b27917d153158c004",
      "new_mode": 33188,
      "new_path": "subversion/include/private/svn_repos_private.h"
    },
    {
      "type": "modify",
      "old_id": "9af9bc58f7edbece1c72ec139b543733c639c32e",
      "old_mode": 33188,
      "old_path": "subversion/include/svn_dav.h",
      "new_id": "dfbcd42829659294e44707ee8a50407294ec11ac",
      "new_mode": 33188,
      "new_path": "subversion/include/svn_dav.h"
    },
    {
      "type": "modify",
      "old_id": "b1e07297adc8fd6d2affac8fdac8d41ffe920b7a",
      "old_mode": 33188,
      "old_path": "subversion/include/svn_ra.h",
      "new_id": "2ab289afd2df9376647329ae89b344dd4d75605e",
      "new_mode": 33188,
      "new_path": "subversion/include/svn_ra.h"
    },
    {
      "type": "modify",
      "old_id": "0bcd40b7aee031f3eef2115d6131f3c68fe0185c",
      "old_mode": 33188,
      "old_path": "subversion/include/svn_ra_svn.h",
      "new_id": "c41dbfe81ae3976303724d03576f93a8fa2bed9c",
      "new_mode": 33188,
      "new_path": "subversion/include/svn_ra_svn.h"
    },
    {
      "type": "modify",
      "old_id": "947b22dac32f2c9d242047a0898b167937444437",
      "old_mode": 33188,
      "old_path": "subversion/include/svn_repos.h",
      "new_id": "31a43732bcf8b8dfab7cb168d1dae0a2d4164205",
      "new_mode": 33188,
      "new_path": "subversion/include/svn_repos.h"
    },
    {
      "type": "modify",
      "old_id": "0c86a7e17bf3ce99ed07ae935254ca4ffcfd179e",
      "old_mode": 33188,
      "old_path": "subversion/libsvn_ra_local/ra_plugin.c",
      "new_id": "5948a1f9ad1a8b863bf5ce4f43d608ddb4386bd1",
      "new_mode": 33188,
      "new_path": "subversion/libsvn_ra_local/ra_plugin.c"
    },
    {
      "type": "modify",
      "old_id": "a3d321a64715f3fbacfe58b151bc66e5efe97f45",
      "old_mode": 33188,
      "old_path": "subversion/libsvn_ra_serf/options.c",
      "new_id": "4876d969b4e2dc4e7355b1e9fbe1b5b2c7368ff7",
      "new_mode": 33188,
      "new_path": "subversion/libsvn_ra_serf/options.c"
    },
    {
      "type": "modify",
      "old_id": "8f90dc64932091637ff7ac5a1b220827785e5bbc",
      "old_mode": 33188,
      "old_path": "subversion/libsvn_ra_svn/client.c",
      "new_id": "16244ad7b3d293fdbc1172912070729fa3918ed3",
      "new_mode": 33188,
      "new_path": "subversion/libsvn_ra_svn/client.c"
    },
    {
      "type": "modify",
      "old_id": "486dedd0928c52581affc2d2365e98919e9439be",
      "old_mode": 33188,
      "old_path": "subversion/libsvn_repos/commit.c",
      "new_id": "f5a6e6f4e8a42c41601131756361a89978fdfb04",
      "new_mode": 33188,
      "new_path": "subversion/libsvn_repos/commit.c"
    },
    {
      "type": "modify",
      "old_id": "7ca0e17120f0a1e03e9159dd666d05450e2f3577",
      "old_mode": 33188,
      "old_path": "subversion/libsvn_repos/deprecated.c",
      "new_id": "0748d2c469710dc00c975fd1b429c2139c2cda6c",
      "new_mode": 33188,
      "new_path": "subversion/libsvn_repos/deprecated.c"
    },
    {
      "type": "modify",
      "old_id": "c5cecdc56c842356fde1f07a94064d54907f2e6d",
      "old_mode": 33188,
      "old_path": "subversion/libsvn_repos/fs-wrap.c",
      "new_id": "edd6835ffe95935a9a5c9c13c10c09bc65e86004",
      "new_mode": 33188,
      "new_path": "subversion/libsvn_repos/fs-wrap.c"
    },
    {
      "type": "modify",
      "old_id": "4020a09bda914c3a441840844c6095fd7d97f492",
      "old_mode": 33188,
      "old_path": "subversion/mod_dav_svn/activity.c",
      "new_id": "71bab28fea77009e92eafa9de98884e69df75f7a",
      "new_mode": 33188,
      "new_path": "subversion/mod_dav_svn/activity.c"
    },
    {
      "type": "modify",
      "old_id": "d2a6aa9021e270a08ef0da02c31a40b68648ed84",
      "old_mode": 33188,
      "old_path": "subversion/mod_dav_svn/lock.c",
      "new_id": "7856cf71e76e260436a6afb8b07f9aca93df35f1",
      "new_mode": 33188,
      "new_path": "subversion/mod_dav_svn/lock.c"
    },
    {
      "type": "modify",
      "old_id": "005f4e5daa4ab14a679f3e956a283237495e3ea8",
      "old_mode": 33188,
      "old_path": "subversion/svnserve/serve.c",
      "new_id": "b846697151e267a8080f86497e1d0bdd5e1f5b4f",
      "new_mode": 33188,
      "new_path": "subversion/svnserve/serve.c"
    },
    {
      "type": "modify",
      "old_id": "32aa64b6f6de637a2becaf7815c2756117bde61f",
      "old_mode": 33188,
      "old_path": "subversion/svnsync/svnsync.c",
      "new_id": "85885442a6f4cab5c1793e0118147b29283660a9",
      "new_mode": 33188,
      "new_path": "subversion/svnsync/svnsync.c"
    },
    {
      "type": "modify",
      "old_id": "79dfbbf00b176ad1e65751c972adc2eaef319e78",
      "old_mode": 33261,
      "old_path": "subversion/tests/cmdline/svnsync_tests.py",
      "new_id": "381e1a53ae80ed3eb809d4b264610e2f52706c65",
      "new_mode": 33261,
      "new_path": "subversion/tests/cmdline/svnsync_tests.py"
    },
    {
      "type": "modify",
      "old_id": "7017ecb922a0c4096ce7f9c378c8d10b6827cb55",
      "old_mode": 33188,
      "old_path": "subversion/tests/libsvn_repos/repos-test.c",
      "new_id": "bf7f1984f7a3d972fb6b874fda8d7d059adcaf81",
      "new_mode": 33188,
      "new_path": "subversion/tests/libsvn_repos/repos-test.c"
    }
  ]
}
