)]}'
{
  "commit": "675415976704459edaf8fb39a176be2be0f403d8",
  "tree": "adb5d060b5a4aedb6f335adbc08f1360eb01ee5a",
  "parents": [
    "101b3204f37606972b40fc17dec84560c22f69f6"
  ],
  "author": {
    "name": "Patrick Steinhardt",
    "email": "ps@pks.im",
    "time": "Fri Jun 19 08:56:14 2020 +0200"
  },
  "committer": {
    "name": "Junio C Hamano",
    "email": "gitster@pobox.com",
    "time": "Fri Jun 19 10:46:13 2020 -0700"
  },
  "message": "refs: implement reference transaction hook\n\nThe low-level reference transactions used to update references are\ncurrently completely opaque to the user. While certainly desirable in\nmost usecases, there are some which might want to hook into the\ntransaction to observe all queued reference updates as well as observing\nthe abortion or commit of a prepared transaction.\n\nOne such usecase would be to have a set of replicas of a given Git\nrepository, where we perform Git operations on all of the repositories\nat once and expect the outcome to be the same in all of them. While\nthere exist hooks already for a certain subset of Git commands that\ncould be used to implement a voting mechanism for this, many others\ncurrently don\u0027t have any mechanism for this.\n\nThe above scenario is the motivation for the new \"reference-transaction\"\nhook that reaches directly into Git\u0027s reference transaction mechanism.\nThe hook receives as parameter the current state the transaction was\nmoved to (\"prepared\", \"committed\" or \"aborted\") and gets via its\nstandard input all queued reference updates. While the exit code gets\nignored in the \"committed\" and \"aborted\" states, a non-zero exit code in\nthe \"prepared\" state will cause the transaction to be aborted\nprematurely.\n\nGiven the usecase described above, a voting mechanism can now be\nimplemented via this hook: as soon as it gets called, it will take all\nof stdin and use it to cast a vote to a central service. When all\nreplicas of the repository agree, the hook will exit with zero,\notherwise it will abort the transaction by returning non-zero. The most\nimportant upside is that this will catch _all_ commands writing\nreferences at once, allowing to implement strong consistency for\nreference updates via a single mechanism.\n\nIn order to test the impact on the case where we don\u0027t have any\n\"reference-transaction\" hook installed in the repository, this commit\nintroduce two new performance tests for git-update-refs(1). Run against\nan empty repository, it produces the following results:\n\n  Test                         origin/master     HEAD\n  --------------------------------------------------------------------\n  1400.2: update-ref           2.70(2.10+0.71)   2.71(2.10+0.73) +0.4%\n  1400.3: update-ref --stdin   0.21(0.09+0.11)   0.21(0.07+0.14) +0.0%\n\nThe performance test p1400.2 creates, updates and deletes a branch a\nthousand times, thus averaging runtime of git-update-refs over 3000\ninvocations. p1400.3 instead calls `git-update-refs --stdin` three times\nand queues a thousand creations, updates and deletes respectively.\n\nAs expected, p1400.3 consistently shows no noticeable impact, as for\neach batch of updates there\u0027s a single call to access(3P) for the\nnegative hook lookup. On the other hand, for p1400.2, one can see an\nimpact caused by this patchset. But doing five runs of the performance\ntests where each one was run with GIT_PERF_REPEAT_COUNT\u003d10, the overhead\nranged from -1.5% to +1.1%. These inconsistent performance numbers can\nbe explained by the overhead of spawning 3000 processes. This shows that\nthe overhead of assembling the hook path and executing access(3P) once\nto check if it\u0027s there is mostly outweighed by the operating system\u0027s\noverhead.\n\nSigned-off-by: Patrick Steinhardt \u003cps@pks.im\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "81f2a87e88ba5fee51419b615a60352a8dd3c999",
      "old_mode": 33188,
      "old_path": "Documentation/githooks.txt",
      "new_id": "642471109f70c202ce214b4b3dd2b3fd7aa98c69",
      "new_mode": 33188,
      "new_path": "Documentation/githooks.txt"
    },
    {
      "type": "modify",
      "old_id": "224ff66c7bb0ef587cf2b34763586f53ad73bd84",
      "old_mode": 33188,
      "old_path": "refs.c",
      "new_id": "f05295f50300b6ce7261fa65c6a9e0af221a20b3",
      "new_mode": 33188,
      "new_path": "refs.c"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "d275a81248b04adaab5e37ea20504a82d572e649",
      "new_mode": 33261,
      "new_path": "t/perf/p1400-update-ref.sh"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "da58d867a56f57360c7090bced0911350bc5fef0",
      "new_mode": 33261,
      "new_path": "t/t1416-ref-transaction-hooks.sh"
    }
  ]
}
