)]}'
{
  "log": [
    {
      "commit": "1ff279f3404a482a83fb04c7457e41ab26884aea",
      "tree": "9ae99a55b2ff5e78314eed78714accf8e5dd5148",
      "parents": [
        "18b6502b3a0036a53cfa707e5a360374c47b8797"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Jun 09 10:04:31 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Jun 09 10:04:51 2026 +0900"
      },
      "message": "The 13th batch\n\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "18b6502b3a0036a53cfa707e5a360374c47b8797",
      "tree": "0f582605132ac128ccfdc64328215ce71658bb40",
      "parents": [
        "4d96a1280b49b210c1080742c1363209e577fef4",
        "7c9b38d267129625adeced9f66140e802c345261"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Jun 09 10:04:51 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Jun 09 10:04:51 2026 +0900"
      },
      "message": "Merge branch \u0027jc/doc-monitor-ghci\u0027\n\nEncourage original authors to monitor the CI status.\n\n* jc/doc-monitor-ghci:\n  SubmittingPatches: proactively monitor GHCI pages\n"
    },
    {
      "commit": "4d96a1280b49b210c1080742c1363209e577fef4",
      "tree": "535ec854fb261bec82a883a268067c6a6685e158",
      "parents": [
        "a58e51dddfa75d74ec7897ab98b2e47244a6a79b",
        "b2040bfafe0f7bbbd21cf65a903d2346d602f421"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Jun 09 10:04:51 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Jun 09 10:04:51 2026 +0900"
      },
      "message": "Merge branch \u0027ib/doc-push-default-simple\u0027\n\nThe documentation for `push.default \u003d simple` has been clarified to\nbetter explain its behavior, making it clear that it pushes the\ncurrent branch to a same-named branch on the remote, and detailing\nthe upstream requirements for centralized workflows.\n\n* ib/doc-push-default-simple:\n  doc: clarify push.default\u003dsimple behavior\n"
    },
    {
      "commit": "a58e51dddfa75d74ec7897ab98b2e47244a6a79b",
      "tree": "4f8ac254502b3bdf6df7ab5f1343979f7a420f77",
      "parents": [
        "2fd113ae07212081d425f67cb8f03b604d7c6b81",
        "74216ffe0aa02309e1fc510c0056ec6fd523898c"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Jun 09 10:04:50 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Jun 09 10:04:51 2026 +0900"
      },
      "message": "Merge branch \u0027gh/jump-auto-mode\u0027\n\nThe \u0027git-jump\u0027 command (in contrib/) has been taught to automatically\npick a mode (merge, diff, or ws) when invoked without arguments.\n\n* gh/jump-auto-mode:\n  git-jump: pick a mode automatically when invoked without arguments\n"
    },
    {
      "commit": "2fd113ae07212081d425f67cb8f03b604d7c6b81",
      "tree": "32067fe2252f119ca3fef96d9fb3e4e5e1a7d433",
      "parents": [
        "7eaa3c82a850847b52a9450740c28644f4d15b77",
        "63621bcbba81a131794d510bcedfa08d9318219c"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Jun 09 10:04:50 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Jun 09 10:04:50 2026 +0900"
      },
      "message": "Merge branch \u0027rs/strbuf-add-oid-hex\u0027\n\nFormatting object name in full hexadecimal form has been optimized\nby using a new strbuf_add_oid_hex() helper function.\n\n* rs/strbuf-add-oid-hex:\n  hex: add and use strbuf_add_oid_hex()\n"
    },
    {
      "commit": "7eaa3c82a850847b52a9450740c28644f4d15b77",
      "tree": "67b295a080e92a7b5761529d29dc88e26991bfa1",
      "parents": [
        "2c677d20b684cdcae669fe508d4cd60fea8cb320",
        "4f87748b0d25bdc92b76e453f086204808e8be87"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Jun 09 10:04:50 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Jun 09 10:04:50 2026 +0900"
      },
      "message": "Merge branch \u0027rs/strbuf-add-uint\u0027\n\nAdding a decimal integer with strbuf_addf(\"%u\") appears commonly;\nthey have been optimized by using a custom formatter.\n\n* rs/strbuf-add-uint:\n  ls-tree: use strbuf_add_uint()\n  ls-files: use strbuf_add_uint()\n  cat-file: use strbuf_add_uint()\n  strbuf: add strbuf_add_uint()\n"
    },
    {
      "commit": "2c677d20b684cdcae669fe508d4cd60fea8cb320",
      "tree": "92eea805b86bc08c0f004235fe3dda78398e3544",
      "parents": [
        "fca09c8fc2ccd1478cef1263b773424a0d42091c",
        "8ea82816652d20ac7070a8fcd60980568a8a293c"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Jun 09 10:04:50 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Jun 09 10:04:50 2026 +0900"
      },
      "message": "Merge branch \u0027ua/push-remote-group\u0027\n\n\"git push\" learned to take a \"remote group\" name to push to, which\ncauses pushes to multiple places, just like \"git fetch\" would do.\n\n* ua/push-remote-group:\n  push: support pushing to a remote group\n  remote: move remote group resolution to remote.c\n  remote: fix sign-compare warnings in push_cas_option\n"
    },
    {
      "commit": "fca09c8fc2ccd1478cef1263b773424a0d42091c",
      "tree": "1a88137abd188c28c42ce190ead0d0bc6a2b248a",
      "parents": [
        "1c0af131cc139f1b47bd14ead50688f50e95ef44",
        "fa1468a1f7c7765a6c7dd1faca4c9dc241d0538c"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Jun 09 10:04:49 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Jun 09 10:04:50 2026 +0900"
      },
      "message": "Merge branch \u0027th/promisor-quiet-per-repo\u0027\n\nThe \"promisor.quiet\" configuration variable was not used from\nrelevant submodules when commands like \"grep --recurse-submodules\"\ntriggered a lazy fetch, which has been corrected.\n\n* th/promisor-quiet-per-repo:\n  promisor-remote: fix promisor.quiet to use the correct repository\n"
    },
    {
      "commit": "1c0af131cc139f1b47bd14ead50688f50e95ef44",
      "tree": "91eda77a609ded7e93cc25d27a951f38dc2008fe",
      "parents": [
        "600fe743028cbfb640855f659e9851522214bc0b",
        "49633dc88c14008f9a405f215b60994362b36d6c"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Jun 09 10:04:49 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Jun 09 10:04:49 2026 +0900"
      },
      "message": "Merge branch \u0027tb/bitmap-build-performance\u0027\n\nReachability bitmap generation has been significantly optimized. By\nreordering tree traversal, caching object positions, and refining how\npseudo-merge bitmaps are constructed, the performance of \"git repack\n--write-midx-bitmaps\" is improved, especially for large repositories\nand when using pseudo-merges.\n\n* tb/bitmap-build-performance:\n  pack-bitmap: build pseudo-merge bitmaps after regular bitmaps\n  pack-bitmap: remember pseudo-merge parents\n  pack-bitmap: sort bitmaps before XORing\n  pack-bitmap: cache object positions during fill\n  pack-bitmap: consolidate `find_object_pos()` success path\n  pack-bitmap: reuse stored selected bitmaps\n  pack-bitmap: check subtree bits before recursing\n  pack-bitmap: pass object position to `fill_bitmap_tree()`\n"
    },
    {
      "commit": "600fe743028cbfb640855f659e9851522214bc0b",
      "tree": "f0923c220ad543f97637a598578ca10467219d3a",
      "parents": [
        "212d25596df20c48f3c1284999378d972f69a7b3"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun Jun 07 23:58:12 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun Jun 07 23:58:25 2026 +0900"
      },
      "message": "The 12th batch\n\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "212d25596df20c48f3c1284999378d972f69a7b3",
      "tree": "4b000bb4e0ee2f77496fdfd93d36388302e84b81",
      "parents": [
        "6390da42c728af2a1b2bfd32a8195c0f1c6f89cd",
        "2ef248ae45bdcfbb027108bf87fcc3375cb5daba"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun Jun 07 23:58:25 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun Jun 07 23:58:25 2026 +0900"
      },
      "message": "Merge branch \u0027ja/doc-synopsis-style-again\u0027\n\nA batch of documentation pages has been updated to use the modern\nsynopsis style.\n\n* ja/doc-synopsis-style-again:\n  doc: convert git-imap-send synopsis and options to new style\n  doc: convert git-apply synopsis and options to new style\n  doc: convert git-am synopsis and options to new style\n  doc: convert git-grep synopsis and options to new style\n  doc: git bisect: clarify the usage of the synopsis vs actual command\n  doc: convert git-bisect to synopsis style\n"
    },
    {
      "commit": "6390da42c728af2a1b2bfd32a8195c0f1c6f89cd",
      "tree": "8a195be0c06952938b8bf0027041c8e9306d1ee7",
      "parents": [
        "de5383c2ce2f8ae20107e10fbc72d3425c1fe43b",
        "a186b7797a8bd4b9ca09b9cb326a2dccee00f90e"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun Jun 07 23:58:25 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun Jun 07 23:58:25 2026 +0900"
      },
      "message": "Merge branch \u0027kk/commit-reach-optim\u0027\n\nThe check for non-stale commits in the priority queue used by\n`paint_down_to_common` and `ahead_behind` has been optimized by\nreplacing an O(N) scan with an O(1) counter, yielding performance\nimprovements in repositories with wide histories.\n\n* kk/commit-reach-optim:\n  commit-reach: replace queue_has_nonstale() scan with O(1) tracking\n  commit-reach: deduplicate queue entries in paint_down_to_common\n  object.h: fix stale entries in object flag allocation table\n"
    },
    {
      "commit": "de5383c2ce2f8ae20107e10fbc72d3425c1fe43b",
      "tree": "f6afeb947e4133903b536f2ecc3c1711505c950d",
      "parents": [
        "92b870a675b40ca4c318db889ab876ea6f9c4b9f",
        "48513e05e2f226c85a9b88893630c8ae28409772"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun Jun 07 23:58:24 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun Jun 07 23:58:25 2026 +0900"
      },
      "message": "Merge branch \u0027aj/stash-patch-optimize-temporary-index\u0027\n\n\"git stash -p\" has been optimized by reusing cached index\nentries in its temporary index, avoiding unnecessary lstat()\ncalls on unchanged files.\n\n* aj/stash-patch-optimize-temporary-index:\n  stash: reuse cached index entries in --patch temporary index\n"
    },
    {
      "commit": "92b870a675b40ca4c318db889ab876ea6f9c4b9f",
      "tree": "b7107af82f51ddf7f25d7af9b7bbdc95b8d9109e",
      "parents": [
        "7450009e6f3a05f742682e923726404034aed4c0",
        "83e7f3bd2bac934c21f39175b965c37810a41ea5"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun Jun 07 23:58:24 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun Jun 07 23:58:24 2026 +0900"
      },
      "message": "Merge branch \u0027kh/free-commit-list\u0027\n\nCode clean-up.\n\n* kh/free-commit-list:\n  commit: remove deprecated functions\n  *: replace deprecated free_commit_list\n"
    },
    {
      "commit": "7450009e6f3a05f742682e923726404034aed4c0",
      "tree": "e510c42b7d9f4f3f89421b1f592b32af27e993fa",
      "parents": [
        "17204228cf658e4766d16fdab26266677541496c",
        "105aacd072e41c55948d016b46f86f75db2487b3"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun Jun 07 23:58:24 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun Jun 07 23:58:24 2026 +0900"
      },
      "message": "Merge branch \u0027ds/restore-sparse-index\u0027\n\n\u0027git restore --staged\u0027 has been optimized to avoid unnecessarily expanding\nthe sparse index when operating on paths within the sparse checkout\ndefinition, by handling sparse directory entries at the tree level.\n\n* ds/restore-sparse-index:\n  restore: avoid sparse index expansion\n  t1092: test \u0027git restore\u0027 with sparse index\n"
    },
    {
      "commit": "17204228cf658e4766d16fdab26266677541496c",
      "tree": "0cc1f13663ba0323934c53f03d43ef849cd98ceb",
      "parents": [
        "9ac3f193c05c2237e2b14ebaa1149e9fc8a1abe0",
        "44d04e442683b53ed618b74861f056f93fcbd783"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun Jun 07 23:58:24 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun Jun 07 23:58:24 2026 +0900"
      },
      "message": "Merge branch \u0027ar/receive-pack-worktree-env\u0027\n\nThe GIT_WORK_TREE variable prepared to invoke the push-to-checkout\nhook was leaking into the environment even when there was no hook\nused and broke the default push-to-deploy (i.e., let \"git checkout\"\nupdate the working tree only when the working tree is clean).\n\n* ar/receive-pack-worktree-env:\n  receive-pack: fix updateInstead with core.worktree\n"
    },
    {
      "commit": "9ac3f193c05c2237e2b14ebaa1149e9fc8a1abe0",
      "tree": "2f0008c0002043dfed547993d8df485889725ba7",
      "parents": [
        "95e5fbd0efb6816101eea283837db43ac61241d9"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Jun 02 12:48:59 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Jun 02 16:15:29 2026 +0900"
      },
      "message": "The 11th batch\n\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "95e5fbd0efb6816101eea283837db43ac61241d9",
      "tree": "99abf6c6845477f4e957661f157ac330033b9dd2",
      "parents": [
        "ffaa2eddd07afa5a86daaf0f9fd8838fb283dc2d",
        "5c6a41e4b5b60ea397393fb0542c7d67553a105e"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Jun 02 16:15:29 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Jun 02 16:15:29 2026 +0900"
      },
      "message": "Merge branch \u0027kh/doc-hook\u0027\n\nDoc updates.\n\n* kh/doc-hook:\n  doc: hook: don’t self-link via config include\n  doc: config: include existing git-hook(1) section\n  doc: hook: consistently capitalize Git\n  doc: hook: remove stray backtick\n"
    },
    {
      "commit": "ffaa2eddd07afa5a86daaf0f9fd8838fb283dc2d",
      "tree": "b9423237a268c1e0a20d32bc690335987104094b",
      "parents": [
        "15dc60dcd1410a01b5e30b018895c3bd454735e5",
        "456efac53b088759abdadb6a33fa9bebdd9945b7"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Jun 02 16:15:29 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Jun 02 16:15:29 2026 +0900"
      },
      "message": "Merge branch \u0027ds/path-walk-filters\u0027\n\nThe \"git pack-objects --path-walk\" traversal has been integrated\nwith several object filters, including blobless and sparse filters.\n\n* ds/path-walk-filters:\n  path-walk: support `combine` filter\n  path-walk: support `object:type` filter\n  path-walk: support `tree:0` filter\n  t6601: tag otherwise-unreachable trees\n  pack-objects: support sparse:oid filter with path-walk\n  path-walk: add pl_sparse_trees to control tree pruning\n  path-walk: support blob size limit filter\n  backfill: die on incompatible filter options\n  path-walk: support blobless filter\n  path-walk: always emit directly-requested objects\n  t/perf: add pack-objects filter and path-walk benchmark\n  pack-objects: pass --objects with --path-walk\n  t5620: make test work with path-walk var\n"
    },
    {
      "commit": "15dc60dcd1410a01b5e30b018895c3bd454735e5",
      "tree": "8efa699ad061ff5bf660dc62e5363b7d1a6c561b",
      "parents": [
        "7b3ab91768047cb9e51482d6f3d4797db11bcfe2",
        "b809304101635d0fafc7644e82704ae653cacb07"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Jun 02 16:15:29 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Jun 02 16:15:29 2026 +0900"
      },
      "message": "Merge branch \u0027ta/approxidate-noon-fix\u0027\n\n\"Friday noon\" asked in the morning on Sunday was parsed to be one\nday before the specified time, which has been corrected.\n\n* ta/approxidate-noon-fix:\n  approxidate: use deferred mday adjustments for \"specials\"\n  approxidate: make \"specials\" respect fixed day-of-month\n  t0006: add support for approxidate test date adjustment\n  approxidate: make \"today\" wrap to midnight\n"
    },
    {
      "commit": "7b3ab91768047cb9e51482d6f3d4797db11bcfe2",
      "tree": "109123fc9beab4fb9ac3a50c41da3d3b7e828c63",
      "parents": [
        "1666c1265231b0bc5f613fbbf3f0a9896cdef76e",
        "abcf2dd5b215ff7bad0bb44524f352cd352bda0f"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Jun 02 16:15:28 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Jun 02 16:15:28 2026 +0900"
      },
      "message": "Merge branch \u0027jk/connect-service-enum\u0027\n\nThe \"name\" argument in git_connect() and related functions has been\nconverted to a \"service\" enum to improve type safety and clarify its\npurpose.\n\n* jk/connect-service-enum:\n  transport-helper: fix typo in BUG() message\n  connect: use \"service\" enum for \"name\" argument\n"
    },
    {
      "commit": "1666c1265231b0bc5f613fbbf3f0a9896cdef76e",
      "tree": "7ecdda836137e1639abf1dcb88be154fc6943e8c",
      "parents": [
        "25d6fff5946249d2ed0c71ec7605c3e81678f6cc"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 31 10:00:11 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 31 10:00:39 2026 +0900"
      },
      "message": "The 10th batch\n\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "25d6fff5946249d2ed0c71ec7605c3e81678f6cc",
      "tree": "28b9cd4965b7898221446d0442d41b67d673de07",
      "parents": [
        "a096b19c57ec5cc7f5dcf823dce4e5524f701ebe",
        "f4d7eb3d1c5e5d5fcbfeebd93e214bba35186868"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 31 10:00:39 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 31 10:00:39 2026 +0900"
      },
      "message": "Merge branch \u0027sp/doc-range-diff-takes-notes\u0027\n\nDocfix.\n\n* sp/doc-range-diff-takes-notes:\n  Documentation/git-range-diff: add missing notes options in synopsis\n"
    },
    {
      "commit": "a096b19c57ec5cc7f5dcf823dce4e5524f701ebe",
      "tree": "4268befe48b893d5c9ac02a4c76cac0ca1e10173",
      "parents": [
        "33da2f4d3b95a241030d2df7ff7022bc002fb6c1",
        "62319b49bbe7e52df2cf90d8c4a5121112135784"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 31 10:00:38 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 31 10:00:39 2026 +0900"
      },
      "message": "Merge branch \u0027ps/gitlab-ci-macOS-improvements\u0027\n\nUpdate GitLab CI jobs that exercise macOS.\n\n* ps/gitlab-ci-macOS-improvements:\n  gitlab-ci: update macOS image\n  gitlab-ci: upgrade macOS runners\n"
    },
    {
      "commit": "33da2f4d3b95a241030d2df7ff7022bc002fb6c1",
      "tree": "42b932cb2fa48328935ab39af9b1332cc9b1f1e6",
      "parents": [
        "f6c8fe189b698845caa3c553bcffa226642948d5",
        "6da647d8522641f932528de0167413719a38a2c0"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 31 10:00:38 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 31 10:00:38 2026 +0900"
      },
      "message": "Merge branch \u0027sa/cat-file-batch-mailmap-switch\u0027\n\n\"git cat-file --batch\" learns an in-line command \"mailmap\"\nthat lets the user toggle use of mailmap.\n\n* sa/cat-file-batch-mailmap-switch:\n  cat-file: add mailmap subcommand to --batch-command\n"
    },
    {
      "commit": "f6c8fe189b698845caa3c553bcffa226642948d5",
      "tree": "3476c4b14d343e169ccbac5c7c126e47e017bd3f",
      "parents": [
        "4d11b9c21863c1a860fdf61a9066f0d94c0d692a",
        "3d8e4004c604b206d70240a087816907cce70a08"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 31 10:00:38 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 31 10:00:38 2026 +0900"
      },
      "message": "Merge branch \u0027jk/commit-graph-lazy-load-fallback\u0027\n\nThe logic to lazy-load trees from the commit-graph has been made\nmore robust by falling back to reading the commit object when\nthe commit-graph is no longer available.\n\n* jk/commit-graph-lazy-load-fallback:\n  commit: fall back to full read when maybe_tree is NULL\n"
    },
    {
      "commit": "4d11b9c21863c1a860fdf61a9066f0d94c0d692a",
      "tree": "08c07cf9448eb306305999ee9a65de0fc069b266",
      "parents": [
        "7af2503365b4bc683c16e667b88c0796d6d9d2ee",
        "b1cebd7194299ad5414ab2122b2970b339399446"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 31 10:00:38 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 31 10:00:38 2026 +0900"
      },
      "message": "Merge branch \u0027pt/fsmonitor-linux\u0027\n\nThe fsmonitor daemon has been implemented for Linux.\n\n* pt/fsmonitor-linux:\n  fsmonitor: convert shown khash to strset in do_handle_client\n  fsmonitor: add tests for Linux\n  fsmonitor: add timeout to daemon stop command\n  fsmonitor: close inherited file descriptors and detach in daemon\n  run-command: add close_fd_above_stderr option\n  fsmonitor: implement filesystem change listener for Linux\n  fsmonitor: rename fsm-settings-darwin.c to fsm-settings-unix.c\n  fsmonitor: rename fsm-ipc-darwin.c to fsm-ipc-unix.c\n  fsmonitor: use pthread_cond_timedwait for cookie wait\n  compat/win32: add pthread_cond_timedwait\n  fsmonitor: fix hashmap memory leak in fsmonitor_run_daemon\n  fsmonitor: fix khash memory leak in do_handle_client\n  t9210, t9211: disable GIT_TEST_SPLIT_INDEX for scalar clone tests\n"
    },
    {
      "commit": "7af2503365b4bc683c16e667b88c0796d6d9d2ee",
      "tree": "944678708ee16d99e7b66d84b4227aea6850ca71",
      "parents": [
        "d2c01318b0f04c568808072c5b328e8021b94530",
        "9bab3ce5553b2333b8f8ee1aff27a9fe6a938f65"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 31 10:00:37 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 31 10:00:38 2026 +0900"
      },
      "message": "Merge branch \u0027ps/graph-lane-limit\u0027\n\nThe graph output from commands like \"git log --graph\" can now be\nlimited to a specified number of lanes, preventing overly wide output\nin repositories with many branches.\n\n* ps/graph-lane-limit:\n  graph: add truncation mark to capped lanes\n  graph: add --graph-lane-limit option\n  graph: limit the graph width to a hard-coded max\n"
    },
    {
      "commit": "d2c01318b0f04c568808072c5b328e8021b94530",
      "tree": "5d9fcb34bf71585a8cc0ed1e347e37faa4de44f8",
      "parents": [
        "1694d2bba576f330180be7fc8487e74a2925f4a5",
        "cb559918253d636dc00afa8cb468a810c1f4347b"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 31 10:00:37 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 31 10:00:37 2026 +0900"
      },
      "message": "Merge branch \u0027jr/bisect-custom-terms-in-output\u0027\n\n\"git bisect\" now uses the selected terms (e.g., old/new) more\nconsistently in its output.\n\n* jr/bisect-custom-terms-in-output:\n  rev-parse: use selected alternate terms to look up refs\n  bisect: print bisect terms in single quotes\n  bisect: use selected alternate terms in status output\n"
    },
    {
      "commit": "1694d2bba576f330180be7fc8487e74a2925f4a5",
      "tree": "19370a239e525c2b1fda658af65227a0d69b0f4b",
      "parents": [
        "a0ce168def3e141ddc79ac01f51455bf9bb633ea",
        "088d9a1716c2b8cd31bf504371fd677fde1dddb1"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 31 10:00:37 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 31 10:00:37 2026 +0900"
      },
      "message": "Merge branch \u0027tc/generate-configlist-fix-for-older-ninja\u0027\n\nBuild update.\n\n* tc/generate-configlist-fix-for-older-ninja:\n  generate-configlist: collapse depfile for older Ninja\n"
    },
    {
      "commit": "a0ce168def3e141ddc79ac01f51455bf9bb633ea",
      "tree": "e9995d0a64edb63e1a40095e15e76e61f1daf17a",
      "parents": [
        "e6a641e8a129c75770ecea3e453f69e66b9ea569",
        "a30f132bcb62bc44053b1dba0940c2d4041c797a"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 31 10:00:37 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 31 10:00:37 2026 +0900"
      },
      "message": "Merge branch \u0027kk/tips-reachable-from-bases-optim\u0027\n\nRevision traversal optimization.\n\n* kk/tips-reachable-from-bases-optim:\n  t6600: add tests for duplicate tips in tips_reachable_from_bases()\n  commit-reach: use object flags for tips_reachable_from_bases()\n"
    },
    {
      "commit": "e6a641e8a129c75770ecea3e453f69e66b9ea569",
      "tree": "8aaf48eb5a2e0f872c14cc601928b3500f07f9ee",
      "parents": [
        "e9068a5b000b22e522c7bd5690e2857c7727bf79",
        "1740cc35d0cc7d21b0eeb8bc7d2898b739d10784"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 31 10:00:36 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 31 10:00:37 2026 +0900"
      },
      "message": "Merge branch \u0027ed/check-connected-close-err-fd\u0027\n\nFile descriptor leak fix.\n\n* ed/check-connected-close-err-fd:\n"
    },
    {
      "commit": "e9068a5b000b22e522c7bd5690e2857c7727bf79",
      "tree": "8aaf48eb5a2e0f872c14cc601928b3500f07f9ee",
      "parents": [
        "c69baaf57ba26cf117c2b6793802877f19738b0d",
        "d9982e829069afeae191254c5ad63d465ec7dade"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 31 10:00:36 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 31 10:00:36 2026 +0900"
      },
      "message": "Merge branch \u0027ed/check-connected-close-err-fd-2.53\u0027\n\nFile descriptor leak fix (for 2.54 maintenance track).\n\n* ed/check-connected-close-err-fd-2.53:\n  connected: close err_fd in promisor fast-path\n"
    },
    {
      "commit": "83e7f3bd2bac934c21f39175b965c37810a41ea5",
      "tree": "60f590d31dce37693d538e54167587c9a9ab8278",
      "parents": [
        "7dd898a92ddc2318c3516c06fb6769c3e64216ed"
      ],
      "author": {
        "name": "Kristoffer Haugsbakk",
        "email": "code@khaugsbakk.name",
        "time": "Thu May 28 09:00:11 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri May 29 05:11:03 2026 +0900"
      },
      "message": "commit: remove deprecated functions\n\nThese functions were deprecated in a series of commits merged in\n52882024 (Merge branch \u0027ps/commit-list-functions-renamed\u0027, 2026-02-13).\n\nThe compatibility was for in-flight topics at the time.\n\nAcked-by: Patrick Steinhardt \u003cps@pks.im\u003e\nSigned-off-by: Kristoffer Haugsbakk \u003ccode@khaugsbakk.name\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "7dd898a92ddc2318c3516c06fb6769c3e64216ed",
      "tree": "90d1ca94c5524d68f404ef3db5e857b01c177ad7",
      "parents": [
        "a89346e34a937f001e5d397ee62224e3e9852040"
      ],
      "author": {
        "name": "Kristoffer Haugsbakk",
        "email": "code@khaugsbakk.name",
        "time": "Thu May 28 09:00:10 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri May 29 05:11:02 2026 +0900"
      },
      "message": "*: replace deprecated free_commit_list\n\nReplace `free_commit_list` with `commit_list_free`. The former was\ndeprecated in 9f18d089 (commit: rename `free_commit_list()` to conform\nto coding guidelines, 2026-01-15).\n\nThis allows us to remove all the deprecated functions in the\nnext commit:\n\n• `copy_commit_list`\n• `reverse_commit_list`\n• `free_commit_list`\n\nAcked-by: Patrick Steinhardt \u003cps@pks.im\u003e\nSigned-off-by: Kristoffer Haugsbakk \u003ccode@khaugsbakk.name\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "49633dc88c14008f9a405f215b60994362b36d6c",
      "tree": "7fd4627e8a508d823ee3de9322e27ad41c3aee7c",
      "parents": [
        "b04d26607de35b88cf9c62ca11931d4f8cc4ac05"
      ],
      "author": {
        "name": "Taylor Blau",
        "email": "me@ttaylorr.com",
        "time": "Wed May 27 15:56:11 2026 -0400"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Thu May 28 05:23:01 2026 +0900"
      },
      "message": "pack-bitmap: build pseudo-merge bitmaps after regular bitmaps\n\nWhen generating bitmaps, `bitmap_builder_init()` starts with an initial\nselection of commits to receive bitmap coverage, and then determines a\nset of \"maximal\" commits based on its input.\n\nCommit 089f751360f (pack-bitmap-write: build fewer intermediate bitmaps,\n2020-12-08) has extensive details, but the gist is as follows:\n\nEach selected commit starts with one commit_mask bit in its \"commit\nmask\" bitmap. Then, we walk the first-parent history in topological\norder and OR each commit\u0027s mask into its (first) parent. Whenever that\nOR results in the parent having more bits set, the child is deemed to be\nnon-maximal, and the frontier is pushed further back along the first\nparent history.\n\nThat approach works extremely well for ordinary selected commits, whose\nfirst-parent histories often describe real sharing between the bitmaps\nwe are going to write.\n\nIt struggles, however, to efficiently generate pseudo-merge bitmaps.\nUnlike ordinary commits for which the above algorithm is designed,\npseudo-merges don\u0027t represent any \"real\" commit in history, just a\ngrouping of non-bitmapped reference tips. In that sense, their first\nparent is just a part of a larger set, and treating them like ordinary\nselected commits imposes a significant slow-down when generating bitmaps\nwith pseudo-merges enabled.\n\nConsider partitioning all non-bitmapped reference tips into eight\nindividual pseudo-merges via the following configuration:\n\n    [bitmapPseudoMerge \"all\"]\n        pattern\u003drefs/\n        threshold\u003dnow\n        stableSize\u003d10000000\n        maxMerges\u003d8\n\n, the cost of generating a bitmap from scratch rises significantly:\n\n    +------------------+-----------------+---------------+---------------------+\n    |                  | no pseudo-merge | pseudo-merges | Delta               |\n    |                  |                 | (HEAD^)       |                     |\n    +------------------+-----------------+---------------+---------------------+\n    | elapsed          |   294.1 s       |   575.0 s     |   +280.9 s (+95.5%) |\n    | cycles           | 1,365.5 B       | 2,686.9 B     | +1,321.4 B (+96.8%) |\n    | instructions     | 1,389.8 B       | 2,546.6 B     | +1,156.8 B (+83.2%) |\n    | CPI              |     0.983       |     1.055     |   +0.073    (+7.4%) |\n    +------------------+-----------------+---------------+---------------------+\n\nThis is a particularly poor trade-off, because the time saved by these\npseudo-merges during, e.g.,\n\n    $ git rev-list --count --all --objects --use-bitmap-index\n\nis only:\n\n    $ hyperfine -L v true,false -n \u0027pseudo-merges: {v}\u0027 \u0027\n        GIT_TEST_USE_PSEUDO_MERGES\u003d{v} git.compile rev-list --count \\\n          --objects --all --use-bitmap-index\n      \u0027\n\n    Benchmark 1: pseudo-merges: true\n      Time (mean ± σ):      2.613 s ±  0.012 s    [User: 2.308 s, System: 0.305 s]\n      Range (min … max):    2.594 s …  2.633 s    10 runs\n\n    Benchmark 2: pseudo-merges: false\n      Time (mean ± σ):     52.205 s ±  0.170 s    [User: 51.500 s, System: 0.697 s]\n      Range (min … max):   51.956 s … 52.458 s    10 runs\n\n    Summary\n      pseudo-merges: true ran\n       19.98 ± 0.11 times faster than pseudo-merges: false\n\nIn other words, we pay a nearly ~5 minute penalty to generate\npseudo-merge bitmaps, but only save ~50 seconds during traversal.\n\nThe problem stems from injecting pseudo-merges into the bitmap builder\nas if they were normal commits. The maximal commit selection algorithm\nwas simply not designed for that case, and performs predictably poorly.\n\nThe only reason we reused the maximal commit selection routine for\npseudo-merges alongside regular non-pseudo-merge commits is because we\nrepresent them both as commit objects (where the pseudo-merge commits\njust represent a made-up commit as opposed to one that actually exists\nin a repository\u0027s object store).\n\nInstead, build the regular selected commit bitmaps first, considering\nonly non-pseudo-merge commits in `bitmap_builder_init()`. Once those\nbitmaps have been stored, build each pseudo-merge bitmap separately and\nattach its parent and object bitmaps to the corresponding pseudo-merge\nentry before writing the extension.\n\nThis keeps the regular bitmap build shaped like the no-pseudo-merge\ncase. The later pseudo-merge fill can still stop at stored selected\nancestor bitmaps, so it does not have to rewalk each pseudo-merge\nclosure from scratch.\n\nWhen an existing bitmap has the same pseudo-merge parent set, reuse and\nremap that whole pseudo-merge bitmap before falling back to\nfill_bitmap_commit(). This preserves the benefit of stable pseudo-merges\nwhile keeping the on-disk format and reader behavior unchanged.\n\nAs a result, the overhead cost for generating pseudo-merges in the above\nconfiguration is much smaller:\n\n    +------------------+-----------------+---------------+-------------------+\n    |                  | no pseudo-merge | pseudo-merges | Delta             |\n    |                  |                 | (HEAD)        |                   |\n    +------------------+-----------------+---------------+-------------------+\n    | elapsed          |   294.1 s       |   328.4 s     |  +34.3 s (+11.7%) |\n    | cycles           | 1,365.5 B       | 1,529.3 B     | +163.7 B (+12.0%) |\n    | instructions     | 1,389.8 B       | 1,552.8 B     | +163.0 B (+11.7%) |\n    | CPI              |     0.983       |     0.985     |  +0.002   (+0.2%) |\n    +------------------+-----------------+---------------+-------------------+\n\nRecall that at the start of this series, generating reachability bitmaps\ntook 612.5 seconds *without* pseudo-merges. With this commit, it is\nstill ~46.38% *faster* to generate reachability bitmaps *with*\npseudo-merges than it was to generate bitmaps wihtout them at the\nbeginning of this series.\n\nThe changes to implement this are mostly straightforward. We exclude\npseudo-merge commits from the existing bitmap generation, and walk over\nthem in a separate pass, by either reusing an existing on-disk\npseudo-merge, or passing the pseudo-merge commit itself back to the\nexisting routine in `fill_bitmap_commit()`.\n\n(Note that the routine to build pseudo-merge bitmaps is the same both\nbefore and after this change, the difference is only that we do not let\npsuedo-merges participate in determining the set of maximal commits.)\n\nThe only wrinkle is that `fill_bitmap_commit()` must be taught to not\nexpect that all tree objects have been parsed, which is the case for any\nportion of history reachable by one or more pseudo-merge(s), but not by\nany non-pseudo-merge commit selected for bitmapping.\n\nSigned-off-by: Taylor Blau \u003cme@ttaylorr.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "b04d26607de35b88cf9c62ca11931d4f8cc4ac05",
      "tree": "4fc82d37ff7446b6b08d26511cf5881a30fb135d",
      "parents": [
        "dcccd997462e2130bcc35f933285ff087454275e"
      ],
      "author": {
        "name": "Taylor Blau",
        "email": "me@ttaylorr.com",
        "time": "Wed May 27 15:56:08 2026 -0400"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Thu May 28 05:23:01 2026 +0900"
      },
      "message": "pack-bitmap: remember pseudo-merge parents\n\nwrite_pseudo_merges() currently builds an array of temporary bitmaps for\nthe parent set of each pseudo-merge, then serializes those bitmaps later\nwhile writing the extension.\n\nMove those parent bitmaps onto the corresponding bitmapped_commit\nentries instead. This keeps the on-disk output unchanged, but gives the\nparent bitmap the same lifetime and access pattern that later changes\nwill use when pseudo-merge object bitmaps are built before the write\nstep.\n\nSigned-off-by: Taylor Blau \u003cme@ttaylorr.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "dcccd997462e2130bcc35f933285ff087454275e",
      "tree": "c7c1c808bd032751cb31a1383e08ac1a899cd343",
      "parents": [
        "c720bbcc53f223236220c7a879f0a0e73e5d3739"
      ],
      "author": {
        "name": "Taylor Blau",
        "email": "me@ttaylorr.com",
        "time": "Wed May 27 15:56:05 2026 -0400"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Thu May 28 05:23:01 2026 +0900"
      },
      "message": "pack-bitmap: sort bitmaps before XORing\n\nReachability bitmaps may be stored as XORs against nearby bitmaps, up to\n10 away. However, when callers provide selected commits in an arbitrary\norder, the writer may miss good ancestor/descendant pairs and produce\nmuch larger bitmap files without changing query coverage.\n\nSort the selected bitmaps in date order (from oldest to newest) before\ncomputing XOR offsets, leaving pseudo-merge bitmaps alone (which we will\ndeal with separately in following commits).\n\nOn our same testing repository from previous commits, this change shrunk\nour selection of 1,261 bitmaps from ~635.46 MiB to 176.4 MiB for a\n~72.24% reduction in the on-disk size of our *.bitmap file. The time to\ngenerate the smaller bitmap file decreased by ~3.69 seconds, though this\nis likely mostly noise.\n\nSigned-off-by: Taylor Blau \u003cme@ttaylorr.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "c720bbcc53f223236220c7a879f0a0e73e5d3739",
      "tree": "3739a82b0ec9a9eef8a7ba5379d7160defe806f1",
      "parents": [
        "ece3465d44157157a03eb7cd5de955e552e7831c"
      ],
      "author": {
        "name": "Taylor Blau",
        "email": "me@ttaylorr.com",
        "time": "Wed May 27 15:56:02 2026 -0400"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Thu May 28 05:23:01 2026 +0900"
      },
      "message": "pack-bitmap: cache object positions during fill\n\nThe previous commits removed some redundant work from bitmap generation\nby avoiding unnecessary tree recursion and by reusing selected bitmaps\nthat have already been computed.\n\nEven with those changes in place, there is still an extremely hot path\nfrom `fill_bitmap_commit()` and `fill_bitmap_tree()` to translate object\nIDs into their corresponding bit positions in order to generate their\nbitmaps.\n\nIn a small repository, this overhead is not significant. However, in a\nvery large repository (e.g., the one that we have been using as a\nbenchmark over the past several commits with ~57M total objects), the\noverhead of locating object bit positions (often repeatedly) adds up\nsignificantly.\n\nCombat this by adding a small, direct-mapped cache to the bitmap writer\nwhich maps object IDs to their corresponding bit positions. Size the\ncache according to the number of objects being written, with fixed lower\nand upper bounds so small repositories do not pay for a large table and\nlarge repositories can avoid most repeated packlist and MIDX lookups.\n\nOn my machine with (a somewhat outdated) GCC 15.2.0, each entry in the\ncache is 40 bytes wide:\n\n    $ pahole -C bitmap_pos_cache_entry pack-bitmap-write.o\n    struct bitmap_pos_cache_entry {\n            struct object_id           oid;                  /*     0    36 */\n            uint32_t                   pos;                  /*    36     4 */\n\n            /* size: 40, cachelines: 1, members: 2 */\n            /* last cacheline: 40 bytes */\n    };\n\n, and we will allocate up to 2^21 entries for a maximum total of 80 MiB\nof cache overhead.\n\nIn our example repository from above and in earlier commits, this\nresults in a ~9.4% reduction in runtime relative to the previous commit:\n\n    +------------------+-------------+-------------+---------------------+\n    |                  | HEAD^       | HEAD        | Delta               |\n    +------------------+-------------+-------------+---------------------+\n    | elapsed          |   324.8 s   |   294.1 s   |    -30.7 s  (-9.4%) |\n    | cycles           | 1,508.6 B   | 1,365.5 B   |   -143.0 B  (-9.5%) |\n    | instructions     | 1,436.6 B   | 1,389.8 B   |    -46.9 B  (-3.3%) |\n    | CPI              |     1.050   |     0.983   |   -0.068    (-6.4%) |\n    +------------------+-------------+-------------+---------------------+\n\nWhen generating bitmaps on this repository (to produce the above\ntimings), the cache grew to its maximum size of 80 MiB, and resulted in\n1.024B cache hits and 59.957M cache misses.\n\nSigned-off-by: Taylor Blau \u003cme@ttaylorr.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "ece3465d44157157a03eb7cd5de955e552e7831c",
      "tree": "c1042ed7adaa1f237915b48f31ec64de02727a43",
      "parents": [
        "3ea5fe8482e44fe8636b2725edffcadc81b22161"
      ],
      "author": {
        "name": "Taylor Blau",
        "email": "me@ttaylorr.com",
        "time": "Wed May 27 15:55:59 2026 -0400"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Thu May 28 05:23:00 2026 +0900"
      },
      "message": "pack-bitmap: consolidate `find_object_pos()` success path\n\nBoth sides of `find_object_pos()` report success in the same way by\nsetting the optional `found` out-parameter and return the resolved\nbitmap position.\n\nPrepare for adding more bookkeeping around object-position lookups by\nstoring the result in a local `pos` variable and sharing the success\nreturn path between the packlist and MIDX cases.\n\nSigned-off-by: Taylor Blau \u003cme@ttaylorr.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "3ea5fe8482e44fe8636b2725edffcadc81b22161",
      "tree": "c284aaf7fc900ab26ffd6b32242ad6526a6844b5",
      "parents": [
        "1760c372589af09ff0b986c57bfe0b9101275674"
      ],
      "author": {
        "name": "Taylor Blau",
        "email": "me@ttaylorr.com",
        "time": "Wed May 27 15:55:56 2026 -0400"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Thu May 28 05:23:00 2026 +0900"
      },
      "message": "pack-bitmap: reuse stored selected bitmaps\n\nWhen `fill_bitmap_commit()` reaches an ancestor that was selected for\nits own bitmap and processed earlier, its object closure is already\nstored in `writer-\u003ebitmaps` as an EWAH bitmap. As a result, walking\nthrough that commit\u0027s tree and parents again is redundant.\n\nTeach `fill_bitmap_commit()` to notice that case. For non-root commits in\nthe walk, look for a stored selected bitmap and OR it into the bitmap\nbeing built. If one exists, skip the commit, its tree, and its parents.\n\nBuilding bitmaps from scratch on the same test repository from the\nprevious commits yields a significant speed-up:\n\n    +------------------+-------------+-------------+---------------------+\n    |                  | HEAD^       | HEAD        | Delta               |\n    +------------------+-------------+-------------+---------------------+\n    | elapsed          |   562.8 s   |   324.8 s   |   -237.9 s (-42.3%) |\n    | cycles           | 2,621.3 B   | 1,508.6 B   | -1,112.7 B (-42.4%) |\n    | instructions     | 2,348.9 B   | 1,436.6 B   |   -912.3 B (-38.8%) |\n    | CPI              |     1.116   |     1.050   |   -0.066    (-5.9%) |\n    +------------------+-------------+-------------+---------------------+\n\nIn our testing repository, there are 1,261 commits selected for bitmap\ncoverage, and 1,382 maximal commits induced as a result of that. Of the\n1,382 calls made to `fill_bitmap_commit()` (one per maximal commit), 131\nof them can be short-circuited at some point during their traversal as a\nconsequence of this change.\n\nIn large repositories where the cost of filling the bitmap for any\nindividual commit is large, being able to short-circuit even ~9.5% of\nthe calls to `fill_bitmap_commit()` results in a significant savings.\n\nSigned-off-by: Taylor Blau \u003cme@ttaylorr.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "1760c372589af09ff0b986c57bfe0b9101275674",
      "tree": "835b9ec292eb66cc1364816a8c2f519f6afb92af",
      "parents": [
        "e3959cc78c968d8f029daa48d4aadcb486da0629"
      ],
      "author": {
        "name": "Taylor Blau",
        "email": "me@ttaylorr.com",
        "time": "Wed May 27 15:55:53 2026 -0400"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Thu May 28 05:23:00 2026 +0900"
      },
      "message": "pack-bitmap: check subtree bits before recursing\n\nIn the previous commit, we adjusted the callers of `fill_bitmap_tree()`\nto pass in the bit position of the tree they wish to fill.\n\nThis commit makes use of that information at the call site to avoid\nsetting up a stack frame for fill_bitmap_tree() entirely whenever a\ntree\u0027s bit position is already set.\n\nSince this is such a hot path, the avoided cost of setting up and\ntearing down stack frames for each noop\u0027d call to `fill_bitmap_tree()`\nis significant:\n\n    +--------------+-------------+-------------+-------------------+\n    |              | HEAD^       | HEAD        | Delta             |\n    +--------------+-------------+-------------+-------------------+\n    | elapsed      |   582.4 s   |   562.8 s   |  -19.6 s  (-3.4%) |\n    | cycles       | 2,713.3 B   | 2,621.3 B   |  -92.0 B  (-3.4%) |\n    | instructions | 2,415.5 B   | 2,348.9 B   |  -66.6 B  (-2.8%) |\n    | CPI          |     1.123   |     1.116   |  -0.007   (-0.7%) |\n    +--------------+-------------+-------------+-------------------+\n\nIn the same repository as in the previous commit, our timings dropped\nfrom ~582.4 seconds down to ~562.77 seconds.\n\nWhile the cycles-per-instruction ratio is basically unchanged, we\nexecute significantly fewer instructions, and correspondingly fewer\ncycles.\n\nSigned-off-by: Taylor Blau \u003cme@ttaylorr.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "e3959cc78c968d8f029daa48d4aadcb486da0629",
      "tree": "12c3ababed391901b1844b3bf8a4c36a3425e674",
      "parents": [
        "d9e49a6abe15a291ab87868f3195dabe10be4790"
      ],
      "author": {
        "name": "Taylor Blau",
        "email": "me@ttaylorr.com",
        "time": "Wed May 27 15:55:50 2026 -0400"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Thu May 28 05:23:00 2026 +0900"
      },
      "message": "pack-bitmap: pass object position to `fill_bitmap_tree()`\n\nIn the following commit, callers of `fill_bitmap_tree()` will be\nrequired to check the bit corresponding to their tree before calling\nthat function. That change will reduce the overhead of setting up and\ntearing down stack frames for trees whose bits are already set.\n\nTo prepare for that change, have callers pass in the tree\u0027s bit position\nin `fill_bitmap_tree()`, which will make the next commit easier to read.\n\nIn the meantime, this change has a surprising and measurable benefit\nduring bitmap generation, particularly on very large repositories.\n\nWhen processing sub-trees within `fill_bitmap_tree()`, the preimage of\nthis patch did the following:\n\n    while (tree_entry(\u0026desc, entry)) {\n        switch (object_type(entry.mode)) {\n        case OBJ_TREE:\n            if (fill_bitmap_tree(writer, bitmap,\n                                 lookup_tree(writer-\u003erepo,\n                                             \u0026entry.oid)) \u003c 0) {\n                /* ... */\n            }\n            /* ... */\n        }\n    }\n\n, first performing the object lookup via `lookup_tree()`, and then\nlocating its bit position within the recursive call. This patch\neffectively reorders those two calls so that we first discover the\nsub-tree\u0027s bit position, *then* load its tree.\n\nBy reordering these two operations, we spend fewer CPU cycles per\ninstruction, likely due to improved CPU dependency/cache/pipeline\nbehavior. Comparing the results of: running `perf stat` before and after\nthis commit, we have:\n\n    +--------------+-------------+-------------+-------------------+\n    |              | HEAD^       | HEAD        | Delta             |\n    +--------------+-------------+-------------+-------------------+\n    | elapsed      |   612.5 s   |   582.4 s   |  -30.1 s  (-4.9%) |\n    | cycles       | 2,857.3 B   | 2,713.3 B   | -144.0 B  (-5.0%) |\n    | instructions | 2,413.2 B   | 2,415.5 B   |   +2.3 B  (+0.1%) |\n    | CPI          |     1.184   |     1.123   |  -0.061   (-5.1%) |\n    +--------------+-------------+-------------+-------------------+\n\nIn a large repository with ~4.8M commit, and ~37.1M tree objects this\nchange improves timing from ~612.5 seconds down to ~582.4 seconds, or a\n~4.9% improvement. More importantly, the number of CPU cycles spent\ndropped off significantly as a result of this commit, lowering our\ncycles-per-instruction ratio by about ~5.1%.\n\nSigned-off-by: Taylor Blau \u003cme@ttaylorr.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "c69baaf57ba26cf117c2b6793802877f19738b0d",
      "tree": "2ababa2f6f5c2977da519adb01a2b00f6a7bbe1c",
      "parents": [
        "455ff75d35622ba2219432400756c697bb15e7c8"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed May 27 14:15:25 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed May 27 14:15:46 2026 +0900"
      },
      "message": "The 9th batch\n\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "455ff75d35622ba2219432400756c697bb15e7c8",
      "tree": "d7086e1d8cc009498645a866f5817702de556bfe",
      "parents": [
        "0839e5695702d2fc14002c37b5f2f1c6c4c6be43",
        "df69f40c34de003ebc43cfe514526b11ffdec113"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed May 27 14:15:46 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed May 27 14:15:46 2026 +0900"
      },
      "message": "Merge branch \u0027ps/setup-wo-the-repository\u0027\n\nMany uses of the_repository has been updated to use a more\nappropriate struct repository instance in setup.c codepath.\n\n* ps/setup-wo-the-repository:\n  setup: stop using `the_repository` in `init_db()`\n  setup: stop using `the_repository` in `create_reference_database()`\n  setup: stop using `the_repository` in `initialize_repository_version()`\n  setup: stop using `the_repository` in `check_repository_format()`\n  setup: stop using `the_repository` in `upgrade_repository_format()`\n  setup: stop using `the_repository` in `setup_git_directory()`\n  setup: stop using `the_repository` in `setup_git_directory_gently()`\n  setup: stop using `the_repository` in `setup_git_env()`\n  setup: stop using `the_repository` in `set_git_work_tree()`\n  setup: stop using `the_repository` in `setup_work_tree()`\n  setup: stop using `the_repository` in `enter_repo()`\n  setup: stop using `the_repository` in `verify_non_filename()`\n  setup: stop using `the_repository` in `verify_filename()`\n  setup: stop using `the_repository` in `path_inside_repo()`\n  setup: stop using `the_repository` in `prefix_path()`\n  setup: stop using `the_repository` in `is_inside_work_tree()`\n  setup: stop using `the_repository` in `is_inside_git_dir()`\n  setup: replace use of `the_repository` in static functions\n"
    },
    {
      "commit": "0839e5695702d2fc14002c37b5f2f1c6c4c6be43",
      "tree": "ed8a4f57c0bd64c5ea92923fd42f0bc615eb2c6d",
      "parents": [
        "2f952b81ed2c44ebce3496d659a93d82a1a2f662",
        "d2902a45498793f8dc69abc6448f517b69437eec"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed May 27 14:15:46 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed May 27 14:15:46 2026 +0900"
      },
      "message": "Merge branch \u0027ps/odb-in-memory\u0027\n\nAdd a new odb \"in-memory\" source that is meant to only hold\ntentative objects (like the virtual blob object that represents the\nworking tree file used by \"git blame\").\n\n* ps/odb-in-memory:\n  t/unit-tests: add tests for the in-memory object source\n  odb: generic in-memory source\n  odb/source-inmemory: stub out remaining functions\n  odb/source-inmemory: implement `freshen_object()` callback\n  odb/source-inmemory: implement `count_objects()` callback\n  odb/source-inmemory: implement `find_abbrev_len()` callback\n  odb/source-inmemory: implement `for_each_object()` callback\n  odb/source-inmemory: convert to use oidtree\n  oidtree: add ability to store data\n  cbtree: allow using arbitrary wrapper structures for nodes\n  odb/source-inmemory: implement `write_object_stream()` callback\n  odb/source-inmemory: implement `write_object()` callback\n  odb/source-inmemory: implement `read_object_stream()` callback\n  odb/source-inmemory: implement `read_object_info()` callback\n  odb: fix unnecessary call to `find_cached_object()`\n  odb/source-inmemory: implement `free()` callback\n  odb: introduce \"in-memory\" source\n"
    },
    {
      "commit": "2f952b81ed2c44ebce3496d659a93d82a1a2f662",
      "tree": "3e0bb4d2c717f6bee60e259396122d75546ce383",
      "parents": [
        "8b5873a1f228fe0e568f13c864fcdd69a866aa95",
        "08b6afb2a2dbf762e3d9fa7abd78090b9afbd1a8"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed May 27 14:15:45 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed May 27 14:15:45 2026 +0900"
      },
      "message": "Merge branch \u0027jt/odb-transaction-write\u0027\n\nODB transaction interface is being reworked to explicitly handle\nobject writes.\n\n* jt/odb-transaction-write:\n  odb/transaction: make `write_object_stream()` pluggable\n  object-file: generalize packfile writes to use odb_write_stream\n  object-file: avoid fd seekback by checking object size upfront\n  object-file: remove flags from transaction packfile writes\n  odb: update `struct odb_write_stream` read() callback\n  odb/transaction: use pluggable `begin_transaction()`\n  odb: split `struct odb_transaction` into separate header\n"
    },
    {
      "commit": "8b5873a1f228fe0e568f13c864fcdd69a866aa95",
      "tree": "a938a0c34c2aae594f0c3c5281f1d22a79ade39e",
      "parents": [
        "1103041f3482c2e19174a6192dabfcf6a286b6a8",
        "06733a50eeec4205011d210d3932c5b708a665e9"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed May 27 14:15:45 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed May 27 14:15:45 2026 +0900"
      },
      "message": "Merge branch \u0027tb/incremental-midx-part-3.3\u0027\n\nThe repacking code has been refactored and compaction of MIDX layers\nhave been implemented, and incremental strategy that does not require\nall-into-one repacking has been introduced.\n\n* tb/incremental-midx-part-3.3:\n  repack: allow `--write-midx\u003dincremental` without `--geometric`\n  repack: introduce `--write-midx\u003dincremental`\n  repack: implement incremental MIDX repacking\n  packfile: ensure `close_pack_revindex()` frees in-memory revindex\n  builtin/repack.c: convert `--write-midx` to an `OPT_CALLBACK`\n  repack-geometry: prepare for incremental MIDX repacking\n  repack-midx: extract `repack_fill_midx_stdin_packs()`\n  repack-midx: factor out `repack_prepare_midx_command()`\n  midx: expose `midx_layer_contains_pack()`\n  repack: track the ODB source via existing_packs\n  midx: support custom `--base` for incremental MIDX writes\n  midx: introduce `--no-write-chain-file` for incremental MIDX writes\n  midx: use `strvec` for `keep_hashes`\n  midx: build `keep_hashes` array in order\n  midx: use `strset` for retained MIDX files\n  midx-write: handle noop writes when converting incremental chains\n"
    },
    {
      "commit": "1103041f3482c2e19174a6192dabfcf6a286b6a8",
      "tree": "3ac21c62d4e89d8406bbf8216df9b00aa316367f",
      "parents": [
        "ebdb4c523d5e372a6e9556d218e1cb295d23b7a2",
        "a6d92c48e4426b88a427a75ed2c20d1daa5dc7f7"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed May 27 14:15:45 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed May 27 14:15:45 2026 +0900"
      },
      "message": "Merge branch \u0027ds/fetch-negotiation-options\u0027\n\nThe negotiation tip options in \"git fetch\" have been reworked to\nallow requiring certain refs to be sent as \"have\" lines, and to\nrestrict negotiation to a specific set of refs.\n\n* ds/fetch-negotiation-options:\n  send-pack: pass negotiation config in push\n  remote: add remote.*.negotiationInclude config\n  fetch: add --negotiation-include option for negotiation\n  negotiator: add have_sent() interface\n  remote: add remote.*.negotiationRestrict config\n  transport: rename negotiation_tips\n  fetch: add --negotiation-restrict option\n  t5516: fix test order flakiness\n"
    },
    {
      "commit": "ebdb4c523d5e372a6e9556d218e1cb295d23b7a2",
      "tree": "294c96da3ea263422b6aceea6dc57b6d6f503577",
      "parents": [
        "a77a640250eb7b4c12dfc20962727651e4aedefb",
        "29d9fdcf1098672b2146c60eea5202e840615772"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed May 27 14:15:44 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed May 27 14:15:45 2026 +0900"
      },
      "message": "Merge branch \u0027rs/use-builtin-add-overflow-explicitly-on-clang\u0027\n\nMicro optimization of codepaths that compute allocation sizes carefully.\n\n* rs/use-builtin-add-overflow-explicitly-on-clang:\n  use __builtin_add_overflow() in st_add() with Clang\n  strbuf: use st_add3() in strbuf_grow()\n"
    },
    {
      "commit": "a77a640250eb7b4c12dfc20962727651e4aedefb",
      "tree": "410ca4ea2a3c879f2e11cc55be059bd94e37a005",
      "parents": [
        "bbcc0ae3e94be45320ca7bbd31dbc2a2ce58ea8d",
        "b56ab270aab71168ab7d0731f0a3853dac7aa62f"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed May 27 14:15:44 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed May 27 14:15:44 2026 +0900"
      },
      "message": "Merge branch \u0027jk/sq-dequote-cleanup\u0027\n\nCode simplification.\n\n* jk/sq-dequote-cleanup:\n  quote: simplify internals of dequoting\n  quote: drop sq_dequote_to_argv()\n  quote.h: bump strvec forward declaration to the top\n"
    },
    {
      "commit": "bbcc0ae3e94be45320ca7bbd31dbc2a2ce58ea8d",
      "tree": "94049044553dd896a3f5057e723155d9fdd9fdc6",
      "parents": [
        "c5e6e497ac6c9a80ec4b04752cce1c35337bd6b9",
        "e0fcba2d9cf86ba45943066924f111006d55ba08"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed May 27 14:15:44 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed May 27 14:15:44 2026 +0900"
      },
      "message": "Merge branch \u0027kn/refs-fsck-skip-lock-files\u0027\n\nThe consistency checks for the files reference backend have been updated\nto skip lock files earlier, avoiding unnecessary parsing of\nintermediate files.\n\n* kn/refs-fsck-skip-lock-files:\n  refs/files: skip lock files during consistency checks\n"
    },
    {
      "commit": "c5e6e497ac6c9a80ec4b04752cce1c35337bd6b9",
      "tree": "4aab2f6f6c73cebc8e3038a388740f71e6227dde",
      "parents": [
        "9020a116d63828a9bd521564d9d41b2c0136e6d2",
        "499f9048e0ef09285fe112dc387324404fb99b1d"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed May 27 14:15:44 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed May 27 14:15:44 2026 +0900"
      },
      "message": "Merge branch \u0027ps/t3903-cover-stash-include-untracked\u0027\n\nTest coverage has been added to \"git stash --include-untracked\".\n\n* ps/t3903-cover-stash-include-untracked:\n  stash: add coverage for show --include-untracked\n"
    },
    {
      "commit": "9020a116d63828a9bd521564d9d41b2c0136e6d2",
      "tree": "cdcd8f96977b7f214a5222a28329c67af85b5849",
      "parents": [
        "6d2ba7ead7ab074bfd88e194bb75d6b384c44d4e",
        "0acbaf9000bd50bfbec24e5c40ab96bbd5e79281"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed May 27 14:15:44 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed May 27 14:15:44 2026 +0900"
      },
      "message": "Merge branch \u0027kk/merge-octopus-optim\u0027\n\nThe logic to determine that branches in an octopus merge are\nindependent has been optimized.\n\n* kk/merge-octopus-optim:\n  merge: use repo_in_merge_bases for octopus up-to-date check\n"
    },
    {
      "commit": "6d2ba7ead7ab074bfd88e194bb75d6b384c44d4e",
      "tree": "86e89683aa6ed9cab5cb16f71411c89caa92730f",
      "parents": [
        "c8de06d69bbcdb4807687337e24a06ff3696cf3c",
        "854061ea5484fffc6c54941332115abbd7fc950f"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed May 27 14:15:43 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed May 27 14:15:44 2026 +0900"
      },
      "message": "Merge branch \u0027en/batch-prefetch\u0027\n\nIn a lazy clone, \"git cherry\" and \"git grep\" often fetch necessary\nblob objects one by one from promisor remotes.  It has been corrected\nto collect necessary object names and fetch them in bulk to gain\nreasonable performance.\n\n* en/batch-prefetch:\n  grep: prefetch necessary blobs\n  builtin/log: prefetch necessary blobs for `git cherry`\n  patch-ids.h: add missing trailing parenthesis in documentation comment\n  promisor-remote: document caller filtering contract\n"
    },
    {
      "commit": "c8de06d69bbcdb4807687337e24a06ff3696cf3c",
      "tree": "b7cd8b7e4b73d9d3aff236524bfb38b95a5b98ce",
      "parents": [
        "49a06cc814b689610ef2e8fcfe7663fc295448fe",
        "34a891a2d30865316be2628949d4f1b005f65662"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed May 27 14:15:43 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed May 27 14:15:43 2026 +0900"
      },
      "message": "Merge branch \u0027rs/trailer-fold-optim\u0027\n\nCode simplification.\n\n* rs/trailer-fold-optim:\n  trailer: change strbuf in-place in unfold_value()\n"
    },
    {
      "commit": "49a06cc814b689610ef2e8fcfe7663fc295448fe",
      "tree": "4581ce319fc0b1468e2de21bf8b276aded203f8a",
      "parents": [
        "947a026e8377b9d4163ff46f76936b93df47f1e3",
        "6d09e798bcfba92ef071abb27ad807985681122c"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed May 27 14:15:43 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed May 27 14:15:43 2026 +0900"
      },
      "message": "Merge branch \u0027pb/doc-diff-format-updates\u0027\n\nDoc updates.\n\n* pb/doc-diff-format-updates:\n  diff-format.adoc: mode and hash are 0* for unmerged paths from index only\n  diff-format.adoc: \u0027git diff-files\u0027 prints two lines for unmerged files\n  diff-format.adoc: remove mention of diff-tree specific output\n"
    },
    {
      "commit": "947a026e8377b9d4163ff46f76936b93df47f1e3",
      "tree": "eda9b03a4ec46c993afa1d17d353c430607542c3",
      "parents": [
        "bccafbc09c2b7516f50182ff098bc144e45847ce",
        "ef8d51a8a3e1c57201aa2c116ad27b0db580123a"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed May 27 14:15:43 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed May 27 14:15:43 2026 +0900"
      },
      "message": "Merge branch \u0027kk/limit-list-optim\u0027\n\nThe limit_list() function that is one of the core part of the\nrevision traversal infrastructure has been optimized by replacing\nits use of linear list with priority queue.\n\n* kk/limit-list-optim:\n  revision: use priority queue in limit_list()\n"
    },
    {
      "commit": "bccafbc09c2b7516f50182ff098bc144e45847ce",
      "tree": "ba377b83200c600f2aa980650e98d3e9b2e43271",
      "parents": [
        "56a4f3c3a221adf1df9b39da69b8a6890f803157",
        "5e6e8dc7860374d79bad3e2a3ade0c2d391bbad6"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed May 27 14:15:43 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed May 27 14:15:43 2026 +0900"
      },
      "message": "Merge branch \u0027tb/pseudo-merge-bugfixes\u0027\n\nFixes many bugs in pseudo-merge code.\n\n* tb/pseudo-merge-bugfixes:\n  pack-bitmap: prevent pattern leak on pseudo-merge re-assignment\n  Documentation: fix broken `sampleRate` in gitpacking(7)\n  pack-bitmap: reject pseudo-merge \"sampleRate\" of 0\n  pack-bitmap: parse commits in `find_pseudo_merge_group_for_ref()`\n  pack-bitmap: fix pseudo-merge lookup for shared commits\n  pack-bitmap: fix inverted binary search in `pseudo_merge_at()`\n  pack-bitmap-write: sort pseudo-merge commit lookup table in pack order\n  t5333: demonstrate various pseudo-merge bugs\n  t/helper: add \u0027test-tool bitmap write\u0027 subcommand\n"
    },
    {
      "commit": "105aacd072e41c55948d016b46f86f75db2487b3",
      "tree": "adc9720f503c7059c903d6b8b8175f3f7a1a4f32",
      "parents": [
        "ca7b9ae3403b1a46fffbdae312092c4029470eee"
      ],
      "author": {
        "name": "Derrick Stolee",
        "email": "stolee@gmail.com",
        "time": "Tue May 26 20:26:34 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed May 27 13:42:59 2026 +0900"
      },
      "message": "restore: avoid sparse index expansion\n\nTeach update_some() to handle sparse directory entries at the tree\nlevel rather than expanding the entire sparse index. When iterating a\nsource tree during checkout/restore operations:\n\n - If a directory matches a sparse directory entry with the same OID,\n   skip it entirely (no change needed).\n\n - If the OID differs and we are in non-overlay mode (e.g., restore\n   --staged), update the sparse directory entry\u0027s OID in place. This\n   is semantically correct because non-overlay mode removes paths not\n   in the source tree anyway.\n\n - In overlay mode (e.g., checkout \u003ctree\u003e -- .), fall through to\n   recursive descent so individual file entries are preserved\n   correctly.\n\nAlso switch from index_name_pos() to index_name_pos_sparse() for\nindividual file lookups to avoid triggering ensure_full_index() when\nthe file is already individually tracked in the index.\n\nUpdate the test expectation in t1092 to assert that \u0027restore --staged\u0027\nno longer expands the sparse index.\n\nSigned-off-by: Derrick Stolee \u003cstolee@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "ca7b9ae3403b1a46fffbdae312092c4029470eee",
      "tree": "ffd8d8194712eaab11faa58ef23ce251984c7efe",
      "parents": [
        "6a4418c36d6bad69a599044b3cf49dcbd049cb45"
      ],
      "author": {
        "name": "Derrick Stolee",
        "email": "stolee@gmail.com",
        "time": "Tue May 26 20:26:33 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed May 27 13:42:59 2026 +0900"
      },
      "message": "t1092: test \u0027git restore\u0027 with sparse index\n\nA user reported that \u0027git restore --staged .\u0027 causes the sparse index to\nexpand. This is somewhat natural because the \u0027.\u0027 pathspec means \u0027check\nevery path\u0027. However, the restore will not update paths marked with the\nSKIP_WORKTREE bit, so we shouldn\u0027t need to process such entries.\n\nFor now, establish the current behavior, including the sparse index\nexpansion, in the t1092 test case as a baseline.\n\nSigned-off-by: Derrick Stolee \u003cstolee@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "b2040bfafe0f7bbbd21cf65a903d2346d602f421",
      "tree": "7ae78e53ba2078890207f50db3b811d830ebff63",
      "parents": [
        "56a4f3c3a221adf1df9b39da69b8a6890f803157"
      ],
      "author": {
        "name": "Ivan Baluta",
        "email": "ivanbaluta.dev@gmail.com",
        "time": "Tue May 26 03:58:07 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue May 26 20:11:29 2026 +0900"
      },
      "message": "doc: clarify push.default\u003dsimple behavior\n\nThe documentation for the \u0027simple\u0027 push mode currently singles out\nthe centralized workflow, which can cause confusion about its\nbehavior in other scenarios, such as triangular workflows.\n\nClarify that \u0027simple\u0027 always pushes the current branch to a branch\nof the same name, but only enforces the strict upstream tracking\nrequirement when pushing back to the same remote being pulled from.\n\nSuggested-by: Junio C Hamano \u003cgitster@pobox.com\u003e\nSigned-off-by: Ivan Baluta \u003civanbaluta.dev@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "44d04e442683b53ed618b74861f056f93fcbd783",
      "tree": "dbbf9588470b68270ff4e3b7aa46ecc3f0f6a204",
      "parents": [
        "67ad42147a7acc2af6074753ebd03d904476118f"
      ],
      "author": {
        "name": "Alyssa Ross",
        "email": "hi@alyssa.is",
        "time": "Mon May 25 18:23:12 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue May 26 07:54:18 2026 +0900"
      },
      "message": "receive-pack: fix updateInstead with core.worktree\n\nBefore a8cc594333 (hooks: fix an obscure TOCTOU \"did we just run a\nhook?\" race, 2022-03-07), when receive.denyCurrentBranch is set to\nupdateInstead, only one of push_to_checkout() or push_to_deploy()\nwas called.  That commit changed to always call push_to_checkout(),\nand then to call push_to_deploy() if push_to_checkout() didn\u0027t run\nanything.\n\nThis change didn\u0027t take into account that push_to_checkout() had a\nside effect of modifying env, and that modified env broke updating\nthe worktree in push_to_deploy() if core.worktree was configured.\nTo fix this, only mutate the environment used inside\npush_to_commit(), rather than the environment that might later be\npassed to push_to_deploy().\n\nSigned-off-by: Alyssa Ross \u003chi@alyssa.is\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "a186b7797a8bd4b9ca09b9cb326a2dccee00f90e",
      "tree": "a81c72b67ef09664cbd18247ef07637b8698eea8",
      "parents": [
        "f767dae3e6c8359128d0ec83acd009751e92e419"
      ],
      "author": {
        "name": "Kristofer Karlsson",
        "email": "krka@spotify.com",
        "time": "Mon May 25 14:28:05 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue May 26 07:18:04 2026 +0900"
      },
      "message": "commit-reach: replace queue_has_nonstale() scan with O(1) tracking\n\npaint_down_to_common() and ahead_behind() call queue_has_nonstale()\non every iteration to decide whether to continue the walk.\nqueue_has_nonstale() performs a linear scan of the priority queue,\nmaking the overall walk O(n*m) where n is the number of commits\nwalked and m is the queue size.\n\nIntroduce \u0027struct nonstale_queue\u0027, a thin wrapper around prio_queue\nthat maintains a \u0027max_nonstale\u0027 pointer — the lowest-priority\n(oldest) non-stale commit seen so far. When this commit is popped,\nevery remaining queue entry is known to be stale, so the walk can\nstop. This reduces the per-iteration termination check from O(m)\nto O(1).\n\nUses \u003c\u003d 0 (not \u003c 0) when comparing priorities so that among distinct\ncommits with equal priority (same generation and timestamp) the\nlast-enqueued one is tracked. Since prio_queue breaks ties by\ninsertion order, this ensures max_nonstale is always the last in its\npriority class to be popped, making pointer equality on pop\nsufficient for correctness.\n\nThe previous commit\u0027s ENQUEUED deduplication guarantees each commit\nappears at most once in the queue, which is required for the pointer\nequality check to be unambiguous.\n\nOn a large monorepo (3.7M commits), this yields ~2x end-to-end\nspeedup for merge-base calculations on deep import branches.\nProfiling shows paint_down_to_common() drops from 50% to 4% of\ntotal runtime (~27x faster), with the remaining time in commit\ngraph lookups and heap operations:\n\n  Before: 8536ms / 5757ms / 4743ms  (three test cases)\n  After:  3956ms / 4383ms / 1927ms\n\nSuggested-by: Jeff King \u003cpeff@peff.net\u003e\nSigned-off-by: Kristofer Karlsson \u003ckrka@spotify.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "f767dae3e6c8359128d0ec83acd009751e92e419",
      "tree": "7f6b2172a2b24facb80cb851675c6b8db075abaa",
      "parents": [
        "85a30b5b26c2953aa836c554af5fc58eed707e4a"
      ],
      "author": {
        "name": "Kristofer Karlsson",
        "email": "krka@spotify.com",
        "time": "Mon May 25 14:28:04 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue May 26 07:17:26 2026 +0900"
      },
      "message": "commit-reach: deduplicate queue entries in paint_down_to_common\n\npaint_down_to_common() can enqueue the same commit multiple times\nwhen it is reached through different parents with different flag\ncombinations. Add an ENQUEUED flag to track whether a commit is\ncurrently in the priority queue, and skip it if already present.\n\nIntroduce prio_queue_put_dedup() and prio_queue_get_dedup()\nwrappers that manage the ENQUEUED flag on enqueue and dequeue.\n\nThis change is performance-neutral on its own: the O(n)\nqueue_has_nonstale() scan still dominates the per-iteration cost.\nHowever, the deduplication guarantee (each commit appears in the\nqueue at most once) is a prerequisite for the next commit, which\nreplaces that scan with O(1) tracking.\n\nSigned-off-by: Kristofer Karlsson \u003ckrka@spotify.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "85a30b5b26c2953aa836c554af5fc58eed707e4a",
      "tree": "e55045fd9e1178102021343db35b2b7b7f4e1f6b",
      "parents": [
        "6a4418c36d6bad69a599044b3cf49dcbd049cb45"
      ],
      "author": {
        "name": "Kristofer Karlsson",
        "email": "krka@spotify.com",
        "time": "Mon May 25 14:28:03 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue May 26 07:17:26 2026 +0900"
      },
      "message": "object.h: fix stale entries in object flag allocation table\n\nUpdate three stale entries found during an audit of the flag\nallocation table:\n\n - sha1-name.c was renamed to object-name.c\n - builtin/show-branch.c uses bits 0 and 2-28, not 0-26\n   (REV_SHIFT\u003d2, MAX_REVS\u003dFLAG_BITS-REV_SHIFT\u003d27)\n - negotiator/skipping.c uses bits 2-5 like negotiator/default.c\n   (ADVERTISED on bit 3 instead of COMMON_REF)\n\nSigned-off-by: Kristofer Karlsson \u003ckrka@spotify.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "2ef248ae45bdcfbb027108bf87fcc3375cb5daba",
      "tree": "40360247b2e2fbf7747788e31bf2a83f4a51c280",
      "parents": [
        "ba1c516edabccd3e195746a8be842a70cdea6502"
      ],
      "author": {
        "name": "Jean-Noël Avila",
        "email": "jn.avila@free.fr",
        "time": "Mon May 25 10:28:27 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Mon May 25 20:05:45 2026 +0900"
      },
      "message": "doc: convert git-imap-send synopsis and options to new style\n\nConvert git-imap-send from [verse]/single-quote style to the modern\nsynopsis-block style:\n\n- Replace [verse] with [synopsis] in SYNOPSIS block\n- Backtick-quote all OPTIONS terms\n- Backtick-quote all config keys in config/imap.adoc\n- Backtick-quote bare config key references in prose\n\nSigned-off-by: Jean-Noël Avila \u003cjn.avila@free.fr\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "ba1c516edabccd3e195746a8be842a70cdea6502",
      "tree": "cbda3d631f4f60f23c4cc655dd5f321be9449159",
      "parents": [
        "242d3aa317ccaa3e7c5f6bf2218ccbdd8a0a26e9"
      ],
      "author": {
        "name": "Jean-Noël Avila",
        "email": "jn.avila@free.fr",
        "time": "Mon May 25 10:28:26 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Mon May 25 20:05:44 2026 +0900"
      },
      "message": "doc: convert git-apply synopsis and options to new style\n\nConvert git-apply from [verse]/single-quote style to the modern\nsynopsis-block style:\n\n- Replace [verse] with [synopsis] in SYNOPSIS block\n- Backtick-quote all OPTIONS terms and config keys in config/apply.adoc\n- Convert single-quoted inline commands (\u0027git apply\u0027, \u0027diff\u0027, etc.)\n- Wrap standalone placeholders in underscores (\u003cn\u003e, \u003croot\u003e, \u003caction\u003e)\n- Backtick-quote `*.rej` and GNU `patch` tool references\n\nSigned-off-by: Jean-Noël Avila \u003cjn.avila@free.fr\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "242d3aa317ccaa3e7c5f6bf2218ccbdd8a0a26e9",
      "tree": "ce352be0299c745d1d57ae958850d3b693da5828",
      "parents": [
        "25d5d60958f1486cb8439863062f66ffef605f18"
      ],
      "author": {
        "name": "Jean-Noël Avila",
        "email": "jn.avila@free.fr",
        "time": "Mon May 25 10:28:25 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Mon May 25 20:05:44 2026 +0900"
      },
      "message": "doc: convert git-am synopsis and options to new style\n\nConvert git-am from [verse]/single-quote style to the modern\nsynopsis-block style:\n\n- Replace [verse] with [synopsis] in SYNOPSIS block\n- Backtick-quote all OPTIONS terms\n- Convert inline man page refs\n- Convert inline command refs\n- Convert prose placeholders:\n\nSigned-off-by: Jean-Noël Avila \u003cjn.avila@free.fr\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "25d5d60958f1486cb8439863062f66ffef605f18",
      "tree": "461d912dba3805e8506d347a6a130b055d00e6a4",
      "parents": [
        "ed31e2872a7306f52de1e2b9ab0065b9d91f3338"
      ],
      "author": {
        "name": "Jean-Noël Avila",
        "email": "jn.avila@free.fr",
        "time": "Mon May 25 10:28:24 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Mon May 25 20:05:44 2026 +0900"
      },
      "message": "doc: convert git-grep synopsis and options to new style\n\nConvert git-grep.adoc from [verse]/single-quote style to the modern\nsynopsis-block style:\n\n- Replace [verse] with [synopsis] in SYNOPSIS block\n- Change \u0027git grep\u0027 to git grep (no single quotes)\n- Backtick-quote all OPTIONS terms\n- Convert inline man page refs: grep(1) -\u003e `grep`(1)\n- Convert inline command refs: \u0027git diff\u0027 -\u003e `git diff`\n- Convert prose placeholders: \u003cfile\u003e -\u003e _\u003cfile\u003e_\n\nSigned-off-by: Jean-Noël Avila \u003cjn.avila@free.fr\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "ed31e2872a7306f52de1e2b9ab0065b9d91f3338",
      "tree": "a0e590995fae9c4739a3574781b403f10be2965c",
      "parents": [
        "50cd5219d2b63f4896a3d142f83fadf8e47a6c3b"
      ],
      "author": {
        "name": "Jean-Noël Avila",
        "email": "jn.avila@free.fr",
        "time": "Mon May 25 10:28:23 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Mon May 25 20:05:44 2026 +0900"
      },
      "message": "doc: git bisect: clarify the usage of the synopsis vs actual command\n\nThe difference between a synopsis and an actual command is that the synopsis\nis a more abstract representation of the command, which may include\nplaceholders for arguments and options. The actual command is the specific\ninstance of the command with all the arguments and options filled in.\n\nThe formatting of an actual command is a code block, with the command\nprefixed by a dollar sign ($) to indicate that it is a command to be run in\nthe terminal. It can also include comments with a hash sign (#) to explain\nthe command or provide additional information, just like in a regular\nterminal session.\n\nSigned-off-by: Jean-Noël Avila \u003cjn.avila@free.fr\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "50cd5219d2b63f4896a3d142f83fadf8e47a6c3b",
      "tree": "eb1a57b59e72bfb398e54a87c385599f83cdb3b5",
      "parents": [
        "94f057755b7941b321fd11fec1b2e3ca5313a4e0"
      ],
      "author": {
        "name": "Jean-Noël Avila",
        "email": "jn.avila@free.fr",
        "time": "Mon May 25 10:28:22 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Mon May 25 20:05:44 2026 +0900"
      },
      "message": "doc: convert git-bisect to synopsis style\n\nConvert Documentation/git-bisect.adoc to the modern synopsis style.\n\n- Replace [verse] with [synopsis] in the SYNOPSIS block\n- Remove single quotes around command names in the synopsis\n- Use backticks for inline commands, options, refs, and special values\n- Apply [synopsis] attribute to in-body command-form code blocks\n- Format OPTIONS entries with backtick-quoted terms and direct\n- Add synopsis-style formatting to listing blocks\n- Format man page references as `command`(N)\n\nSigned-off-by: Jean-Noël Avila \u003cjn.avila@free.fr\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "7c9b38d267129625adeced9f66140e802c345261",
      "tree": "bf3a0ed490fa4a9bc945dc6ea74cb1fef4abe66c",
      "parents": [
        "67ad42147a7acc2af6074753ebd03d904476118f"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Mon May 25 11:58:48 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Mon May 25 12:03:00 2026 +0900"
      },
      "message": "SubmittingPatches: proactively monitor GHCI pages\n\nEven those contributors who do not come from GGG and do not first\npush their changes to their repositories on GitHub with CI enabled,\ncan still monitor the CI runs triggered by integration of their\ntopic to \u0027seen\u0027 and other branches to notice a breakage their topic\ncaused to the system.\n\nEncourage them to help the project by keeping an eye on these CI\nruns.\n\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "56a4f3c3a221adf1df9b39da69b8a6890f803157",
      "tree": "3a5a9a7ba573b2eb6688c17cdff9b12613515426",
      "parents": [
        "2f1b8f56f8647cc4ff4c6e2e740e82ce80e99d65"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Mon May 25 09:39:50 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Mon May 25 09:40:08 2026 +0900"
      },
      "message": "The 8th batch\n\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "2f1b8f56f8647cc4ff4c6e2e740e82ce80e99d65",
      "tree": "c2a384fd8f1b23c426ac55aba751e982e72e72e6",
      "parents": [
        "734fd43d3fd5477e6be7c2609a812f5b5c8c5b01",
        "b92387cd55f9fa66edd6e646ec5c17be8d72609b"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Mon May 25 09:40:08 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Mon May 25 09:40:08 2026 +0900"
      },
      "message": "Merge branch \u0027jk/dumb-http-alternate-fix\u0027\n\nThe HTTP walker misinterpreted the alternates file that gives an\nabsolute path when the server URL does not have the final slash\n(i.e., \"https://example.com\" not \"https://example.com/\").\n\n* jk/dumb-http-alternate-fix:\n  http: handle absolute-path alternates from server root\n"
    },
    {
      "commit": "734fd43d3fd5477e6be7c2609a812f5b5c8c5b01",
      "tree": "fc99ea7b40d9dea79ec45276ea255a2e245a0849",
      "parents": [
        "bbc230981d4d264aff51963437ce80112f6efb14",
        "a9ce8526dcc8592429ae73c8f73b29792aa30aa1"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Mon May 25 09:40:08 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Mon May 25 09:40:08 2026 +0900"
      },
      "message": "Merge branch \u0027jk/pretty-no-strbuf-presizing\u0027\n\nRemove ineffective strbuf presizing that would have computed an\nallocation that would not have fit in the available memory anyway,\nor too small due to integer wraparound to cause immediate automatic\ngrowing.\n\n* jk/pretty-no-strbuf-presizing:\n  pretty: drop strbuf pre-sizing from add_rfc2047()\n"
    },
    {
      "commit": "bbc230981d4d264aff51963437ce80112f6efb14",
      "tree": "ba500f2275d37b744933750df0d3566ebd43aa01",
      "parents": [
        "5830a84a1425a004a4a6377110a9fa9513c514ce",
        "61f711de4b0fda3464ef54637b3600a6a5aab214"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Mon May 25 09:40:07 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Mon May 25 09:40:07 2026 +0900"
      },
      "message": "Merge branch \u0027ag/sequencer-remove-unused-struct-member\u0027\n\nCode clean-up.\n\n* ag/sequencer-remove-unused-struct-member:\n  sequencer: remove todo_add_branch_context.commit\n"
    },
    {
      "commit": "5830a84a1425a004a4a6377110a9fa9513c514ce",
      "tree": "445974f5b12d9318e8039906acf751ae45596599",
      "parents": [
        "ed54ca14f4fda09d7dbf794d63e9217d31ed1448",
        "d654777d73061b112c7ed7bad604b72019f5aafa"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Mon May 25 09:40:07 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Mon May 25 09:40:07 2026 +0900"
      },
      "message": "Merge branch \u0027mm/diff-U-takes-no-negative-values\u0027\n\nThe command line parser for \"git diff\" learned a few options take\nonly non-negative integers.\n\n* mm/diff-U-takes-no-negative-values:\n  parse-options: clarify what \"negated\" means for PARSE_OPT_NONEG\n  xdiff: guard against negative context lengths\n  diff: reject negative values for -U/--unified\n  diff: reject negative values for --inter-hunk-context\n"
    },
    {
      "commit": "ed54ca14f4fda09d7dbf794d63e9217d31ed1448",
      "tree": "51595ea4efa6ee3de0e77d0a5a948653bc051a11",
      "parents": [
        "0d5b240d73ffe8b66fe22dbe166329f1b27b5fe7",
        "bd40c65bbc98eb1244d7f91e7265af0aa21e4404"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Mon May 25 09:40:07 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Mon May 25 09:40:07 2026 +0900"
      },
      "message": "Merge branch \u0027dk/doc-exclude-is-shared-per-repo\u0027\n\nDocument the fact that .git/info/exclude is shared across worktrees\nlinked to the same repository.\n\n* dk/doc-exclude-is-shared-per-repo:\n  ignore: note info/exclude lives in GIT_COMMON_DIR, not GIT_DIR\n"
    },
    {
      "commit": "0d5b240d73ffe8b66fe22dbe166329f1b27b5fe7",
      "tree": "3ec0f071169e926fc80dbdaba2cd1930fa8f0b97",
      "parents": [
        "6a4418c36d6bad69a599044b3cf49dcbd049cb45",
        "93e5b1680e30650ceca889a56429a055f17033bd"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Mon May 25 09:40:07 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Mon May 25 09:40:07 2026 +0900"
      },
      "message": "Merge branch \u0027kk/paint-down-to-common-optim\u0027\n\n\"git merge-base\" optimization.\n\n* kk/paint-down-to-common-optim:\n  commit-reach: early exit paint_down_to_common for single merge-base\n  commit-reach: introduce merge_base_flags enum\n"
    },
    {
      "commit": "48513e05e2f226c85a9b88893630c8ae28409772",
      "tree": "9113174facd05c42c0f286a7cf93781294ae6bd4",
      "parents": [
        "94f057755b7941b321fd11fec1b2e3ca5313a4e0"
      ],
      "author": {
        "name": "Adam Johnson",
        "email": "me@adamj.eu",
        "time": "Fri May 22 23:12:25 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 24 18:43:22 2026 +0900"
      },
      "message": "stash: reuse cached index entries in --patch temporary index\n\n`git stash -p` prepares the interactive selection by creating a\ntemporary index at HEAD, switching `GIT_INDEX_FILE` to it, and then\nrunning the `add -p` machinery.\n\nThat temporary index was created by running `git read-tree HEAD`.  The\nresulting index had no useful cached stat data or fsmonitor-valid bits\nfrom the real index.  When `run_add_p()` refreshed that temporary index\nbefore showing the first prompt, it could end up lstat(2)-ing every\ntracked file, even in a repository where `git diff` and `git restore -p`\ncan use fsmonitor to avoid that work.\n\nCreate the temporary index in-process instead.  Use `unpack_trees()` to\nreset the real index contents to HEAD while writing the result to the\ntemporary index path.  For paths whose index entries already match HEAD,\n`oneway_merge()` reuses the existing cache entries, preserving their\ncached stat data and `CE_FSMONITOR_VALID` state.\n\nThis makes the refresh performed by `run_add_p()` behave like the one\nused by `git restore -p`: unchanged paths can be skipped via fsmonitor\ninstead of being scanned again.\n\nIn a 206k file repository with `core.fsmonitor` enabled and a one-line\nchange in one file, time to first prompt dropped from 34.774 seconds to\n0.659 seconds. The new perf test file demonstrates similar improvements,\nwith maen times for without- and with-fsmonitor cases dropping from 6.90\nand 6.83 seconds to 0.55 and 0.28 seconds, respectively.\n\nSigned-off-by: Adam Johnson \u003cme@adamj.eu\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "456efac53b088759abdadb6a33fa9bebdd9945b7",
      "tree": "e00f98a28795232ec7322075199861fb64170d61",
      "parents": [
        "2b8d07ef918404bbe4a63dc266be0596519bc64e"
      ],
      "author": {
        "name": "Taylor Blau",
        "email": "me@ttaylorr.com",
        "time": "Fri May 22 18:24:37 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 24 18:41:07 2026 +0900"
      },
      "message": "path-walk: support `combine` filter\n\nThe `combine` filter takes the intersection of its children, that is:\nobjects are shown only when all child filters would admit the object.\n\nThe preceding patches added support for many individual filter types.\nEnable users to compose these filters by implementing support for the\n`combine` filter type.\n\nMapping intersection onto path_walk_info works because every supported\nchild filter is a monotonic restriction:\n\n - `blob:none`, `tree:0` unconditionally clear `info-\u003eblobs` and (for\n   `tree:0`) `info-\u003etrees`; clearing an already-cleared flag is a\n   no-op.\n\n - `object:type\u003dX` is now expressed as an AND of each type flag with the\n   filtered type, so applying multiple such filters only refines the\n   existing set rather than overwrites it.\n\n - `blob:limit\u003dN` has to compose too: the intersection of \"size \u003c L1\"\n   and \"size \u003c L2\" is \"size \u003c min(L1, L2)\".\n\n   Update the `LOFC_BLOB_LIMIT` handler to take the running minimum when\n   `info-\u003eblob_limit` is already set, so a combined filter with, e.g.,\n   both \"blob:limit\u003d10\" and \"blob:limit\u003d5\" produces a limit of 5\n   regardless of ordering.\n\n - `sparse:oid` is left unchanged. A `combine` filter that includes a\n   `sparse:oid` is allowed at most once, since the existing handler\n   refuses to overwrite `info-\u003epl`. Two `sparse:oid` filters in a single\n   `combine` would be unusual and are rejected with a warning, matching\n   the standalone `sparse:oid` behavior.\n\nImplementation-wise, the existing `prepare_filters()` called\n`list_objects_filter_release()` inside each case branch. That works fine for\ntop-level filters, but `combine` filters need to recurse over its child\nfilters without releasing each one in turn (since the parent\u0027s release\niterates the sub array). Split `prepare_filters()` into a recursive helper\nthat performs only the mutation, plus a thin wrapper that calls the helper\nand then releases the top-level filter once.\n\nThe `LOFC_COMBINE` case in the helper just walks `sub_nr` and recurses;\nchild filters are released by the wrapper\u0027s single\n`list_objects_filter_release()` call on the parent (which itself recursively\nreleases each sub-filter, the same way it always has).\n\nIf any sub-filter is unsupported (e.g. \"tree:1\", \"sparse:\u003cpath\u003e\", or a\nnot-yet-supported choice), the recursion bubbles a failure up and the\nexisting pack-objects/backfill fallback paths kick in.\n\nAdd coverage in t6601:\n\n  - \"combine:blob:none+tree:0\" collapses to \"tree:0\"\n\n  - \"combine:object:type\u003dblob+blob:limit\u003d3\" yields only the blobs\n    smaller than three bytes\n\n  - \"combine:object:type\u003dblob+object:type\u003dtree\" intersects to empty\n\n  - \"combine:tree:1+blob:none\" reports the \"tree:1\" error.\n\nUpdate Documentation/git-pack-objects.adoc to add combine to the\nlist of supported --filter forms.\n\nSigned-off-by: Taylor Blau \u003cme@ttaylorr.com\u003e\nSigned-off-by: Derrick Stolee \u003cstolee@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "2b8d07ef918404bbe4a63dc266be0596519bc64e",
      "tree": "a58caa2ece5b2d98683518836f4df9cefab24a6d",
      "parents": [
        "5111520e2a140b80f60565c579b694b8d95eee01"
      ],
      "author": {
        "name": "Taylor Blau",
        "email": "me@ttaylorr.com",
        "time": "Fri May 22 18:24:36 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 24 18:41:07 2026 +0900"
      },
      "message": "path-walk: support `object:type` filter\n\nThe `object:type` filter accepts only objects of a single type; it is\nthe second member of the object-info-only filter family that bitmap\ntraversal already supports.\n\nLike `blob:none` and `tree:0`, it can be evaluated with nothing more\nthan the object\u0027s type, which is exactly the granularity path-walk\u0027s\nexisting info-\u003e{commits,trees,blobs,tags} flags already control.\n\nMap `LOFC_OBJECT_TYPE` in `prepare_filters()` by AND-ing each flag\nagainst the filtered type. A single `object:type\u003dX` filter\napplied to the default info (all flags \u003d 1) leaves `info-\u003eX \u003d 1` and\nall the others 0, which is what we want.\n\nUsing an AND rather than straight assignment prepares us for a\nsubsequent change to implement combined object filters.\n\nThe path-walk machinery is mostly already wired for the per-type\ndistinction:\n\n - `walk_path()` calls `path_fn` for a batch only when the corresponding\n   `info-\u003eX` flag is set, so unwanted types are silently not reported.\n\n - `add_tree_entries()` skips tree entries of type `OBJ_BLOB` when\n   `info-\u003eblobs` is unset, so we don\u0027t even allocate paths for them.\n\n - The commit-walk loop short-circuits the root-tree fetch when\n   `!info-\u003etrees \u0026\u0026 !info-\u003eblobs`, so commit-only filters don\u0027t descend\n   into trees at all.\n\nBut there are a couple of side effects of the \"trees off, blobs on\" case\nthat need fixing:\n\n 1. \u0027setup_pending_objects()\u0027 previously skipped pending trees as soon\n    as `info-\u003etrees` was zero. For \u0027object:type\u003dblob\u0027 the call site\n    needs those pending trees: a lightweight tag pointing to a tree, or\n    an annotated tag whose peeled target is a tree, can both reach\n    blobs that are otherwise unreachable from any commit\u0027s root tree.\n    Loosen the gate to \"if (!info-\u003etrees \u0026\u0026 !info-\u003eblobs) continue\" and\n    similarly retrieve the root_tree_list whenever either trees or\n    blobs are wanted.\n\n 2. The revision machinery\u0027s `handle_commit()` drops pending trees when\n    `revs-\u003etree_objects` is zero (see the \u0027OBJ_TREE\u0027 handler in\n    revision.c), so by the time path-walk sees the pending list\n    after `prepare_revision_walk()` the tree-bearing pendings would\n    already be gone. Fix this by setting\n\n        revs-\u003etree_objects \u003d info-\u003etrees || info-\u003eblobs\n\n    so pending trees survive `prepare_revision_walk()` whenever we\n    need to walk into them. Path-walk still resets tree_objects to\n    zero immediately after `prepare_revision_walk()` returns, so the\n    rev-walk itself never enumerates trees redundantly with\n    path-walk\u0027s own descent.\n\nAdd coverage in t6601 for each of the four `object:type` values. The\n\u0027object:type\u003dblob\u0027 test in particular asserts that file2 and child/file\n(both reachable only through tag-pointed trees) show up in the output,\nexercising the pending-tree fix.\n\nUpdate Documentation/git-pack-objects.adoc to add object:type to\nthe list of supported --filter forms.\n\nSigned-off-by: Taylor Blau \u003cme@ttaylorr.com\u003e\nSigned-off-by: Derrick Stolee \u003cstolee@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "5111520e2a140b80f60565c579b694b8d95eee01",
      "tree": "c122c9025cb246042cb03bbdec68b00dc23d1e70",
      "parents": [
        "5c21575ecfe8dad297adfc043d9553165b523579"
      ],
      "author": {
        "name": "Taylor Blau",
        "email": "me@ttaylorr.com",
        "time": "Fri May 22 18:24:35 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 24 18:41:07 2026 +0900"
      },
      "message": "path-walk: support `tree:0` filter\n\nThe `tree:0` object filter omits all trees and blobs from the result,\nkeeping only commits and tags. Consequently, this filter type should\nhas a fairly straightforward integration with path-walk, as the decision\nto include an object depends only on its type and does not depend on any\npath-sensitive state.\n\nMapping it onto `path_walk_info` is direct: set `info-\u003etrees \u003d 0` and\n`info-\u003eblobs \u003d 0` in `prepare_filters()` when the `LOFC_TREE_DEPTH`\nchoice is requested with depth zero. The existing code already plumbs\nthose flags through the rest of the walk:\n\n - \u0027walk_objects_by_path()\u0027 sets `revs-\u003eblob_objects \u003d info-\u003eblobs` and\n   `revs-\u003etree_objects \u003d info-\u003etrees` before `prepare_revision_walk()`,\n   so the revision walk doesn\u0027t try to enumerate trees or blobs itself.\n\n - The commit-walk loop short-circuits the root-tree fetch with\n   \"if (!info-\u003etrees \u0026\u0026 !info-\u003eblobs) continue;\", so we never even\n   look up the root tree, let alone descend into it.\n\n - `setup_pending_objects()` skips pending trees and blobs based on\n   the same flags.\n\nThis means the path-walk doesn\u0027t allocate or expand any tree structures\nat all under `tree:0`, which matches the intended behavior of the\nfilter.\n\nHowever, this requires first fixing some issues with how the path-walk\nAPI handles directly-requested trees _and_ trees requested through\nlightweight tags. These changes create substantial updates to\nt6601-path-walk.sh, which the previous change highlighted as a problem\nby tagging otherwise-unreachable trees and having them not appear in the\noutput.\n\nNon-zero tree-depth filters are not supported. Those depend on the depth\nat which a tree is visited, which is a path-walk concept the filter\nmachinery doesn\u0027t currently share with the path-walk API. Reject them in\n`prepare_filters()` with a helpful error and let pack-objects fall back\nto the regular traversal, the same way it already does for unsupported\nfilters.\n\nAdd coverage in t6601 for both `--all` and a single-branch case to\nconfirm that no trees or blobs are emitted, and a separate test that\n`tree:1` is rejected with the expected error message. Place the new\ntests before \"setup sparse filter blob\" so they run on the original set\nof refs, before the orphan branch that the sparse-tree tests create.\n\nSigned-off-by: Taylor Blau \u003cme@ttaylorr.com\u003e\nSigned-off-by: Derrick Stolee \u003cstolee@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "5c21575ecfe8dad297adfc043d9553165b523579",
      "tree": "62f7a56374ee947ddc499f3d6278ebb27e919987",
      "parents": [
        "2dc858e69e963b6c4501e1fc234938bea54c1248"
      ],
      "author": {
        "name": "Derrick Stolee",
        "email": "stolee@gmail.com",
        "time": "Fri May 22 18:24:34 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 24 18:41:06 2026 +0900"
      },
      "message": "t6601: tag otherwise-unreachable trees\n\nThe tests in t6601-path-walk.sh demonstrate the behavior of the\npath-walk API under different conditions. One thing that I noticed while\nupdating the behavior of directly-requested objects is that we don\u0027t\nactually emit tagged trees. This was previously not noticed due to those\ntagged trees actually being reachable from commits that we are including\nin the path-walk.\n\nUpdate the test setup to have tree-tag and tree-tag2 point to trees that\nare otherwise unreachable.\n\nIt is worth noting that this does not meaningfully change any of the\nother test cases, demontrating the bug.\n\nSigned-off-by: Derrick Stolee \u003cstolee@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "2dc858e69e963b6c4501e1fc234938bea54c1248",
      "tree": "4342942facb19937ef3d0b3d08dd86118ea8f7f0",
      "parents": [
        "8ff8de76162387f1adcd01c159ada9b74987cdf2"
      ],
      "author": {
        "name": "Derrick Stolee",
        "email": "stolee@gmail.com",
        "time": "Fri May 22 18:24:33 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 24 18:41:06 2026 +0900"
      },
      "message": "pack-objects: support sparse:oid filter with path-walk\n\nThe --filter\u003dsparse:\u003coid\u003e option to \u0027git pack-objects\u0027 allows focusing\nan object set to a sparse-checkout definition. This reduces the set of\nmatching blobs while retaining all reachable trees. No server currently\nsupports fetching with this filter because it is expensive to compute\nand reachability bitmaps do not help without a significant effort to\nextend the bitmap feature to store bitmaps for each supported sparse-\ncheckout definition.\n\nWithout focusing on serving fetches and clones with these filters, there\nare still benefits that could be realized by making this faster. With\nthe sparse index, it\u0027s more realistic now than ever to be able to\noperate a local clone that was bootstrapped by a packfile created with\na sparse filter, because the missing trees are not needed to move a\nsparse-checkout from one commit to another or to view the history of any\npath in scope. Such clones could perhaps be bootstrapped by partial\nbundles.\n\nPreviously, constructing these sparse packs has been incredibly\ncomputationally inefficient. The revision walk that explores which\nobjects are in scope spends a lot of time checking each object to see if\nit matches the sparse-checkout patterns, causing quadratic behavior\n(number of objects times number of sparse-checkout patterns). This\nimproves somewhat when using cone-mode sparse-checkout patterns that can\nuse hashtables and prefix matches to determine containment. However, the\ncheck per object is still too expensive for most cases.\n\nThis is where the path-walk feature comes in. We can proceed as normal\nby placing objects in bins by path and _then_ check a group of objects\nall at once. Since sparse:\u003coid\u003e only restricts blobs, the path-walk must\ninclude all reachable trees while using the cone-mode patterns to skip\nblobs at paths outside the sparse scope. This establishes a baseline for\na potential future \"treesparse:\u003coid\u003e\" filter that would also restrict\ntrees, but introducing such a new filter is deferred to a later change.\n\nThe implementation here is focused around loading the sparse-checkout\npatterns from the provided object ID and checking that the patterns are\nindeed cone-mode patterns. We can then load the correct pattern list\ninto the path walk context and use the logic that already exists from\nbff45557675 (backfill: add --sparse option, 2025-02-03), though that\nfeature loads sparse-checkout patterns from the worktree\u0027s local\nsettings and also restricts tree objects. We use a combination of errors\nand warnings to signal problems during this load. The difference is that\nerrors are likely fatal for the non-path-walk version while the warnings\nare probably just implementation details for the path-walk version and\nthe \u0027git pack-objects\u0027 command can fall back to the revision walk\nversion.\n\nNow that the SEEN flag is deferred until after pattern checks (from the\nprevious commit), handle the case where a tree with a shared OID appears\nat both an out-of-cone and in-cone path. When trees are not being pruned\n(pl_sparse_trees \u003d\u003d 0), the path-walk re-walks the tree at the in-cone\npath so that in-cone blobs within it are discovered. The new tests in\nt5317 and t6601 demonstrate this behavior and would fail without these\nchanges.\n\nThe performance test p5315 shows the impact of this change when using\nsparse filters:\n\nTest                                              HEAD~1     HEAD\n----------------------------------------------------------------------\n5315.10: repack (sparse:oid)                      77.98    77.47  -0.7%\n5315.11: repack size (sparse:oid)                187.5M   187.4M  -0.0%\n5315.12: repack (sparse:oid, --path-walk)         77.91    31.41 -59.7%\n5315.13: repack size (sparse:oid, --path-walk)   187.5M   161.1M -14.1%\n\nThese performance tests were run on the Git repository. The --path-walk\nfeature shows meaningful space savings (14% smaller for sparse packs)\nand dramatic time savings (60% faster) by leveraging the path-walk\u0027s\nability to skip blobs outside the sparse scope.\n\nCo-authored-by: Taylor Blau \u003cme@ttaylorr.com\u003e\nSigned-off-by: Taylor Blaue \u003cme@ttaylorr.com\u003e\nSigned-off-by: Derrick Stolee \u003cstolee@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "8ff8de76162387f1adcd01c159ada9b74987cdf2",
      "tree": "31482d4dacc2bbfcc711f03984a16abf6a42775e",
      "parents": [
        "f1b5d3da163f90093ab4f1816df24be54e75a1d9"
      ],
      "author": {
        "name": "Derrick Stolee",
        "email": "stolee@gmail.com",
        "time": "Fri May 22 18:24:32 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 24 18:41:06 2026 +0900"
      },
      "message": "path-walk: add pl_sparse_trees to control tree pruning\n\nThe path-walk API prunes trees and blobs when a sparse-checkout pattern\nlist is provided, which is the correct behavior for \u0027git backfill\n--sparse\u0027 since it only needs to fill in objects at paths within the\nsparse cone.\n\nHowever, a future change will use the path-walk API with a sparse:\u003coid\u003e\nfilter that restricts only blobs while retaining all reachable trees.\nTo support both behaviors, add a \u0027pl_sparse_trees\u0027 flag to\npath_walk_info. When set (as in \u0027git backfill --sparse\u0027 and the\n--stdin-pl test helper mode), the sparse patterns prune both trees and\nblobs. When unset, only blobs are filtered and all trees are walked and\nreported.\n\nAdditionally, move the SEEN flag assignment in add_tree_entries() to\nafter the sparse pattern and pathspec checks. Previously, SEEN was set\nimmediately upon discovering an object, before checking whether its path\nmatched the sparse patterns. When the same object ID appeared at\nmultiple paths (e.g. sibling directories with identical contents), the\nfirst path to be visited would mark the object as SEEN. If that path was\noutside the sparse cone, the object would be skipped there but also\nnever discovered at its in-cone path.\n\nBy deferring the SEEN flag until after the checks pass, objects that are\nskipped due to sparse filtering remain discoverable at other paths where\nthey may be in scope.\n\nSigned-off-by: Derrick Stolee \u003cstolee@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "f1b5d3da163f90093ab4f1816df24be54e75a1d9",
      "tree": "e142378daa292245f55e391edce55904c7e5e353",
      "parents": [
        "bf24de4b7cd5f30b1539c8e8a25cca5b92d9b621"
      ],
      "author": {
        "name": "Derrick Stolee",
        "email": "stolee@gmail.com",
        "time": "Fri May 22 18:24:31 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 24 18:41:06 2026 +0900"
      },
      "message": "path-walk: support blob size limit filter\n\nExtend the path-walk API to handle the \u0027blob:limit\u003d\u003csize\u003e\u0027 object\nfilter natively. This filter omits blobs whose size is equal to or\ngreater than the given limit, matching the semantics used by the\nlist-objects-filter machinery.\n\nWhen revs-\u003efilter.choice is LOFC_BLOB_LIMIT, the prepare_filters()\nmethod stores the limit value in info-\u003eblob_limit and clears the filter\nfrom revs. If the limit is zero, this degenerates to blob:none (all\nblobs excluded), so info-\u003eblobs is set to 0 instead.\n\nDuring walk_path(), blob batches are filtered before being delivered to\nthe callback: each blob\u0027s size is checked via odb_read_object_info(),\nand only blobs strictly smaller than the limit are included. Blobs whose\nsize cannot be determined (e.g. missing in a partial clone) are\nconservatively included, matching the existing filter behavior. Empty\nbatches after filtering are skipped entirely.\n\nThe check for inclusion in the path batch looks a little strange at\nfirst glance. We use odb_read_object_info() to read the object\u0027s size.\nBased on all of the assumptions to this point, this _should_ return\nOBJ_BLOB. Since we are focused on the size filter, we use a\nshort-circuited OR (||) to skip the size check if that method returns a\ndifferent object type.\n\nNotice that this inspection of object sizes requires the content to be\npresent in the repository. The odb_read_object_info() call will download\na missing blob on-demand. This means that the use of the path-walk API\nwithin \u0027git backfill\u0027 would not operate nicely with this filter type.\nThe intention of that command is to download missing blobs in batches.\nDownloading objects one-by-one would go against the point. Update the\nvalidation in \u0027git backfill\u0027 to add its own compatibility check on top\nof path_walk_filter_compatible().\n\nAdd tests for blob:limit\u003d0 (equivalent to blob:none) and blob:limit\u003d3\n(which exercises partial filtering within a batch where some blobs are\nkept and others are excluded).\n\nCo-authored-by: Taylor Blau \u003cme@ttaylorr.com\u003e\nSigned-off-by: Taylor Blau \u003cme@ttaylorr.com\u003e\nSigned-off-by: Derrick Stolee \u003cstolee@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "bf24de4b7cd5f30b1539c8e8a25cca5b92d9b621",
      "tree": "bacda4a1d2fba3eb7d650e313dc864a511b05895",
      "parents": [
        "6d87f0e8a3bf3d718c7aaf3657cf3ce73c3bd026"
      ],
      "author": {
        "name": "Derrick Stolee",
        "email": "stolee@gmail.com",
        "time": "Fri May 22 18:24:30 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 24 18:41:06 2026 +0900"
      },
      "message": "backfill: die on incompatible filter options\n\nThe \u0027git backfill\u0027 command uses the path-walk API in a critical way: it\nuses the objects output from the command to find the batches of missing\nobjects that should be requested from the server. Unlike \u0027git\npack-objects\u0027, we cannot fall back to another mechanism.\n\nThe previous change added the path_walk_filter_compatible() method that\nwe can reuse here. Use it during argument validation in cmd_backfill().\n\nSigned-off-by: Derrick Stolee \u003cstolee@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "6d87f0e8a3bf3d718c7aaf3657cf3ce73c3bd026",
      "tree": "10451d334202fa27e3234b4094a28c3938035cca",
      "parents": [
        "7a7070eebce16f20548bd4685362bca7df6af431"
      ],
      "author": {
        "name": "Derrick Stolee",
        "email": "stolee@gmail.com",
        "time": "Fri May 22 18:24:29 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 24 18:41:06 2026 +0900"
      },
      "message": "path-walk: support blobless filter\n\nThe \u0027git pack-objects\u0027 command can opt-in to using the path-walk API for\nscanning the objects. Currently, this option is dynamically disabled if\ncombined with \u0027--filter\u003d\u003cX\u003e\u0027, even when using a simple filter such as\n\u0027blob:none\u0027 to signal a blobless packfile. This is a common scenario for\nrepos at scale, so is worth integrating.\n\nAlso, users can opt-in to the \u0027--path-walk\u0027 option by default through\nthe pack.usePathWalk\u003dtrue config option. When using that in a blobless\npartial clone, the following warning can appear even though the user did\nnot specify either option directly:\n\n  warning: cannot use --filter with --path-walk\n\nTeach the path-walk API to handle the \u0027blob:none\u0027 object filter\nnatively. When revs-\u003efilter.choice is LOFC_BLOB_NONE, the path-walk\nsets info-\u003eblobs to 0 (skipping all blob objects) and clears the\nfilter from revs so that prepare_revision_walk() does not reject the\nconfiguration.\n\nThis check is implemented in the static prepare_filters() method, which\nwill simultaneously check if the input filters are compatible and will\nmake the appropriate mutations to the path_walk_info and filters if the\npath_walk_info is non-NULL. This allows us to use this logic both in the\nAPI method path_walk_filter_compatible() for use in\nbuiltin/pack-objects.c and as a prep step in walk_objects_by_path().\n\nUpdate the test helper (test-path-walk) to accept --filter\u003d\u003cspec\u003e\nas a test-tool option (before \u0027--\u0027), applying it to revs after\nsetup_revisions() to avoid the --objects requirement check. We can also\nrevert recent GIT_TEST_PACK_PATH_WALK overrides in t5620.\n\nAlso switch test-path-walk from REV_INFO_INIT with manual repo\nassignment to repo_init_revisions(), which properly initializes\nthe filter_spec strbuf needed for filter parsing.\n\nAdd tests for blob:none with --all and with a single branch.\n\nThe performance test p5315 shows the impact of this change when using\nblobless filters:\n\nTest                                           HEAD~1     HEAD\n---------------------------------------------------------------------\n5315.6: repack (blob:none)                      13.53   13.87  +2.5%\n5315.7: repack size (blob:none)                137.7M  137.8M  +0.1%\n5315.8: repack (blob:none, --path-walk)         13.51   23.43 +73.4%\n5315.9: repack size (blob:none, --path-walk)   137.7M  115.2M -16.3%\n\nThese performance tests were run on the Git repository. The --path-walk\nfeature shows meaningful space savings (16% smaller for blobless packs)\nat the cost of increased computation time due to the two compression\npasses. This data demonstrates that the feature is engaged and provides\nreal compression benefits when --no-reuse-delta forces fresh deltas.\n\nCo-Authored-by: Taylor Blau \u003cme@ttaylorr.com\u003e\nSigned-off-by: Taylor Blau \u003cme@ttaylorr.com\u003e\nSigned-off-by: Derrick Stolee \u003cstolee@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "7a7070eebce16f20548bd4685362bca7df6af431",
      "tree": "14adf2449e14bae98072725ef86750c97c4932fe",
      "parents": [
        "5406b62b21e4c24cd2b0ca698b5fb95b4a5816ca"
      ],
      "author": {
        "name": "Derrick Stolee",
        "email": "stolee@gmail.com",
        "time": "Fri May 22 18:24:28 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 24 18:41:06 2026 +0900"
      },
      "message": "path-walk: always emit directly-requested objects\n\nWe are preparing to integrate the path-walk API with some --filter options\nin \u0027git pack-objects\u0027, but there is a subtle issue that is revealed when\nthose are put together and the test suite is run with\nGIT_TEST_PACK_PATH_WALK\u003d1.\n\nWhen a filter reduces the set of requested objects, this results in\nfiltering out directly-requested objects, such as in the download of needed\nblobs in a blobless partial clone.\n\nThe root cause is that the scan of pending objects in the path-walk API\nrespects the filters set in the path_walk_info instead of overriding them\nfor pending objects.\n\nWe can tell that a path is part of the directly-referenced objects if its\npath name starts with \u0027/\u0027 (other paths, including root trees never have this\nstarting character). Create a path_is_for_direct_objects() to make this\nmeaning clear, especially as we add more references in the future as we\nintegrate the path-walk API with partial clone filter options.\n\nSigned-off-by: Derrick Stolee \u003cstolee@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "5406b62b21e4c24cd2b0ca698b5fb95b4a5816ca",
      "tree": "4c05ab129aec1a17b8e8646bbf6c273e9253fd93",
      "parents": [
        "35567889ef7c2f0bdf629a5692340886e98f687f"
      ],
      "author": {
        "name": "Derrick Stolee",
        "email": "stolee@gmail.com",
        "time": "Fri May 22 18:24:27 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 24 18:41:06 2026 +0900"
      },
      "message": "t/perf: add pack-objects filter and path-walk benchmark\n\nAdd p5315-pack-objects-filter.sh to measure the performance of\n\u0027git pack-objects --revs --all\u0027 under different filter and traversal\ncombinations:\n\n * no filter (baseline)\n * --filter\u003dblob:none (blobless)\n * --filter\u003dsparse:oid\u003d\u003coid\u003e (cone-mode sparse)\n\nEach filter scenario is tested both with and without --path-walk,\nproducing paired measurements that show the impact of the path-walk\ntraversal for each filter type as we integrate the --path-walk feature\nwith different --filter options. It currently has no integration so\nfalls back to the standard revision walk. Thus, there are no significant\ndifferences in the current results other than a full repack (and even\nthen, the --path-walk feature is not incredibly different for the\ndefault Git repository):\n\nTest                                             HEAD\n-----------------------------------------------------\n5315.2: repack (no filter)                      27.91\n5315.3: repack size (no filter)                250.7M\n5315.4: repack (no filter, --path-walk)         34.92\n5315.5: repack size (no filter, --path-walk)   220.0M\n5315.6: repack (blob:none)                      13.63\n5315.7: repack size (blob:none)                137.6M\n5315.8: repack (blob:none, --path-walk)         13.48\n5315.9: repack size (blob:none, --path-walk)   137.7M\n5315.10: repack (sparse:oid)                    72.67\n5315.11: repack size (sparse:oid)              187.4M\n5315.12: repack (sparse:oid, --path-walk)       72.47\n5315.13: repack size (sparse:oid, --path-walk) 187.4M\n\nThe sparse filter definition is built automatically by sampling\ndepth-2 directories from the test repository, making the test work\non any repo passed via GIT_PERF_LARGE_REPO. For repos that lack\ndepth-2 directories, a single top-level directory is used; for flat\nrepos, the sparse tests are skipped via prerequisite.\n\nSigned-off-by: Derrick Stolee \u003cstolee@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "35567889ef7c2f0bdf629a5692340886e98f687f",
      "tree": "32d3d22a7ee8d7727cbdd480aaa15f552828e735",
      "parents": [
        "b00c374d471ae74e6158388fbf485b3a989729bd"
      ],
      "author": {
        "name": "Derrick Stolee",
        "email": "stolee@gmail.com",
        "time": "Fri May 22 18:24:26 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 24 18:41:06 2026 +0900"
      },
      "message": "pack-objects: pass --objects with --path-walk\n\nWhen \u0027git pack-objects\u0027 has the --path-walk option enabled, it uses a\ndifferent set of revision walk parameters than normal. For one,\n--objects was previously assumed by the path-walk API and could be\nomitted. We also needed --boundary to allow discovering UNINTERESTING\nobjects to use as delta bases.\n\nWe will be updating the path-walk API soon to work with some filter\noptions. However, the revision machinery will trigger a fatal error:\n\n  fatal: object filtering requires --objects\n\nThe fix is easy: add the --objects option as an argument. This has no\neffect on the path-walk API but does simplify the revision option\nparsing for the objects filter.\n\nWe can remove the comment about \"removing\" the options because they were\nnever removed and instead not added. We still need to disable using\nbitmaps.\n\nSigned-off-by: Derrick Stolee \u003cstolee@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "b00c374d471ae74e6158388fbf485b3a989729bd",
      "tree": "f7b808305fa310e734afcc5db715a4c030020e0b",
      "parents": [
        "0c1ed96fb91d85165884713cffaa67f7ee67034e"
      ],
      "author": {
        "name": "Derrick Stolee",
        "email": "stolee@gmail.com",
        "time": "Fri May 22 18:24:25 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun May 24 18:41:06 2026 +0900"
      },
      "message": "t5620: make test work with path-walk var\n\nThe GIT_TEST_PACK_PATH_WALK test variable allows enabling the\n--path-walk option to \u0027git pack-objects\u0027 by default. This sometimes\nengages the warning that --path-walk is incompatible with the --filter\noption. These tests in t5620 fail due to this warning over stderr in\nthis case. Disable this variable for this moment until these options\nwork together.\n\nSigned-off-by: Derrick Stolee \u003cstolee@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "abcf2dd5b215ff7bad0bb44524f352cd352bda0f",
      "tree": "b7821cbc31fe554195796e191e5e28f619b2f8dc",
      "parents": [
        "3198237bf3ce3c1eae845ac8e13a2da813800c77"
      ],
      "author": {
        "name": "Jeff King",
        "email": "peff@peff.net",
        "time": "Fri May 22 00:43:52 2026 -0400"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri May 22 14:38:41 2026 +0900"
      },
      "message": "transport-helper: fix typo in BUG() message\n\nWe mistakenly refer to the git_connect_service enum as \"_type\" rather\nthan \"_service\". Users should never see this message in practice, but it\nis slightly confusing when reading the code.\n\nReported-by: Patrick Steinhardt \u003cps@pks.im\u003e\nSigned-off-by: Jeff King \u003cpeff@peff.net\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "5c6a41e4b5b60ea397393fb0542c7d67553a105e",
      "tree": "820c313979ea1a5b6442a808427c8fb61754d695",
      "parents": [
        "2757bc8f7bcb2e29da109861560f96b3477b2395"
      ],
      "author": {
        "name": "Kristoffer Haugsbakk",
        "email": "code@khaugsbakk.name",
        "time": "Thu May 21 18:25:58 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri May 22 09:36:20 2026 +0900"
      },
      "message": "doc: hook: don’t self-link via config include\n\nDo not link to git-hook(1) from the config options when we already are\nin that doc.\n\nThis implementation is similar to the updates to git-init(1) and\ngit-commit(1), implemented in [1] and [2], respectively.\n\n† 1: e7b3a768 (doc: git-init: rework config item init.templateDir,\n     2024-03-10)\n† 2: 819fdd6e (doc: convert git commit config to new format, 2025-01-15)\n\nSigned-off-by: Kristoffer Haugsbakk \u003ccode@khaugsbakk.name\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "2757bc8f7bcb2e29da109861560f96b3477b2395",
      "tree": "48157a655408ed4100ae7cde302bd1dcb7c1cad4",
      "parents": [
        "2d2aeb331ea2ba3e46db382738c64e95a5ca3478"
      ],
      "author": {
        "name": "Kristoffer Haugsbakk",
        "email": "code@khaugsbakk.name",
        "time": "Thu May 21 18:25:57 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri May 22 09:36:20 2026 +0900"
      },
      "message": "doc: config: include existing git-hook(1) section\n\nIt is already included in git-hook(1) but missing from git-config(1).\n\nSigned-off-by: Kristoffer Haugsbakk \u003ccode@khaugsbakk.name\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "2d2aeb331ea2ba3e46db382738c64e95a5ca3478",
      "tree": "63d6740f672dfb14a7b528f93fcd96e054c7d955",
      "parents": [
        "c8a3ceaa2f2c01d778e10685fc8de70592eefb2c"
      ],
      "author": {
        "name": "Kristoffer Haugsbakk",
        "email": "code@khaugsbakk.name",
        "time": "Thu May 21 18:25:56 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri May 22 09:36:20 2026 +0900"
      },
      "message": "doc: hook: consistently capitalize Git\n\nSigned-off-by: Kristoffer Haugsbakk \u003ccode@khaugsbakk.name\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "c8a3ceaa2f2c01d778e10685fc8de70592eefb2c",
      "tree": "5bcad3a23cad2bc9405095bfdc4cb10e239a59e5",
      "parents": [
        "6a4418c36d6bad69a599044b3cf49dcbd049cb45"
      ],
      "author": {
        "name": "Kristoffer Haugsbakk",
        "email": "code@khaugsbakk.name",
        "time": "Thu May 21 18:25:55 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri May 22 09:36:19 2026 +0900"
      },
      "message": "doc: hook: remove stray backtick\n\nSigned-off-by: Kristoffer Haugsbakk \u003ccode@khaugsbakk.name\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "6a4418c36d6bad69a599044b3cf49dcbd049cb45",
      "tree": "e77168b0f5c3f1d64658dedabbbaae27cb1764cf",
      "parents": [
        "6358af747e4e328a0cbe542c91e88e1ada2baa16"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri May 22 08:47:06 2026 +0900"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri May 22 08:48:21 2026 +0900"
      },
      "message": "The 7th batch\n\nWith this batch, we have flushed all the topics that need to\nbe merged to \u0027maint\u0027 to make its build healthy.\n\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    }
  ],
  "next": "6358af747e4e328a0cbe542c91e88e1ada2baa16"
}
