)]}'
{
  "log": [
    {
      "commit": "593c42fe075be0c8cd5239b3a2f21c610cbc9798",
      "tree": "36363be0a51e7f7a51aecf929394fd300e76e859",
      "parents": [
        "679a72c6b841baeb138f5c97e88e7e07d744e313"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun Aug 23 18:01:03 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun Aug 23 18:01:47 2026 -0700"
      },
      "message": "The 17th batch\n\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "679a72c6b841baeb138f5c97e88e7e07d744e313",
      "tree": "ed8aa984bd76cecf41fa6636a222b70a6460a1ea",
      "parents": [
        "e8e7bf97fe55adee95fc46550b9667d7c27da1d5",
        "56c9056e30812bbba545d95ed7eb0f5beb089edd"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun Aug 23 18:01:46 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun Aug 23 18:01:46 2026 -0700"
      },
      "message": "Merge branch \u0027kk/merge-base-exhaustion\u0027\n\nThe merge-base computation has been optimized by stopping the walk\nearly when one side\u0027s exclusive commits in the queue are exhausted,\nyielding significant speedups for queries with one-sided histories.\n\n* kk/merge-base-exhaustion:\n  commit-reach: remove commit-date ordering fallback\n  commit-reach: move min_generation check into paint_queue_get()\n  commit-reach: terminate merge-base walk when one paint side is exhausted\n  commit-reach: introduce struct paint_state with per-side counters\n  t6600: add clock-skew topologies and step counts for edge cases\n  commit-reach: add trace2 instrumentation to paint_down_to_common()\n  t6099: add side-exhaustion regression test\n  t6600: add test cases for side-exhaustion edge cases\n  test-lib-functions: improve diagnostic output for trace2 data assertions\n  Documentation/technical: add paint-down-to-common doc\n"
    },
    {
      "commit": "e8e7bf97fe55adee95fc46550b9667d7c27da1d5",
      "tree": "dd9d98055f46873bb912f047382dd5bd52115d49",
      "parents": [
        "6aab7b26a68c27433a99211b98cb900581464467",
        "65cda10d5bbbca7c97e40e3cff5b8c08e182679e"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun Aug 23 18:01:45 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun Aug 23 18:01:45 2026 -0700"
      },
      "message": "Merge branch \u0027js/sequencer-release-odb-before-commit\u0027\n\nThe sequencer has been updated to release the object database before\nspawning \u0027git commit\u0027.  This prevents open file handles from\nblocking auto-maintenance tasks, such as repacking, on systems like\nWindows where open files cannot be easily unlinked.\n\n* js/sequencer-release-odb-before-commit:\n  sequencer: release the ODB before spawning git commit\n"
    },
    {
      "commit": "6aab7b26a68c27433a99211b98cb900581464467",
      "tree": "c68c2b3ce98ffc38843a730493b3961c8beb8703",
      "parents": [
        "a2ef06b1efba885d5ad2d5d5f1e31f1e4d2418c1",
        "b0b304c10a65882a8e36abbb694603648a78edfd"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun Aug 23 18:01:44 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun Aug 23 18:01:44 2026 -0700"
      },
      "message": "Merge branch \u0027hn/send-email-missing-subject-error\u0027\n\nThe error message given by \u0027git send-email\u0027 when a message file is\nmissing a \u0027Subject:\u0027 header has been clarified, and the error string\nis now terminated with a newline so that Perl avoids appending its\ninternal source location data.\n\n* hn/send-email-missing-subject-error:\n  send-email: clarify missing subject error\n"
    },
    {
      "commit": "a2ef06b1efba885d5ad2d5d5f1e31f1e4d2418c1",
      "tree": "b857b93c54b24b0ed2fdb98d603c1ad9c939528b",
      "parents": [
        "10d3ea2469c09f1920f7b5a875594efb5fe64062",
        "ebdd7e10d6935c510154bcfff03b92cd7e972830"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun Aug 23 18:01:43 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun Aug 23 18:01:43 2026 -0700"
      },
      "message": "Merge branch \u0027ps/odb-streams\u0027\n\nThe \u0027struct odb_read_stream\u0027 and \u0027struct odb_write_stream\u0027\nstructures have been consolidated into a single unified \u0027struct\nodb_stream\u0027 structure, simplifying object database streaming APIs\nand enabling streaming of arbitrary object types.\n\n* ps/odb-streams:\n  odb/streaming: unify function names to create new streams\n  odb/streaming: rename `struct input_zstream_data`\n  odb/streaming: rename `struct read_object_fd_data`\n  odb/streaming: consolidate read and write streams\n  odb/streaming: rename `struct odb_read_stream`\n  odb/streaming: support streaming arbitrary object types\n  odb/streaming: drop `is_finished` field\n  odb/streaming: track write stream size in the structure\n"
    },
    {
      "commit": "10d3ea2469c09f1920f7b5a875594efb5fe64062",
      "tree": "8dff1da24500a6f5c1f825287ba5bdd422993f1c",
      "parents": [
        "4b27b7c7077764401f6a465940e3cdf396d33e54",
        "a09c2f2c70f5c06e74218db5190e0b3ca8f84a1e"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun Aug 23 18:01:42 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun Aug 23 18:01:42 2026 -0700"
      },
      "message": "Merge branch \u0027cc/fast-import-usage\u0027\n\nThe usage string of \u0027git fast-import\u0027 has been updated to use the\nparse_options() API for displaying help, and its SYNOPSIS in the\ndocumentation has been standardized to match.\n\n* cc/fast-import-usage:\n  fast-import: remove useless from_stream argument\n  fast-import: use parse_options() for command line options\n  fast-import: use callbacks to parse some options\n  fast-import: use struct option for usage string\n  fast-import: move command state globals into \u0027struct fast_import_state\u0027\n  fast-import: introduce \u0027struct fast_import_state\u0027\n  fast-import: factor out option_*() functions\n  fast-import: use int for some bool flags\n  fast-import: localize \u0027i\u0027 into the \u0027for\u0027 loops using it\n  api-parse-options.adoc: document hidden and OPT_*_F option macros\n  api-parse-options.adoc: document per-option flags\n  parse-options: introduce OPT_HIDDEN_GROUP\n"
    },
    {
      "commit": "4b27b7c7077764401f6a465940e3cdf396d33e54",
      "tree": "f1ed1abd5c277b3d27158d5ea8e6b6b533713e8d",
      "parents": [
        "1a3e64c6c4a623626ff0687008732a8e007e2a1c",
        "245f2a8b2efb1cf93358cd4c143d0a91c23e0e1d"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun Aug 23 18:01:41 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sun Aug 23 18:01:42 2026 -0700"
      },
      "message": "Merge branch \u0027ps/cat-file-remote-object-info-type\u0027\n\nThe \u0027remote-object-info\u0027 command for \u0027git cat-file --batch-command\u0027\nhas been extended to support the \u0027%(objecttype)\u0027 placeholder.\n\n* ps/cat-file-remote-object-info-type:\n  cat-file: unify default format\n  serve: advertise type capability\n  fetch-object-info: parse type from server response\n  protocol-caps: add type support to object-info\n  transport: drop remote object-info fields from transport struct\n  fetch-object-info: die() on the remaining error path\n  fetch-object-info: use dedicated struct for the results\n  fetch-object-info: pass arguments directly instead of a struct\n  fetch-object-info: detect malformed server responses\n  t5701: use test_file_size() to get the size of a file\n"
    },
    {
      "commit": "1a3e64c6c4a623626ff0687008732a8e007e2a1c",
      "tree": "3d973fc783a61185810ae804e86a8b365a2879ed",
      "parents": [
        "3f664917c20733253934d3c4ff8330a7a60f27b7"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Thu Aug 20 07:30:30 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Thu Aug 20 07:30:52 2026 -0700"
      },
      "message": "The 16th batch\n\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "3f664917c20733253934d3c4ff8330a7a60f27b7",
      "tree": "c7d2c765f78ed04489a0b09c341b694d7615f5d4",
      "parents": [
        "2f6614658f13fd70a1a402d5b8ed443daa471be2",
        "4515c86fd95ef8de8a1cbea90bb275538bfc87ee"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Thu Aug 20 07:30:52 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Thu Aug 20 07:30:52 2026 -0700"
      },
      "message": "Merge branch \u0027kh/doc-trailers\u0027\n\nDocumentation for \u0027git interpret-trailers\u0027 has been updated to explain\nthe format of trailer keys (alphanumeric characters and hyphens),\nreplace outdated terminology, define key terms upfront, and document\nhow comment lines in the input are treated.\n\n* kh/doc-trailers:\n  doc: interpret-trailers: document comment line treatment\n  doc: interpret-trailers: rewrite new-trailers paragraphs\n  doc: interpret-trailers: commit to “trailer block” term\n  doc: interpret-trailers: join new-trailers again\n  doc: interpret-trailers: add key format example\n  doc: interpret-trailers: explain key format\n  doc: interpret-trailers: explain the format after the intro\n  doc: interpret-trailers: not just for commit messages\n  doc: interpret-trailers: use “metadata” in Name as well\n  doc: interpret-trailers: replace “lines” with “metadata”\n  doc: interpret-trailers: stop fixating on RFC 822\n"
    },
    {
      "commit": "2f6614658f13fd70a1a402d5b8ed443daa471be2",
      "tree": "e17a10223b364e2586d9401b0f9a273a2d9066d9",
      "parents": [
        "006933a32c31c879f776056315f6dcacd4ec7b2c",
        "e927cfeb21d6a217b708216862deb36f144f064b"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Thu Aug 20 07:30:52 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Thu Aug 20 07:30:52 2026 -0700"
      },
      "message": "Merge branch \u0027ps/odb-make-creation-pluggable\u0027\n\nThe creation of the on-disk data structures for the object database\nhas been made pluggable, allowing future backends to customize their\nsetup.  As part of this, the initialization of the object database\nhas been deferred, and the loading of the loose-object map has been\ndetangled from repository initialization.\n\n* ps/odb-make-creation-pluggable:\n  odb: make creation of on-disk structures pluggable\n  odb/source: introduce function to map source type to name\n  setup: defer object database creation\n  setup: handle ODB-related environment variables in `odb_new()`\n  setup: detangle loading of loose object maps\n  loose: load loose object map for the correct source\n"
    },
    {
      "commit": "006933a32c31c879f776056315f6dcacd4ec7b2c",
      "tree": "bf457a4bf65fda0fddedbdcecd19af3ccefc67e5",
      "parents": [
        "dea0ea3582e6980ddbc1173cc8e3e9f9db91cde0",
        "25285a6763543242514f3a58c504fd80e9996df2"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Thu Aug 20 07:30:51 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Thu Aug 20 07:30:51 2026 -0700"
      },
      "message": "Merge branch \u0027hn/branch-delete-merged\u0027\n\nThe \u0027git branch\u0027 command has been taught the \u0027--delete-merged\u0027 option\nto remove local branches that are already merged into their tracked\nremote-tracking branches.\n\n* hn/branch-delete-merged:\n  branch: add --dry-run for --delete-merged\n  branch: add branch.\u003cname\u003e.deleteMerged opt-out\n  branch: add --delete-merged \u003cpattern\u003e\n  branch: prepare delete_branches for a bulk caller\n  branch: let delete_branches skip unmerged branches on bulk refusal\n  branch: convert delete_branches() to a flags argument\n  branch: add --forked filter for --list mode\n"
    },
    {
      "commit": "dea0ea3582e6980ddbc1173cc8e3e9f9db91cde0",
      "tree": "cc0de6502077cc4549ce21281b0db4f898c67e55",
      "parents": [
        "e23356ae1afe0e6775aa27c479116bfb7d09272b"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 18 09:31:26 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 18 09:31:36 2026 -0700"
      },
      "message": "The 15th batch\n\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "e23356ae1afe0e6775aa27c479116bfb7d09272b",
      "tree": "b6db4040fcfcaf82b1d11f0c77a3c7eee13710ba",
      "parents": [
        "3beb8bb74277bf0817a09651bccd8f9d9d156ce9",
        "f70281521a06894e51b5acfa9abbbb884c05d980"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 18 09:31:36 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 18 09:31:36 2026 -0700"
      },
      "message": "Merge branch \u0027hn/bisect-reset-when-found\u0027\n\nThe \u0027git bisect\u0027 command has been taught a\n\u0027--reset-when-found[\u003d\u003cwhere\u003e]\u0027 option that tells the command to\nautomatically run \u0027git bisect reset\u0027 to jump back to the original\nstate or to the found culprit.\n\n* hn/bisect-reset-when-found:\n  bisect: add --reset-when-found to leave when done\n  bisect: let bisect_reset() optionally check out quietly\n"
    },
    {
      "commit": "3beb8bb74277bf0817a09651bccd8f9d9d156ce9",
      "tree": "7ec469f78bde7fcf13aa64990a98c3ba9c692502",
      "parents": [
        "1428b15baf7e755d7841d899cf20f039a079ec6f",
        "5bd4f43456aae6fa942eb6c6ace6244d09e01d08"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 18 09:31:36 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 18 09:31:36 2026 -0700"
      },
      "message": "Merge branch \u0027ps/writev\u0027\n\nA compatibility wrapper for writev(3p) has been reintroduced,\nincluding fixes for CMake build and \u0027MAX_IO_SIZE\u0027 limits on NonStop.\nCalls to write(3p) in send_sideband() and cat_blob() have been\nrefactored to use writev(3p) wrappers to reduce syscall overhead.\n\n* ps/writev:\n  fast-import: use writev(3p) to send cat-blob responses\n  sideband: use writev(3p) to send pktlines\n  wrapper: properly handle MAX_IO_SIZE in writev(3p)\n  wrapper: introduce writev(3p) wrappers\n  compat/posix: introduce writev(3p) wrapper\n"
    },
    {
      "commit": "1428b15baf7e755d7841d899cf20f039a079ec6f",
      "tree": "754aa56d09d321f5aa677a3a06d2be85e8001eab",
      "parents": [
        "18e66859d87fb4b76599f73460b54f0848c76b16",
        "0dc68f404af778338a4090a857d51f16b9ed54b8"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 18 09:31:35 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 18 09:31:36 2026 -0700"
      },
      "message": "Merge branch \u0027kh/doc-refs-migrate-limitations\u0027\n\nThe known limitations of the ref format migration in \u0027git refs\u0027 have\nbeen moved to be displayed as a warning admonition directly under the\ndescription of the \u0027migrate\u0027 subcommand, improving visibility.  A\nreference to \u0027git-maintenance\u0027 has also been corrected to use the\n\u0027linkgit\u0027 macro.\n\n* kh/doc-refs-migrate-limitations:\n  doc: refs: linkgit to git-maintenance(1)\n  doc: refs: put ref migration warning under the command\n"
    },
    {
      "commit": "18e66859d87fb4b76599f73460b54f0848c76b16",
      "tree": "b1690ceb94ba97a889573fdecd437dabe62cc004",
      "parents": [
        "230296d5603f39f1b2ef9fd3d0eb23e0f7ae88dc"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sat Aug 15 09:20:13 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sat Aug 15 09:20:27 2026 -0700"
      },
      "message": "The 14th batch\n\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "230296d5603f39f1b2ef9fd3d0eb23e0f7ae88dc",
      "tree": "a59b087ca08e084e3d1a2c9106216e81e710ca70",
      "parents": [
        "90d7103396e50617f76fe5f49043266c3f0b827a",
        "94cf62176ec5e416b7748d60b59bf8f6aa6dd7b3"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sat Aug 15 09:20:27 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sat Aug 15 09:20:27 2026 -0700"
      },
      "message": "Merge branch \u0027jc/add-resolved\u0027\n\n\u0027git add\u0027 has been taught a new \u0027--resolved\u0027 option to stage\nconflict-resolved paths, while leaving unrelated local changes\nunstaged.  It scans the unmerged paths for leftover conflict\nmarkers and aborts if any are found.\n\n* jc/add-resolved:\n  add: introduce \u0027--resolved\u0027 option\n  read-cache: add remove_file_from_index_with_flags()\n  merge-ll: consolidate conflict marker scanning logic\n  read-cache: reindent\n"
    },
    {
      "commit": "90d7103396e50617f76fe5f49043266c3f0b827a",
      "tree": "6b7bcd76edd3e2547069f446b97c39f378f50e5c",
      "parents": [
        "8b34c1f35249c02f42447902ffcd0745bdc58e70",
        "d5dd17756dce04fadb5f787376aabfae4d859bb4"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sat Aug 15 09:20:27 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sat Aug 15 09:20:27 2026 -0700"
      },
      "message": "Merge branch \u0027kl/t7528-ssh-agent-for-csh-users\u0027\n\nThe \u0027ssh-agent\u0027 tests in \u0027t7528\u0027 have been fixed to work when the\nuser\u0027s login shell is csh-like, by explicitly passing \u0027-s\u0027 to\n\u0027ssh-agent\u0027 to force Bourne shell syntax.\n\n* kl/t7528-ssh-agent-for-csh-users:\n  t7528: fix failure under csh\n"
    },
    {
      "commit": "8b34c1f35249c02f42447902ffcd0745bdc58e70",
      "tree": "05cdf0a3f2d69754b30494395ca863301c7b0c0d",
      "parents": [
        "f2f3a37b68be969db7a8f02366c574770d7f17e1",
        "c4244bdfe6d28ed552e10f1e37387978549b36ed"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sat Aug 15 09:20:26 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sat Aug 15 09:20:27 2026 -0700"
      },
      "message": "Merge branch \u0027tn/packfile-uri-concurrency\u0027\n\nConcurrent downloads of packfiles via packfile URIs and dumb HTTP are\nsafer by avoiding concurrent appends to the staging file.  Opening in\nread-write mode with separate file offsets prevents corruption and\npreserves resumability.  \u0027fetch-pack\u0027 now tolerates pre-existing\n\u0027.keep\u0027 files.\n\n* tn/packfile-uri-concurrency:\n  fetch-pack: accept \"pack\" output for packfile URIs\n  http: permit unlinking partial packs on Windows\n  http: avoid concurrent appends to partial packs\n  http: accept HTTP 416 for complete partial packs\n  http: avoid closing index-pack input twice\n  http-fetch: correct --index-pack-arg documentation\n"
    },
    {
      "commit": "f2f3a37b68be969db7a8f02366c574770d7f17e1",
      "tree": "e6ab1135fade34452ad563237f0d830c97403b84",
      "parents": [
        "745601a9a94110d74769ab605ccd4f61339758d2",
        "7454b68b6a08abdc87b8fea6ebc2c54f334860af"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sat Aug 15 09:20:26 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Sat Aug 15 09:20:26 2026 -0700"
      },
      "message": "Merge branch \u0027jm/t0213-skip-emulated-ancestry-tests\u0027\n\nThe \u0027TRACE2_ANCESTRY\u0027 prerequisite in the \u0027t0213\u0027 test script has been\nrefined to avoid failures under user-mode emulation by verifying that\nthe ancestry collector reports the expected process names rather than\nthe emulator binary name.\n\n* jm/t0213-skip-emulated-ancestry-tests:\n  t0213: skip ancestry tests under user-mode emulation\n"
    },
    {
      "commit": "745601a9a94110d74769ab605ccd4f61339758d2",
      "tree": "4929799a1f94642df9b2c8ed4a32cb4bf4f2ab02",
      "parents": [
        "11c6700f10234578d10523faf35656ca491425c9"
      ],
      "author": {
        "name": "Elijah Newren",
        "email": "newren@gmail.com",
        "time": "Wed Aug 12 17:59:59 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed Aug 12 13:16:46 2026 -0700"
      },
      "message": "mailmap: map Elijah Newren\u0027s current and previous work addresses\n\nSigned-off-by: Elijah Newren \u003cnewren@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "65cda10d5bbbca7c97e40e3cff5b8c08e182679e",
      "tree": "8a8cec7a1eb6b7b1372ef8a520d39673bbb6812f",
      "parents": [
        "11c6700f10234578d10523faf35656ca491425c9"
      ],
      "author": {
        "name": "Johannes Schindelin",
        "email": "johannes.schindelin@gmx.de",
        "time": "Wed Aug 12 09:54:57 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed Aug 12 09:07:03 2026 -0700"
      },
      "message": "sequencer: release the ODB before spawning git commit\n\nAs of 4557f1add261 (rebase--helper: add a builtin helper for interactive\nrebases, 2017-02-09), continuing an interactive rebase uses the builtin\nsequencer, which spawns `git commit`.\n\nThe child may trigger auto-maintenance, which may need to replace files\nfor which the sequencer still holds resources. See\nhttps://github.com/git-for-windows/git/issues/6315: on Windows, this\nproduces unlink retry prompts that cannot succeed while the sequencer\nwaits for the child.\n\nResources such as file handles or memory mappings must be released\nbefore spawning a command that may run auto-maintenance, as established\nby 28d04e1ec197 (run-command: offer to close the object store before\nrunning, 2021-09-09): release the ODB file handles and memory mappings,\nso that auto-gc can repack (potentially deleting existing packfiles in\nthe process); If the sequencer needs to access the ODB afterwards, it\nwill gracefully (re-)open the ODB.\n\nRelease the sequencer\u0027s ODB before spawning `git commit`. The regression\ntest uses the legacy-delete trick introduced by 69ed0e35a754 (mingw:\noptionally use legacy (non-POSIX) delete semantics, 2026-05-07) to\ntrigger the failure on modern Windows.\n\nAssisted-by: GPT-5.6 Sol\nSigned-off-by: Johannes Schindelin \u003cjohannes.schindelin@gmx.de\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "11c6700f10234578d10523faf35656ca491425c9",
      "tree": "a5c28b7c0de2899dca9b2aabbb011dfc8cdc74ea",
      "parents": [
        "97895a898db2e6cc5f3b8f012a9e7913b46340ff"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 11 10:06:39 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 11 10:07:00 2026 -0700"
      },
      "message": "The 13th batch\n\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "97895a898db2e6cc5f3b8f012a9e7913b46340ff",
      "tree": "0cd1bf47870c8fba8806eab4cc8b06200fe8fdcc",
      "parents": [
        "4753128b86ff7456ce499f169e1ad6c2366e3563",
        "89454a60ed3c668aabdc372327207096c9613e56"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 11 10:07:00 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 11 10:07:00 2026 -0700"
      },
      "message": "Merge branch \u0027ns/merge-base-is-ancestor-tests\u0027\n\nTests for \u0027git merge-base --is-ancestor\u0027 have been added to cover\nexit codes (0 for success, 1 for non-ancestor, 128 for errors) and\nto ensure it cannot be combined with \u0027--all\u0027.\n\n* ns/merge-base-is-ancestor-tests:\n  merge-base: add tests for --is-ancestor\n"
    },
    {
      "commit": "4753128b86ff7456ce499f169e1ad6c2366e3563",
      "tree": "1793f3d77d5d011efc99c69cb4c06f521ded6405",
      "parents": [
        "461ed7e1b31acee13ef2280b5dcf4f48f6057578",
        "062d90b2a8b39142a57105706e3fb4c455c9b5a0"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 11 10:07:00 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 11 10:07:00 2026 -0700"
      },
      "message": "Merge branch \u0027lo/mv-missing-dest-dir-check\u0027\n\n\u0027git mv\u0027 has been updated to check for a missing destination\nleading directory during the checking phase, allowing \u0027git mv -n\u0027\nto report the failure.  The error message when the rename(2)\nsyscall fails has also been improved to name both the source and\nthe destination.\n\n* lo/mv-missing-dest-dir-check:\n  mv: reject a destination whose leading path is missing or a symlink\n  mv: name both source and destination when rename fails\n"
    },
    {
      "commit": "461ed7e1b31acee13ef2280b5dcf4f48f6057578",
      "tree": "750d04be0232777e12041de009cbf62f6b4c932d",
      "parents": [
        "3307faf4c11f7601fec30efa6143f41fbc6cb243",
        "48c0549f5c8b65acc4de91f2233e62b3fc43a644"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 11 10:06:59 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 11 10:07:00 2026 -0700"
      },
      "message": "Merge branch \u0027kh/doc-replay-config\u0027\n\nDocumentation for \u0027git replay\u0027 has been updated to refer to its\nconfiguration variables.\n\n* kh/doc-replay-config:\n  doc: replay: move “default” to the right-hand side\n  doc: replay: use a nested description list\n  doc: replay: improve config description\n  doc: link to config for git-replay(1)\n"
    },
    {
      "commit": "3307faf4c11f7601fec30efa6143f41fbc6cb243",
      "tree": "162d25f7cf4e093ecceec1ff1b6f92c7278e342e",
      "parents": [
        "bf6bc2ae422832129967fd2021bc17bdb7c5a395",
        "9539653b71ed1ab37302574f96544013b8829eb9"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 11 10:06:59 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 11 10:06:59 2026 -0700"
      },
      "message": "Merge branch \u0027sk/test-commit-body-helper\u0027\n\nA new test helper commit_body() has been introduced to print the\nmessage body of a commit, and various tests have been updated to use\nit instead of spelling out the command pipeline manually and losing\nthe exit status of the \u0027git cat-file\u0027 command on the upstream of the\npipe.\n\n* sk/test-commit-body-helper:\n  t: use commit_body to extract commit message bodies\n  test-lib-functions: add commit_body helper\n"
    },
    {
      "commit": "bf6bc2ae422832129967fd2021bc17bdb7c5a395",
      "tree": "eda2aacab3a4a722be740bd008aeaa56a6f4426e",
      "parents": [
        "010afd3166ddc64c9863b1506f12cbcdda0d4ea1",
        "f8c6bb65d779f0e4eb065acdef76a496a163f4b4"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 11 10:06:59 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 11 10:06:59 2026 -0700"
      },
      "message": "Merge branch \u0027ja/doc-synopsis-style-yet-more\u0027\n\nSynopsis and options in the documentation for \u0027git format-patch\u0027,\n\u0027git imap-send\u0027, \u0027git send-email\u0027, and \u0027git request-pull\u0027 have been\nupdated to the modern style.\n\n* ja/doc-synopsis-style-yet-more:\n  doc: convert git-request-pull synopsis and options to new style\n  doc: convert git-send-email synopsis and options to new style\n  doc: convert git-format-patch synopsis and options to new style\n  doc: convert git-imap-send synopsis and options to new style\n"
    },
    {
      "commit": "56c9056e30812bbba545d95ed7eb0f5beb089edd",
      "tree": "064f2e19ef6becb9e2047d9689836411ef85f445",
      "parents": [
        "4e08160c2b3c037a4650a39edf77f90c7774f3a6"
      ],
      "author": {
        "name": "Kristofer Karlsson",
        "email": "krka@spotify.com",
        "time": "Tue Aug 11 09:28:52 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 11 07:34:32 2026 -0700"
      },
      "message": "commit-reach: remove commit-date ordering fallback\n\nRemove the fallback that switched paint_down_to_common() from\ngeneration ordering to commit-date ordering when the commit-graph\nlacks corrected commit dates (v1 graph with topo levels only).\n\nThe fallback was added in 091f4cf3 (commit: don\u0027t use generation\nnumbers if not needed, 2018-08-30) to avoid a performance\nregression on the Linux kernel repo where v1 topo levels caused\n\"git merge-base v4.8 v4.9\" to walk 636k commits instead of 167k.\nA side branch with a low topo level stayed in the queue behind a\nlong chain, preventing early STALE propagation.\n\nSide-exhaustion (added in the previous commits) solves this\ndifferently by terminating the walk as soon as one paint side\nempties from the queue, preventing the deep walk regardless of\nqueue ordering. Benchmarks of \"git merge-base --all v4.8 v4.9\"\non the Linux kernel repo show that side-exhaustion reduces the\nstep count far below what the date-ordering fallback achieved:\n\n                         steps      time\n  no graph, baseline:   167,413    3.25 s\n  v1 graph, baseline:   167,413    0.25 s\n  v2 graph, baseline:   167,441    0.29 s\n  v1 graph, this series:  5,725    0.02 s\n  v2 graph, this series:  3,887    0.01 s\n\nWith generation ordering always active, the existing min_generation\ncheck in paint_queue_get() can safely terminate once the walk\ncrosses below the caller\u0027s generation floor. The date ordering\nfallback broke this invariant: a commit could have a finite topo\nlevel while the queue was date-ordered, causing the early exit to\nfire before all merge bases were found.\n\nWith the fallback removed, gen_ordered is always true and can be\ndropped. The topo_ceiling field (introduced earlier) already\nhandles V1_MAX saturation, so the early exit gates need no further\nchanges.\n\nSigned-off-by: Kristofer Karlsson \u003ckrka@spotify.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "4e08160c2b3c037a4650a39edf77f90c7774f3a6",
      "tree": "38b27e414ec41d8534015acaa15acebedfa6d9a0",
      "parents": [
        "02d7ba092deee118bb3954077880abfdc8f2dc2f"
      ],
      "author": {
        "name": "Kristofer Karlsson",
        "email": "krka@spotify.com",
        "time": "Tue Aug 11 09:28:51 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 11 07:34:32 2026 -0700"
      },
      "message": "commit-reach: move min_generation check into paint_queue_get()\n\nConsolidate the min_generation termination condition into\npaint_queue_get(), alongside the existing stale-entry and\nside-exhaustion checks.\n\nMove last_gen into struct paint_state so that\ncommit_graph_generation() is called exactly once per dequeued commit\nand the result is shared across all termination checks and the\nmonotonicity BUG assertion.\n\nSigned-off-by: Kristofer Karlsson \u003ckrka@spotify.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "02d7ba092deee118bb3954077880abfdc8f2dc2f",
      "tree": "4e7ccb3570f383f24191b781ee05e7f678e3ca8e",
      "parents": [
        "a3e5bad734f8f83a485c5f28535d1f409993a175"
      ],
      "author": {
        "name": "Kristofer Karlsson",
        "email": "krka@spotify.com",
        "time": "Tue Aug 11 09:28:50 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 11 07:34:32 2026 -0700"
      },
      "message": "commit-reach: terminate merge-base walk when one paint side is exhausted\n\nAdd an early termination check to paint_down_to_common() using the\nper-side counters introduced earlier. Once the walk enters the\nordered region, terminate early when one side\u0027s exclusive count\ndrops to zero -- no new merge-base can form without both paint\nsides meeting.\n\nThe check also waits for pending_merge_bases to reach zero, ensuring\nall merge-base candidates have been dequeued and recorded before\nexiting.\n\nThe optimization is gated by gen_ordered (which excludes v1\ncommit-graphs that use the date-ordering fallback) and by a\ngeneration check against topo_ceiling. topo_ceiling is\nGENERATION_NUMBER_INFINITY for v2 graphs and\nGENERATION_NUMBER_V1_MAX for v1 graphs, so that saturated commits\nare treated as unordered. Together these ensure the check only\nfires in the ordered region where topological ordering holds.\n\nThe same topo_ceiling boundary is applied to the existing\nsingle-result early exit so that all generation-dependent gates\nexpress the same saturation-aware boundary consistently.\n\nStep counts measured with trace2 on git.git with commit-graph:\n\n  merge-base --all v2.0.0 v2.55.0-rc1:\n    before: 72264 steps    after: 44589 steps\n\n  merge-base --all v2.55.0-rc1 v2.55.0-rc1~5:\n    before:   110 steps    after:     7 steps\n\nHelped-by: Derrick Stolee \u003cstolee@gmail.com\u003e\nHelped-by: Elijah Newren \u003cnewren@gmail.com\u003e\nSigned-off-by: Kristofer Karlsson \u003ckrka@spotify.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "a3e5bad734f8f83a485c5f28535d1f409993a175",
      "tree": "ba138d503a4b9deaa25f544dbe3663eabe6dceb6",
      "parents": [
        "bad379346dd81bff1238557aa6dc06254b4f4701"
      ],
      "author": {
        "name": "Kristofer Karlsson",
        "email": "krka@spotify.com",
        "time": "Tue Aug 11 09:28:49 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 11 07:34:32 2026 -0700"
      },
      "message": "commit-reach: introduce struct paint_state with per-side counters\n\nAdd a paint_state struct for use by paint_down_to_common() that\nwraps a prio_queue with per-side commit counters. Each non-stale\nqueued commit occupies exactly one counter bucket based on its\npaint flags: PARENT1-only, PARENT2-only, or both sides (a pending\nmerge-base candidate).\n\nThe counters are maintained by paint_count_update() which adjusts\nthe appropriate bucket by a signed delta. An exhaustive switch on\nthe paint+stale bits documents all valid flag combinations in one\nplace.\n\nConvert paint_down_to_common() to use paint_state. The loop now\ndrains the queue via paint_queue_get() which returns NULL when all\ncounters reach zero, replacing the old pointer-based termination\n(max_nonstale). This is equivalent behavior -- both conditions\ndetect that no non-stale entries remain.\n\npaint_queue_get() uses a \"pop first\" form: it dequeues a commit,\nthen checks the counters. This means the loop exits one iteration\nearlier than the old code in some topologies (the popped stale\ncommit is never processed), so a few step counts drop by one.\n\nThe existing nonstale_queue is left in place for ahead_behind(),\nthough nonstale_queue_put_dedup() and nonstale_queue_get_dedup()\nbecome unused and are removed.\n\nSigned-off-by: Kristofer Karlsson \u003ckrka@spotify.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "bad379346dd81bff1238557aa6dc06254b4f4701",
      "tree": "5587afb12335769c46ca2d74fd60efe0e1fd0545",
      "parents": [
        "6300d71cd63e32fafe3b427d8547b5e0c75f827c"
      ],
      "author": {
        "name": "Kristofer Karlsson",
        "email": "krka@spotify.com",
        "time": "Tue Aug 11 09:28:48 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 11 07:34:32 2026 -0700"
      },
      "message": "t6600: add clock-skew topologies and step counts for edge cases\n\nAdd topologies and tests exercising paint_down_to_common() under\nclock skew, where commit-date ordering (v1 commit-graph without\ncorrected commit dates) violates the topological invariant that\nchildren are dequeued before parents:\n\n - se-*: side-exhaustion fires too early when one paint side fully\n   drains from the queue while a low-date ancestor on the other\n   side is still queued\n\n - se2-*: side-exhaustion returns a too-deep merge base because\n   the correct (closer) base never receives both paint sides\n\nAlso add step counts to the edge-case tests from the previous\ncommit, a mixed finite/INFINITY generation topology exercising\nthe transition from INFINITY-generation commits to graph-backed\ncommits, and step counts for the grid-based merge-base test.\n\nSigned-off-by: Kristofer Karlsson \u003ckrka@spotify.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "6300d71cd63e32fafe3b427d8547b5e0c75f827c",
      "tree": "9b5a4dbb1c5ac1fb485ee78af0b93b9205bce3f0",
      "parents": [
        "259a45f1f847a4f0a39d6a6dd6ad3ae4f7fd6ee7"
      ],
      "author": {
        "name": "Kristofer Karlsson",
        "email": "krka@spotify.com",
        "time": "Tue Aug 11 09:28:47 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 11 07:34:32 2026 -0700"
      },
      "message": "commit-reach: add trace2 instrumentation to paint_down_to_common()\n\nAdd a step counter and trace2_data_intmax() call so that the number\nof commits visited during the paint walk is observable via\nGIT_TRACE2_EVENT. This provides a way to measure the impact of\nfuture optimizations without relying on wall-clock benchmarks alone.\n\nSome step counts already vary across commit-graph modes (e.g.\nin_merge_bases_many:self) because the pre-existing min_generation\noptimization short-circuits the walk when generation data is\navailable.\n\nSigned-off-by: Kristofer Karlsson \u003ckrka@spotify.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "259a45f1f847a4f0a39d6a6dd6ad3ae4f7fd6ee7",
      "tree": "4ca131e8947a958d6c8c3517e0a958397ad3349f",
      "parents": [
        "d3180b1534d4e54f0db3e4f968a0f546657f56fc"
      ],
      "author": {
        "name": "Kristofer Karlsson",
        "email": "krka@spotify.com",
        "time": "Tue Aug 11 09:28:46 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 11 07:34:32 2026 -0700"
      },
      "message": "t6099: add side-exhaustion regression test\n\nAdd t6099 to test the case where multiple merge-base candidates exist\nand one is an ancestor of another. This exercises the side-exhaustion\noptimization in paint_down_to_common together with the\nremove_redundant safety net in get_merge_bases_many_0.\n\nSigned-off-by: Kristofer Karlsson \u003ckrka@spotify.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "d3180b1534d4e54f0db3e4f968a0f546657f56fc",
      "tree": "2b3c883294d399bc39d90b760d84bec0e09aebea",
      "parents": [
        "fe4877bc17b1dd5b25b9444eadee20ec5fa8bf83"
      ],
      "author": {
        "name": "Elijah Newren",
        "email": "newren@gmail.com",
        "time": "Tue Aug 11 09:28:45 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 11 07:34:32 2026 -0700"
      },
      "message": "t6600: add test cases for side-exhaustion edge cases\n\nAdd test cases to t6600-test-reach.sh that exercise edge cases in the\nside-exhaustion optimization for paint_down_to_common():\n\n - in_merge_bases_many:self: commit is both A and one of the X inputs\n - get_merge_bases_many:duplicate-twos: duplicate entries in X list\n - get_merge_bases_many:pending-stale: STALE transition on an\n   already-painted commit (ps-* diamond topology)\n - get_merge_bases_many:infinity-both-sides: both tips outside the\n   commit-graph with non-monotonic dates (pi-* topology)\n\nSigned-off-by: Elijah Newren \u003cnewren@gmail.com\u003e\nSigned-off-by: Kristofer Karlsson \u003ckrka@spotify.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "fe4877bc17b1dd5b25b9444eadee20ec5fa8bf83",
      "tree": "0f53b1c2b318e99f2824cb749c22001b202c97de",
      "parents": [
        "cd2ab0e12896ef505f4be8822788912fe95394eb"
      ],
      "author": {
        "name": "Kristofer Karlsson",
        "email": "krka@spotify.com",
        "time": "Tue Aug 11 09:28:44 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 11 07:34:31 2026 -0700"
      },
      "message": "test-lib-functions: improve diagnostic output for trace2 data assertions\n\ntest_trace2_data is a bare grep that silently exits on failure.\nAdd a more informative variant that verifies the event appears\nexactly once and reports what went wrong: key not found, multiple\nentries, or value mismatch. Diagnostics go to FD 4 like test_grep.\n\nBefore (value mismatch):\n\n  $ test_trace2_data status count/changed 999 \u003ctrace2.txt\n  $ echo $?\n  1\n  (no output)\n\nAfter:\n\n  $ test_trace2_data_singular status count/changed 999 \u003ctrace2.txt\n  error: trace2 data \u0027status/count/changed\u0027\n    expected: 999\n    actual:   0\n\nSigned-off-by: Kristofer Karlsson \u003ckrka@spotify.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "cd2ab0e12896ef505f4be8822788912fe95394eb",
      "tree": "f5e99809422710f33420686876c212ba1e765185",
      "parents": [
        "9175f6c3247ba016f364bbbd214b5fca6cb1e121"
      ],
      "author": {
        "name": "Kristofer Karlsson",
        "email": "krka@spotify.com",
        "time": "Tue Aug 11 09:28:43 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 11 07:34:31 2026 -0700"
      },
      "message": "Documentation/technical: add paint-down-to-common doc\n\nAdd a technical document describing the paint_down_to_common()\nalgorithm used for merge-base computation, covering the paint\nwalk, generation number regions, and termination conditions.\n\nSigned-off-by: Kristofer Karlsson \u003ckrka@spotify.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "a09c2f2c70f5c06e74218db5190e0b3ca8f84a1e",
      "tree": "381dee38cd1727f94ba809bc003fe2d5e59238a5",
      "parents": [
        "863937696ef2bd8faaf4811aaea8cf5301bac78b"
      ],
      "author": {
        "name": "Christian Couder",
        "email": "christian.couder@gmail.com",
        "time": "Tue Aug 11 10:33:14 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 11 07:33:17 2026 -0700"
      },
      "message": "fast-import: remove useless from_stream argument\n\nNow that a previous commit has removed a call to parse_one_feature()\nfrom parse_argv(), the former is always called with its `from_stream`\nargument set to 1.\n\nLet\u0027s take advantage of that to simplify and cleanup the code a bit.\n\nSigned-off-by: Christian Couder \u003cchristian.couder@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "863937696ef2bd8faaf4811aaea8cf5301bac78b",
      "tree": "d71717bc71c84cf7c64d8d761bcf47d6db9b102e",
      "parents": [
        "87cf4d72999cdfdb343964e2027ce4a3c6cb8d04"
      ],
      "author": {
        "name": "Christian Couder",
        "email": "christian.couder@gmail.com",
        "time": "Tue Aug 11 10:33:13 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 11 07:33:17 2026 -0700"
      },
      "message": "fast-import: use parse_options() for command line options\n\nPrevious commits have started to use the parse-options API to display\noutput from `git fast-import -h` and `git fast-import --help-all` and\nto prepare for parsing the command line options using this API.\n\nLet\u0027s now actually use the API to parse command line options.\n\nThis brings a number of changes that are mostly beneficial:\n\n  - The `--alias`, `--get-mark`, `--cat-blob`, `--ls` and `--notes`\n    options are no longer accepted on the command line. They were\n    previously accepted as no-ops because parse_argv() fell through to\n    parse_one_feature(). They are not documented in the OPTIONS section\n    and are only meaningful as in-stream feature assertions, so\n    accepting them on the command line was an accident of code sharing\n    dating back to 9c8398f0c9 (fast-import: add option command,\n    2009-12-04).\n\n  - Abbreviated options like `--dep\u003d5` now work since parse_options()\n    allows unambiguous prefixes.\n\n  - As `--cat-blob` is an abbreviation of `--cat-blob-fd`, using the\n    former on the command line will fail with \"option `cat-blob-fd\u0027\n    requires a value\" unlike the other four options that are not\n    accepted anymore on the command line (see above).\n\n  - Value-taking options now also accept the space-separated\n    `--opt value` form, like `--depth 5`, in addition to the\n    `--opt\u003dvalue` form.\n\n  - A bare or trailing `--` is now accepted and the stream is read\n    normally, while it used to be a usage error.\n\n  - The error messages for some options might differ a bit.\n\n  - The code is shorter and more standard.\n\nNote that parse_one_feature() is now always called with its\n`from_stream` argument set to 1, but the code simplifications that\ncan be made are left for a following clean-up commit.\n\nSigned-off-by: Christian Couder \u003cchristian.couder@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "87cf4d72999cdfdb343964e2027ce4a3c6cb8d04",
      "tree": "e9b8ebb28896e132a240591bb769a799bd7b921f",
      "parents": [
        "27ab5815f72848e9a25e11ee93d6b036a338933b"
      ],
      "author": {
        "name": "Christian Couder",
        "email": "christian.couder@gmail.com",
        "time": "Tue Aug 11 10:33:12 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 11 07:33:17 2026 -0700"
      },
      "message": "fast-import: use callbacks to parse some options\n\nA previous commit started using the parse-option API to generate proper\n`git fast-import -h` and `git fast-import --help-all` output.\n\nLet\u0027s prepare for when we can use that API to also parse the options by\nusing OPT_CALLBACK for some options that require special processing of\ntheir arguments.\n\nA following commit will actually parse the options using these\ncallbacks.\n\nSigned-off-by: Christian Couder \u003cchristian.couder@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "27ab5815f72848e9a25e11ee93d6b036a338933b",
      "tree": "711bc7348d2b39ebe0f20c38f7ede4e08ae63033",
      "parents": [
        "ee996af567434d3fc5204ab8f53a0ade5803303d"
      ],
      "author": {
        "name": "Christian Couder",
        "email": "christian.couder@gmail.com",
        "time": "Tue Aug 11 10:33:11 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 11 07:33:17 2026 -0700"
      },
      "message": "fast-import: use struct option for usage string\n\nCurrently `git fast-import -h` shows the following on a single line:\n\n  usage : git fast-import [--date-format\u003d\u003cf\u003e] [--max-pack-size\u003d\u003cn\u003e] \\\n                          [--big-file-threshold\u003d\u003cn\u003e] [--depth\u003d\u003cn\u003e] \\\n                          [--active-branches\u003d\u003cn\u003e] \\\n                          [--export-marks\u003d\u003cmarks.file\u003e]\n\nThis output has a number of issues like:\n\n  - It\u0027s missing a lot of options.\n  - It\u0027s not consistent with the SYNOPSIS section of the doc.\n  - With `--help-all` instead of `-h` additional hidden options should\n    be shown, but that\u0027s not the case.\n  - It\u0027s not standard style anymore.\n  - Most other Git commands show additional lines for most of the\n    options they support.\n\nAlso while most commands use the parse-options API to handle their\noptions, \"builtin/fast-import.c\" still doesn\u0027t use it.\n\nLet\u0027s improve on that by using the parse-options API to display the\noptions when `-h` and `--help-all` are used.\n\nWhile at it, let\u0027s make the SYNOPSIS section of\n\"Documentation/git-fast-import.adoc\" consistent with the new usage\nstring.\n\nThis deliberately leaves it to future work to also use the\nparse-options API to actually parse the options.\n\nSigned-off-by: Christian Couder \u003cchristian.couder@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "ee996af567434d3fc5204ab8f53a0ade5803303d",
      "tree": "2eba87d67238d2a81ebe1c81d05dfc5026f4eba7",
      "parents": [
        "417afb2b4d2d2c02121300d64e874cb97e23531c"
      ],
      "author": {
        "name": "Christian Couder",
        "email": "christian.couder@gmail.com",
        "time": "Tue Aug 11 10:33:10 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 11 07:33:17 2026 -0700"
      },
      "message": "fast-import: move command state globals into \u0027struct fast_import_state\u0027\n\nA previous commit introduced \u0027struct fast_import_state\u0027 to hold some\ncommand state, and reduce the need for global variables.\n\nLet\u0027s continue in the same direction and move two more global variables\nthat describe the command state into it: \u0027seen_data_command\u0027 and\n\u0027allow_unsafe_features\u0027.\n\nAll the sites accessing these variables are already in functions that\nreceive the \u0027state\u0027 parameter (or in cmd_fast_import() which owns the\nstruct), so no additional threading is needed.\n\nAs \u0027state-\u003eallow_unsafe_features\u0027 is now dereferenced in\ncheck_unsafe_feature(), its \u0027state\u0027 parameter is no longer unused, so\nthe UNUSED marker is removed.\n\nThe fast_import_state_init() call is moved up before the early\ncommand-line scan for \u0027--allow-unsafe-features\u0027, so that this option\ncan be recorded directly into the struct without being clobbered by\nthe memset() in fast_import_state_init().\n\nThis is a mechanical refactoring with no intended behavior change.\n\nSigned-off-by: Christian Couder \u003cchristian.couder@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "417afb2b4d2d2c02121300d64e874cb97e23531c",
      "tree": "4b011747be97f96aea67648b5812e81f51acbac2",
      "parents": [
        "63112e71a3f62cf49a7ee8f13d1250d1f02970ac"
      ],
      "author": {
        "name": "Christian Couder",
        "email": "christian.couder@gmail.com",
        "time": "Tue Aug 11 10:33:09 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 11 07:33:17 2026 -0700"
      },
      "message": "fast-import: introduce \u0027struct fast_import_state\u0027\n\n\"builtin/fast-import.c\" uses a large number of global variables. This\nmakes it harder than necessary to reason about and improve. Especially\nadding new features requires adding more global variables, while\nmodernizing and eventually libifying the code becomes more and more\ndifficult.\n\nTo start reverting the sad trend to more and more globals and to start\ncleaning things up, let\u0027s introduce a \u0027struct fast_import_state\u0027 and\npass an instance of it as the first argument to many functions.\n\nThis is similar to what was done for \"builtin/apply.c\" by introducing a\n\u0027struct apply_state\u0027, see 07d7e290ff (apply: move \u0027struct apply_state\u0027\nto a header file, 2016-08-11) and related commits.\n\nAs a first step only the \u0027global_argc\u0027, \u0027global_argv\u0027 and\n\u0027global_prefix\u0027 variables are moved into the new struct. More variables\nwill be moved into it in the following commits.\n\nSome functions receive the new \u0027state\u0027 parameter only to pass it\nalong or for future use, so they are marked with UNUSED for now to\nsatisfy \u0027-Werror\u003dunused-parameter\u0027.\n\nThis is a mostly mechanical refactoring with no intended behavior\nchange.\n\nSigned-off-by: Christian Couder \u003cchristian.couder@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "63112e71a3f62cf49a7ee8f13d1250d1f02970ac",
      "tree": "46da6787486ce379fd92579e391489724f04a4b6",
      "parents": [
        "a895a37c1bccbfc19892df14ea83c56ea4f50e87"
      ],
      "author": {
        "name": "Christian Couder",
        "email": "christian.couder@gmail.com",
        "time": "Tue Aug 11 10:33:08 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 11 07:33:17 2026 -0700"
      },
      "message": "fast-import: factor out option_*() functions\n\nIn a following commit we are going to use the parse-options API to\nstart parsing options. Some options will have to be parsed using\nOPT_CALLBACK as they process their arguments in special ways.\n\nWhen the processing code is already factored out in an option_*()\nfunction, like for `--date-format`, we can reuse that function.\nUnfortunately for other options the processing code has not been\nfactored out yet.\n\nLet\u0027s do it now and factor out the code that handles the following\noptions:\n\n  - `--max-pack-size\u003d\u003cn\u003e`\n  - `--big-file-threshold\u003d\u003cn\u003e`\n  - `--signed-commits\u003d\u003cmode\u003e`\n  - `--signed-tags\u003d\u003cmode\u003e`\n  - `--quiet`\n\ninto new option_*() functions:\n\n  - option_max_pack_size()\n  - option_big_file_threshold()\n  - option_signed_commits()\n  - option_signed_tags()\n  - option_quiet()\n\nso that we can reuse these functions in following commits when the\nparse-option API will be used.\n\nNote that there are some behavior changes as we now die() with a\nproper error message when git_parse_ulong() cannot parse the argument\nfrom --max-pack-size or from --big-file-threshold. Previously we would\nend up calling die(\"unknown option\") instead.\n\nSigned-off-by: Christian Couder \u003cchristian.couder@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "a895a37c1bccbfc19892df14ea83c56ea4f50e87",
      "tree": "69401b29ebb15a3156e859ba728aac9cb4926f3c",
      "parents": [
        "62c1a58eebe81708f9c2408918f76713285e62a0"
      ],
      "author": {
        "name": "Christian Couder",
        "email": "christian.couder@gmail.com",
        "time": "Tue Aug 11 10:33:07 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 11 07:33:17 2026 -0700"
      },
      "message": "fast-import: use int for some bool flags\n\nThe `show_stats` and `quiet` flags are meant to be parsed and used as\nboolean flags.\n\nTo easily parse them using OPT_BOOL in a following commit, let\u0027s change\ntheir type from \u0027unsigned int\u0027 to just \u0027int\u0027.\n\nSigned-off-by: Christian Couder \u003cchristian.couder@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "62c1a58eebe81708f9c2408918f76713285e62a0",
      "tree": "9ceab842e6bba4a0795d972fdda99e77a51dba52",
      "parents": [
        "08b7e358e377ec2d7cd3cfe0679261b1ffffc8a7"
      ],
      "author": {
        "name": "Christian Couder",
        "email": "christian.couder@gmail.com",
        "time": "Tue Aug 11 10:33:06 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 11 07:33:16 2026 -0700"
      },
      "message": "fast-import: localize \u0027i\u0027 into the \u0027for\u0027 loops using it\n\nIn cmd_fast_import(), a\tlocal variable \u0027i\u0027 is defined as an\n`unsigned int` and then used as a loop counter in four different\n`for (i \u003d ...; i \u003c ...; i++) { ... }` loops.\n\nBut in three out of the four cases, `unsigned int` isn\u0027t the best type\nto use.\n\nTo give each loop counter the type matching its bound\n(int/unsigned/size_t), let\u0027s localize \u0027i\u0027 into each loop that uses it.\n\nSigned-off-by: Christian Couder \u003cchristian.couder@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "08b7e358e377ec2d7cd3cfe0679261b1ffffc8a7",
      "tree": "122e9a49bdd7717a91fb81109a484c33b04af451",
      "parents": [
        "e455bade3a5167c36b42b3b8aa3c690722597c5b"
      ],
      "author": {
        "name": "Christian Couder",
        "email": "christian.couder@gmail.com",
        "time": "Tue Aug 11 10:33:05 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 11 07:33:16 2026 -0700"
      },
      "message": "api-parse-options.adoc: document hidden and OPT_*_F option macros\n\nIn \"Documentation/technical/api-parse-options.adoc\", the list of option\nmacros does not mention the `OPT_*_F()` macro variants that take a\ntrailing `flags` argument, nor the `OPT_HIDDEN_GROUP()` and\n`OPT_HIDDEN_BOOL()` convenience macros.\n\nNow that a previous commit documents the per-option flags, let\u0027s\ndocument these macros too:\n\n  - Add a paragraph explaining the `OPT_*_F` convention and how it\n    relates to the per-option flags.\n\n  - Document `OPT_HIDDEN_GROUP()`, introduced in a previous commit,\n    right after `OPT_GROUP()`.\n\n  - Document `OPT_HIDDEN_BOOL()` right after `OPT_BOOL()`.\n\nSigned-off-by: Christian Couder \u003cchristian.couder@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "e455bade3a5167c36b42b3b8aa3c690722597c5b",
      "tree": "610e4d78eda66496fc5c46f155e40a2c6d41088d",
      "parents": [
        "5ab204e7dfe4e5affb779c406a24b3b6e46ae54e"
      ],
      "author": {
        "name": "Christian Couder",
        "email": "christian.couder@gmail.com",
        "time": "Tue Aug 11 10:33:04 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 11 07:33:16 2026 -0700"
      },
      "message": "api-parse-options.adoc: document per-option flags\n\nThe \"Flags\" section in \"Documentation/technical/api-parse-options.adoc\"\ndocuments the flags that can be passed to parse_options() itself. It\ndoes not, however, document the flags that can be set on individual\noptions through the `flags` member of `struct option` (and through the\n`OPT_*_F()` macro variants).\n\nThese per-option flags are used throughout the codebase (for example\n`PARSE_OPT_HIDDEN` is used to hide an option from `-h` while still\nshowing it with `--help-all`), but a reader currently has to dig into\n\"parse-options.h\" to find them.\n\nTo remediate that, let\u0027s add an \"Option flags\" subsection to the\n\"Data Structure\" section, just before the list of option macros.\n\nLet\u0027s also make it explicit that these are distinct from the\nparse_options() flags described earlier, and let\u0027s describe the `-h`\nversus `--help-all` behavior for `PARSE_OPT_HIDDEN`.\n\nSigned-off-by: Christian Couder \u003cchristian.couder@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "5ab204e7dfe4e5affb779c406a24b3b6e46ae54e",
      "tree": "d79e23b58cf89efdcee5df59f6ce61964e13af0e",
      "parents": [
        "5b2471720c93ee30e5764a19f3d3b3ae9ec9712a"
      ],
      "author": {
        "name": "Christian Couder",
        "email": "christian.couder@gmail.com",
        "time": "Tue Aug 11 10:33:03 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Tue Aug 11 07:33:16 2026 -0700"
      },
      "message": "parse-options: introduce OPT_HIDDEN_GROUP\n\nHidden options are not shown by `git \u003ccmd\u003e -h`, but are still shown by\n`git \u003ccmd\u003e --help-all`. If there are a lot of hidden options or if they\ndon\u0027t belong to the same categories as other options, there is\ncurrently no way to properly group them.\n\nUsing `OPT_GROUP(\"Foo\")` means that \"Foo\" will always be shown which we\ndon\u0027t want if that group contains only hidden options.\n\nTo provide a way to have groups shown only when hidden options are\nshown, let\u0027s implement an OPT_HIDDEN_GROUP macro.\n\nTo test this new macro, let\u0027s also improve `test-tool parse-options`\nand test its output with `--help-all`.\n\nSigned-off-by: Christian Couder \u003cchristian.couder@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "b0b304c10a65882a8e36abbb694603648a78edfd",
      "tree": "d0449b7022e1bd3188bbe0d5d9b557fa8e080a1e",
      "parents": [
        "010afd3166ddc64c9863b1506f12cbcdda0d4ea1"
      ],
      "author": {
        "name": "Harald Nordgren",
        "email": "haraldnordgren@gmail.com",
        "time": "Mon Aug 10 17:53:32 2026 +0000"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Mon Aug 10 14:07:02 2026 -0700"
      },
      "message": "send-email: clarify missing subject error\n\nClarify that a message file is missing a \u0027Subject:\u0027 line.\n\nTerminate the error with a newline so Perl does not append its internal\nsource location.\n\nSigned-off-by: Harald Nordgren \u003charaldnordgren@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "4515c86fd95ef8de8a1cbea90bb275538bfc87ee",
      "tree": "0a6bf5c440e3363a355479d5d1e0a8d2a77b3c41",
      "parents": [
        "cb657364d5c3b82bc32e22fe1eca445d9960032b"
      ],
      "author": {
        "name": "Kristoffer Haugsbakk",
        "email": "code@khaugsbakk.name",
        "time": "Sun Aug 09 22:06:35 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Mon Aug 10 11:05:52 2026 -0700"
      },
      "message": "doc: interpret-trailers: document comment line treatment\n\nComment lines have always been ignored but this is not documented.\n\nThe primary motivation here is to be reasonably complete in the\ndocumentation of how trailers are parsed; this is after all the only\ndocumentation page that documents this format. However, and going beyond\nthat point, we could imagine that someone would want to use this format\noutside a commit (or tag) message context, like say in Git notes.\n\nOn the other hand, it seems far-fetched that someone would be caught\noff guard by this considering that comment characters/strings are not\nlikely to be alphanumeric,[1] which would mean that these comment lines\nwould be treated as non-trailer lines if they were *not* detected and\nremoved as comment lines.\n\n† 1: A notable exception is that Jujutsu VCS uses `JJ:` as\n     the comment string\n\nSigned-off-by: Kristoffer Haugsbakk \u003ccode@khaugsbakk.name\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "cb657364d5c3b82bc32e22fe1eca445d9960032b",
      "tree": "b7346970c28afe1995dc904872a523fdd0b507c0",
      "parents": [
        "4d45e571ae9a8dc47af95a4698cd28b15723bf52"
      ],
      "author": {
        "name": "Kristoffer Haugsbakk",
        "email": "code@khaugsbakk.name",
        "time": "Sun Aug 09 22:06:34 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Mon Aug 10 11:05:52 2026 -0700"
      },
      "message": "doc: interpret-trailers: rewrite new-trailers paragraphs\n\nTwo commits ago we moved new-trailers paragraph next to each other.\nBut there is something curious about two of them:\n\n    By default the new trailer will appear at the end of the trailer\n    block. [...]\n\nThen a source block and a paragraph later:\n\n    By default, a `\u003ckey\u003e\u003d\u003cvalue\u003e` or `\u003ckey\u003e:\u003cvalue\u003e` argument given\n    using `--trailer` will be appended after the existing trailers only\n    if [...]\n\nWhy are there two paragraphs that talk about how “By default” a trailer\nwill be appended?\n\nWe can make these paragraphs flow better, and with a more distinct\ncharacter each, by dividing the flow like this:\n\n1. Declare that we are about to talk about `--trailer` appending\n2. Explain the default behavior\n3. Explain how this affects the trailer block\n4. Then discuss what each trailer line will look like\n\nSigned-off-by: Kristoffer Haugsbakk \u003ccode@khaugsbakk.name\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "4d45e571ae9a8dc47af95a4698cd28b15723bf52",
      "tree": "a38e0a87141eb74613234eed9045ffdd35e4c3b4",
      "parents": [
        "1e4200ede56ba26bbf9d0fb02f1ffad994673d53"
      ],
      "author": {
        "name": "Kristoffer Haugsbakk",
        "email": "code@khaugsbakk.name",
        "time": "Sun Aug 09 22:06:33 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Mon Aug 10 11:05:52 2026 -0700"
      },
      "message": "doc: interpret-trailers: commit to “trailer block” term\n\nWe chose to introduce the term “trailer block” into the documentation a\nfew commits ago.[1] It is used in the code though, so it is not a newly\ninvented term.\n\nThat term was useful to explain where the trailers are found (they\n*trail* the message). But it is also useful here, where we explain\nhow trailers are added to existing messages, how trailer blocks are\nfound (beyond the simple case in the introduction), and how the end\nof the message is found.\n\nAlso note that we simplify the “blank line” point. The text says:\n\n    A blank line will be added before the new trailer if there isn\u0027t one\n    already.\n\nBut this isn’t quite coherent. The previous sentence says “If there is\nno existing trailer”, so we are in one of these modes:\n\n1. discussing trailer blocks in general; or\n2. discussing creating a new trailer block in particular.\n\nIf (1), then we shouldn’t add a blank line before the new trailer if\nthere exists a trailer block already. And if (2), then the “if there\nisn’t one already” is redundant.[2] So just talking about the higher-\nlevel “trailer block” simplifies the text, since we don’t have to worry\nabout the different contexts that *trailers* can find themselves in.\n\n† 1: in commit “explain the format after the intro”\n† 2: Note that non-trailer lines don’t matter here; if you have a\n     trailer block consisting of `(cherry picked from commit \u003ccommit\u003e)`,\n     then you still shouldn’t insert a blank line before the new trailer\n     since that would create a new trailer block\n\nSigned-off-by: Kristoffer Haugsbakk \u003ccode@khaugsbakk.name\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "1e4200ede56ba26bbf9d0fb02f1ffad994673d53",
      "tree": "a4c1c7dc925b6e28a6c74c39d27bebc4f200789c",
      "parents": [
        "fddec1fe112470d35696322de65666a53b5bac5c"
      ],
      "author": {
        "name": "Kristoffer Haugsbakk",
        "email": "code@khaugsbakk.name",
        "time": "Sun Aug 09 22:06:32 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Mon Aug 10 11:05:52 2026 -0700"
      },
      "message": "doc: interpret-trailers: join new-trailers again\n\nThere are three paragraphs that talk about how a new trailer is added.\nBut the first one is separated from the other two by two paragraphs\nabout how `key-alias` can make using `--trailer` more convenient. This\nshort how-to does not follow thematically from the previous paragraph,\nand can wait until we have fully described how a new trailer is\nadded. So let’s move the three paragraphs about the new-trailer topic\ntogether and move the how-to paragraphs after that.\n\n***\n\nLet’s now review the history of the document. Even if the document\nis not quite correct in its current state, just doing the apparently\nobvious edit without considering the history does not respect the\neffort that went into changing the document in the past.\n\nThese three paragraphs were originally next to each other, in the first\nversion of the doc.[1] But extra sentences about this how-to topic was\nadded to the first paragraph nine years later:[2]\n\n    [...]\n    `\u0027: \u0027` (one colon followed by one space). For convenience, the\n    \u003ctoken\u003e can be a shortened string key (e.g., \"sign\") instead of the\n    full string which should [...]\n\nAnd then it was split into it’s own paragraph a little later.[3]\n\nThis evolution shows, in my opinion, that this how-to never followed\nthematically from the existing topic. Which means that there is nothing\nthat was potentially lost to time that we need to restore or respect.\n\n† 1: dfd66ddf (Documentation: add documentation for \u0027git\n     interpret-trailers\u0027, 2014-10-13)\n† 2: eda2c44c (doc: trailer: mention \u0027key\u0027 in DESCRIPTION, 2023-06-15)\n† 3: 6ccbc667 (trailer doc: \u003ctoken\u003e is a \u003ckey\u003e or \u003ckeyAlias\u003e, not both,\n     2023-09-07)\n\nSuggested-by: D. Ben Knoble \u003cben.knoble+github@gmail.com\u003e\nSigned-off-by: Kristoffer Haugsbakk \u003ccode@khaugsbakk.name\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "fddec1fe112470d35696322de65666a53b5bac5c",
      "tree": "7278798f37e2f763ed4ee0ca8ce5594033df0ccc",
      "parents": [
        "fd39e5a481154cdb0e42a8a89c0062bbf6e3ab2b"
      ],
      "author": {
        "name": "Kristoffer Haugsbakk",
        "email": "code@khaugsbakk.name",
        "time": "Sun Aug 09 22:06:31 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Mon Aug 10 11:05:52 2026 -0700"
      },
      "message": "doc: interpret-trailers: add key format example\n\nAll of the examples speak of the Happy Path where everything works\nas intended. But failure examples can also be instructive. Especially\nfor explaining again, by example, the key format (see previous commit).\n\nThis also allows us to demonstrate trailer block detection with a\nconcrete example.\n\nSigned-off-by: Kristoffer Haugsbakk \u003ccode@khaugsbakk.name\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "fd39e5a481154cdb0e42a8a89c0062bbf6e3ab2b",
      "tree": "022ffe1a96cf114e558035b5f71128d861b20bf6",
      "parents": [
        "c88d60db4438b05ac29d07b5373e6fb7a37d56af"
      ],
      "author": {
        "name": "Kristoffer Haugsbakk",
        "email": "code@khaugsbakk.name",
        "time": "Sun Aug 09 22:06:30 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Mon Aug 10 11:05:52 2026 -0700"
      },
      "message": "doc: interpret-trailers: explain key format\n\nA trailer key must consist of ASCII alphanumeric characters and\nhyphens *only*. Let’s document it explicitly instead of relying on\nreaders being conservative and only basing their trailer keys on the\ndocumentation examples.[1]\n\nThe previous commit provided us with an appropriate paragraph to\ndescribe the key format.\n\n† 1: Technically they would then miss out on using digits in them since\n     all of the example keys just use letters and hyphens\n\nReported-by: Brendan Jackman \u003cjackmanb@google.com\u003e\nSigned-off-by: Kristoffer Haugsbakk \u003ccode@khaugsbakk.name\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "c88d60db4438b05ac29d07b5373e6fb7a37d56af",
      "tree": "822102f5db8bf4e131fa05834fbd44f9ef9c85b6",
      "parents": [
        "33691bc9d75560299568ebdf9dfbf38539087be3"
      ],
      "author": {
        "name": "Kristoffer Haugsbakk",
        "email": "code@khaugsbakk.name",
        "time": "Sun Aug 09 22:06:29 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Mon Aug 10 11:05:51 2026 -0700"
      },
      "message": "doc: interpret-trailers: explain the format after the intro\n\nYou need to read the entire “Description” section in order to understand\nthe full trailer format. But there are many nuances, so that’s fine.\nAs a starter though we have an introductory example.[1] That turns out\nto be crucial; the rest of this section talks about the mechanics of the\ncommand and only incidentally the format itself.\n\nNow, although the example might arguably be self-explanatory, we can\nadd a little preamble which defines the format in its simplest form as\nwell as define the most important terms.\n\nNote that we name the “blank line” rule since I want to use that term\nevery time it comes up. It gets very mildly obfuscated if you call it\na “blank line” in one place[2] and “empty (or whitespace-only) ...” in\nanother one.[3]\n\nWe will define the format of the *key* in the next commit.\n\n† 1: from d57fa7fc (doc: trailer: add more examples in DESCRIPTION,\n     2023-06-15)\n† 2: `Documentation/git-interpret-trailers.adoc:86` in\n     5361983c (The 22nd batch, 2026-03-27)\n† 3: `Documentation/git-interpret-trailers.adoc:93` in\n     5361983c (The 22nd batch, 2026-03-27)\n\nSuggested-by: D. Ben Knoble \u003cben.knoble+github@gmail.com\u003e\nSigned-off-by: Kristoffer Haugsbakk \u003ccode@khaugsbakk.name\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "33691bc9d75560299568ebdf9dfbf38539087be3",
      "tree": "0b1117593e20772462eff75c4789df59c469f063",
      "parents": [
        "500257fd2bc6f81181039bc7420383d14ecf980b"
      ],
      "author": {
        "name": "Kristoffer Haugsbakk",
        "email": "code@khaugsbakk.name",
        "time": "Sun Aug 09 22:06:28 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Mon Aug 10 11:05:51 2026 -0700"
      },
      "message": "doc: interpret-trailers: not just for commit messages\n\nThis command doesn’t interface with commits directly. You can\ninterpret or modify any kind of text, even though commit messages\nare the most relevant.\n\nThe git(1) suite also isn’t restricted to only direct commit support\nsince git-tag(1) learned `--trailer` in 066cef77 (builtin/tag: add\n--trailer option, 2024-05-05)\n\nNow, we already introduce the command in the “Name” section as dealing\nwith commit messages as well. That is fine since that intro line needs\nto remain pretty short.\n\nSigned-off-by: Kristoffer Haugsbakk \u003ccode@khaugsbakk.name\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "500257fd2bc6f81181039bc7420383d14ecf980b",
      "tree": "ef8a689fa915b718322eaf87a1184933f0572260",
      "parents": [
        "abb0d859f8132634d77f1205e7862b9e7a14b479"
      ],
      "author": {
        "name": "Kristoffer Haugsbakk",
        "email": "code@khaugsbakk.name",
        "time": "Sun Aug 09 22:06:27 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Mon Aug 10 11:05:51 2026 -0700"
      },
      "message": "doc: interpret-trailers: use “metadata” in Name as well\n\nWe now since the previous commit introduce the format as “trailer\nmetadata”. We can replace “structured information” with “metadata”\nin the “Name” section to be consistent.\n\nWhile “structured information” does emphasize that the data is not\nloosely structured, we also say that this command adds to or parses\nthis format. I don’t think that we need to emphasize that it is\nstructured since clearly there is some structure there.\n\nBoth “metadata” and “structured information” can convey the same\ninformation. But “metadata” is shorter and easier to deploy since\nit’s just one word.\n\nSigned-off-by: Kristoffer Haugsbakk \u003ccode@khaugsbakk.name\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "abb0d859f8132634d77f1205e7862b9e7a14b479",
      "tree": "bd023e2a8b4a60059568924bc6069e1c80460be7",
      "parents": [
        "bc27e75a0e9a75b9543ff4cd2a12443fce558a79"
      ],
      "author": {
        "name": "Kristoffer Haugsbakk",
        "email": "code@khaugsbakk.name",
        "time": "Sun Aug 09 22:06:26 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Mon Aug 10 11:05:51 2026 -0700"
      },
      "message": "doc: interpret-trailers: replace “lines” with “metadata”\n\nWe removed the initial comparison to email headers in the previous\ncommit. Now the introduction paragraph just says “trailer lines”, and\nthe only hint that this is metadata/structured information is the\n“otherwise free-form” phrase.\n\nLet’s replace “lines” with “metadata” since that is their purpose.\nThis also makes the introduction more consistent with how I chose\nto define trailers in the glossary:[1] “Key-value metadata”. (We will\nintroduce “key–value” in the upcoming commit “explain the format after\nthe intro”.)\n\n† 1: 68e3c69e (Documentation/glossary: describe \"trailer\", 2024-11-17)\n\nLet’s not emphasize “trailer” here since we are going to define the term\nin the upcoming commit “explain the format after the intro”.\n\nLet’s call it “trailer metadata” rather than “trailers metadata”.\nAt first it seemed better to use the latter:\n\n1. We’re introducing the jargon, and the format is often discussed as\n   plural “trailers”, with its constituent parts being singular\n   “trailer”\n2. What this replaces uses “trailer”, but it rescues the plural mood\n   with “lines”\n3. This is very soon going to go into the constituent parts, including\n   each trailer, so we’re contrasting the concept name (trailers) with\n   its parts\n\nBut:\n\n1. The former reads better (most important)\n2. “Trailer *metadata*” suggests plurality, similar to “trailer *lines*”\n\nHelped-by: Matt Hunter \u003cm@lfurio.us\u003e\nSigned-off-by: Kristoffer Haugsbakk \u003ccode@khaugsbakk.name\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "bc27e75a0e9a75b9543ff4cd2a12443fce558a79",
      "tree": "603f9c0548745f0481ead7df1d64b415ddca3a77",
      "parents": [
        "270e10ad6dda3379ea0da7efd11e4fbf2cd7a325"
      ],
      "author": {
        "name": "Kristoffer Haugsbakk",
        "email": "code@khaugsbakk.name",
        "time": "Sun Aug 09 22:06:25 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Mon Aug 10 11:05:51 2026 -0700"
      },
      "message": "doc: interpret-trailers: stop fixating on RFC 822\n\nThis command handles the trailer metadata format. But the command\nisn’t introduced as such; it is instead introduced by stating that\nthese trailer lines look similar to RFC 822 email headers.\n\nThis is overwrought; most people do not deal directly with email\nheaders, and certainly not email RFCs.\n\nTrailers are just key–value pairs that, like email headers, use colon\nas the separator. The format in its simplest form is easy to describe\ndirectly without comparing it to anything else; we will do that in the\nupcoming commit “explain the format after the intro”.\n\nFor now, let’s:\n\n• remove the first mention of email headers;\n• keep the second, innocuous comparison with email line folding in the\n  middle; and\n• remove the now-unneeded disclaimer that trailers do not share many of\n  the features of RFC 822 email headers—there is no invitation to\n  speculate that trailers would follow any other email format rules\n  since we do not compare them directly any more.\n\n***\n\nTalking about trailers as an RFC 822/2822-like format seems to go back\nto the `--fixes`/`Fixes:` trailer topic,[1] the thread that precipitated\nthis command and in turn the first trailer support in git(1) beyond\nadding s-o-b lines.\n\n† 1: https://lore.kernel.org/all/20131027071407.GA11683@leaf/\n\nSigned-off-by: Kristoffer Haugsbakk \u003ccode@khaugsbakk.name\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "245f2a8b2efb1cf93358cd4c143d0a91c23e0e1d",
      "tree": "1dd765acd0cd243953a70a1c367f4334ff9750e5",
      "parents": [
        "4c842de0e4580dc217d9ba5519e8348915f9c816"
      ],
      "author": {
        "name": "Pablo Sabater",
        "email": "pabloosabaterr@gmail.com",
        "time": "Sat Aug 08 02:02:25 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri Aug 07 18:50:08 2026 -0700"
      },
      "message": "cat-file: unify default format\n\n%(objecttype) is supported both by the client and by the server.\nChange the temporary default format to the unified version that the\nother commands use.\n\nUpdate documentation to remove %(objecttype) from the caveats of\nremote-object-info and show %(objecttype) support.\n\nNow that type is supported and the default format unified, update the\ntests to expect the new default format.\n\nMentored-by: Karthik Nayak \u003ckarthik.188@gmail.com\u003e\nMentored-by: Chandra Pratap \u003cchandrapratap3519@gmail.com\u003e\nSigned-off-by: Pablo Sabater \u003cpabloosabaterr@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "4c842de0e4580dc217d9ba5519e8348915f9c816",
      "tree": "1ee263cdc3fdb73c931289fa03dae2d9dfe7b220",
      "parents": [
        "afa4ea56fedc3ca04d3b00a3ef930833e7ad68ea"
      ],
      "author": {
        "name": "Pablo Sabater",
        "email": "pabloosabaterr@gmail.com",
        "time": "Sat Aug 08 02:02:24 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri Aug 07 18:50:08 2026 -0700"
      },
      "message": "serve: advertise type capability\n\nThe server and the client can handle type requests but the client won\u0027t\nask for it until the server advertises it.\n\nAdd type to the advertised capabilities so the client knows that it can\nrequest it.\n\nMentored-by: Karthik Nayak \u003ckarthik.188@gmail.com\u003e\nMentored-by: Chandra Pratap \u003cchandrapratap3519@gmail.com\u003e\nSigned-off-by: Pablo Sabater \u003cpabloosabaterr@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "afa4ea56fedc3ca04d3b00a3ef930833e7ad68ea",
      "tree": "99e102a7c7a3fb7bb88f60be9c365fef90c8fefa",
      "parents": [
        "7692fa90199c623629f07e8883f5df8cfa859e03"
      ],
      "author": {
        "name": "Pablo Sabater",
        "email": "pabloosabaterr@gmail.com",
        "time": "Sat Aug 08 02:02:23 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri Aug 07 18:50:08 2026 -0700"
      },
      "message": "fetch-object-info: parse type from server response\n\nThe server can handle type requests but does not advertise the\ncapability yet. Prepare the client to know how to parse the server\nresponse once the server advertises the type capability.\n\nMentored-by: Karthik Nayak \u003ckarthik.188@gmail.com\u003e\nMentored-by: Chandra Pratap \u003cchandrapratap3519@gmail.com\u003e\nSigned-off-by: Pablo Sabater \u003cpabloosabaterr@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "7692fa90199c623629f07e8883f5df8cfa859e03",
      "tree": "6c6485f04db010fb8110cc7643eba76a980580d2",
      "parents": [
        "567e62b1b946407224dedfb85f8c9220983a5e13"
      ],
      "author": {
        "name": "Pablo Sabater",
        "email": "pabloosabaterr@gmail.com",
        "time": "Sat Aug 08 02:02:22 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri Aug 07 18:50:08 2026 -0700"
      },
      "message": "protocol-caps: add type support to object-info\n\nTeach the server-side object-info handler to accept type as a requested\nfield. When the client includes type in its object-info request, the\nserver returns the requested object type.\n\nWhile touching send_info(), wrap an over-long line and fix the bit field\nstyle of requested_info.size.\n\nMentored-by: Karthik Nayak \u003ckarthik.188@gmail.com\u003e\nMentored-by: Chandra Pratap \u003cchandrapratap3519@gmail.com\u003e\nSigned-off-by: Pablo Sabater \u003cpabloosabaterr@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "567e62b1b946407224dedfb85f8c9220983a5e13",
      "tree": "d6c3e35a55d49b2269f58b59900d42030a43fbfd",
      "parents": [
        "50dd6d370cd6421b523347ffa94bdd35bd264833"
      ],
      "author": {
        "name": "Jeff King",
        "email": "peff@peff.net",
        "time": "Sat Aug 08 02:02:21 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri Aug 07 18:50:08 2026 -0700"
      },
      "message": "transport: drop remote object-info fields from transport struct\n\nA remote object-info request needs three things: the transport for\ncontacting the remote, the list of oids to request, and a place to store\nthe output.\n\nRather than take these as function parameters, we take only the\ntransport object, and expect the caller to have placed the other two\ninto special fields in the transport struct. But this doesn\u0027t make much\nsense. The set of oids and results are really only valid for one\nrequest. There is no reason the transport would need to hang on to them\noutside of the single function call.\n\nEven though we save a few lines passing the parameters around through\nthe various vtable functions, the result is harder to understand (for\nexample, who is responsible for cleaning up results, and when should it\nhappen?). It also opens up the possibility of a subtle bug. A caller is\nlikely to point those fields to stack variables which could go out of\nscope, and the transport struct would be left holding invalid pointers.\n\nThis is mostly harmless now, as we disconnect the transport immediately\nafter the sole caller of transport_fetch_object_info(). But conceptually\nwe could keep the transport open and make multiple fetch calls (and\nreuse the same connection to the helper, to a remote HTTP server, and so\non).\n\nSo let\u0027s pull these out of the struct and pass them as function\nparameters. It\u0027s a little more verbose, but I think more clearly\nillustrates the intent. I\u0027ve also tweaked a few function signatures to\nmark the input oid array as const, since it is purely an input to the\nfunction.\n\nSigned-off-by: Jeff King \u003cpeff@peff.net\u003e\nSigned-off-by: Pablo Sabater \u003cpabloosabaterr@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "50dd6d370cd6421b523347ffa94bdd35bd264833",
      "tree": "c48b6c99aacddf55fb10b8dddbde00e31fa86bdb",
      "parents": [
        "c5c971d967617592d27c1b7db72455f9277fad47"
      ],
      "author": {
        "name": "Pablo Sabater",
        "email": "pabloosabaterr@gmail.com",
        "time": "Sat Aug 08 02:02:20 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri Aug 07 18:50:08 2026 -0700"
      },
      "message": "fetch-object-info: die() on the remaining error path\n\nEvery failure in fetch_object_info() dies except one: a short read while\nparsing the attribute lines returns -1. That -1 is then passed through\nfetch_object_info_via_pack() and get_remote_info() up to cat-file, only\nto die() with a generic message.\n\nDie in fetch_object_info() instead, consistently with the rest of its\nerror paths, and make fetch_object_info() void.\n\nMentored-by: Karthik Nayak \u003ckarthik.188@gmail.com\u003e\nMentored-by: Chandra Pratap \u003cchandrapratap3519@gmail.com\u003e\nSigned-off-by: Pablo Sabater \u003cpabloosabaterr@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "c5c971d967617592d27c1b7db72455f9277fad47",
      "tree": "ab87dcdce79f74f66689da3a12d9f5406cdace0c",
      "parents": [
        "d43b4d3fa10ee596c1bb6517f30d6f4daad906e4"
      ],
      "author": {
        "name": "Pablo Sabater",
        "email": "pabloosabaterr@gmail.com",
        "time": "Sat Aug 08 02:02:19 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri Aug 07 18:50:08 2026 -0700"
      },
      "message": "fetch-object-info: use dedicated struct for the results\n\nfetch_object_info() collects information about N objects, but it stores\nthe results in an array of object_info. That struct holds the extended\nparameters of read_object_info() (The optional outputs the caller wants\nfilled). Its pointers tell that function where to write the answers for\na single object. object_info is not meant to be the final storage, and\nsince fetch_object_info() does not call read_object_info(), there is no\nreason to use it. Using it means allocating one scalar per object per\nattribute just to have those pointers somewhere to point at.\n\nAdd struct fetch_object_info_results. The caller sets the wants_* flags\nto say what it is interested in, and fetch_object_info() allocates one\narray per attribute. A set wants_* flag means \"asked for\", while a\nnon-NULL array means \"available\". The caller releases the arrays with\nfree_fetch_object_info_results().\n\nThe object_info_options string list is no longer needed. Filtering\nagainst the server\u0027s advertisement now sets local ask_* flags, and\nsend_object_info_request() turns those into the v2 protocol option\nstrings. remote_atom_map[] existed only to map those strings back into\natom names, so drop it and build remote_allowed_atoms from the result\narrays.\n\nCurrently for wants_* and ask_* there is only the \u0027size\u0027 variant but a\nsubsequent commit will add \u0027*_type\u0027.\n\nfree_object_info_contents() loses its only caller and is dropped.\n\nDropping the allow-list check makes the final else reachable from the\nwire, so die() instead of BUG(): an unknown attribute is the server\u0027s\nerror, not ours.\n\nHelped-by: Jeff King \u003cpeff@peff.net\u003e\nHelped-by: Junio C Hamano \u003cgitster@pobox.com\u003e\nMentored-by: Karthik Nayak \u003ckarthik.188@gmail.com\u003e\nMentored-by: Chandra Pratap \u003cchandrapratap3519@gmail.com\u003e\nSigned-off-by: Pablo Sabater \u003cpabloosabaterr@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "d43b4d3fa10ee596c1bb6517f30d6f4daad906e4",
      "tree": "4e3a9b16a84736dfea8ce2db9e85ca3148705ac1",
      "parents": [
        "62e5104a719bfdb7e536ae9d4a7a816fb6998737"
      ],
      "author": {
        "name": "Pablo Sabater",
        "email": "pabloosabaterr@gmail.com",
        "time": "Sat Aug 08 02:02:18 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri Aug 07 18:50:07 2026 -0700"
      },
      "message": "fetch-object-info: pass arguments directly instead of a struct\n\nstruct object_info_args groups three pointers that already live in the\ntransport and are given to fetch_object_info().\nGrouping them into a struct reduces the number of parameters, but it\nsuggests that the three belong together, when they are unrelated and end\nup being accessed as args-\u003e* independently.\n\nDrop the struct and pass those parameters directly to\nfetch_object_info() and send_object_info_request(). This should have no\nchange in behavior.\n\nHelped-by: Jeff King \u003cpeff@peff.net\u003e\nHelped-by: Junio C Hamano \u003cgitster@pobox.com\u003e\nMentored-by: Karthik Nayak \u003ckarthik.188@gmail.com\u003e\nMentored-by: Chandra Pratap \u003cchandrapratap3519@gmail.com\u003e\nSigned-off-by: Pablo Sabater \u003cpabloosabaterr@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "62e5104a719bfdb7e536ae9d4a7a816fb6998737",
      "tree": "b6733369c35544d5555b70bcac955ecf03fe7f3f",
      "parents": [
        "c3a8f4303c9e7b72ab506d58177648cd90026be6"
      ],
      "author": {
        "name": "Pablo Sabater",
        "email": "pabloosabaterr@gmail.com",
        "time": "Sat Aug 08 02:02:17 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri Aug 07 18:50:07 2026 -0700"
      },
      "message": "fetch-object-info: detect malformed server responses\n\nThe loop reading the object-info response stops as soon as the reader\nreturns something other than PACKET_READ_NORMAL, or once it has read as\nmany lines as we requested. Neither end is checked.\n\nA server that answers with fewer objects leaves the end of the result\narrays empty, and the caller trusts that every requested object was\nfilled in. A server that answers with more leaves the extra packets\nunread. On stateless transports check_stateless_delimiter() notices, but\non the others it passes unnoticed.\n\nCheck both limits by extracting the packet_reader_read() from the loop\ncondition, so the loop no longer consumes the last packet (flush). If\nwhile looping the read is different from a PACKET_READ_NORMAL, die()\nmeaning there are fewer objects than expected. After iterating, we only\nexpect a flush, so if the last packet is not a flush, die().\n\nHelped-by: Junio C Hamano \u003cgitster@pobox.com\u003e\nMentored-by: Karthik Nayak \u003ckarthik.188@gmail.com\u003e\nMentored-by: Chandra Pratap \u003cchandrapratap3519@gmail.com\u003e\nSigned-off-by: Pablo Sabater \u003cpabloosabaterr@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "c3a8f4303c9e7b72ab506d58177648cd90026be6",
      "tree": "ae14005c7a63a7494f62591263bfbe13a4727764",
      "parents": [
        "669c4ad5dc61cca394860909d28152293d6fcdef"
      ],
      "author": {
        "name": "Pablo Sabater",
        "email": "pabloosabaterr@gmail.com",
        "time": "Sat Aug 08 02:02:16 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri Aug 07 18:50:07 2026 -0700"
      },
      "message": "t5701: use test_file_size() to get the size of a file\n\nThe \u0027basics of object-info\u0027 test runs \u0027wc -c | xargs\u0027 twice to get the\nsize of two.t. The pipe to xargs is only there to strip the blanks\nthat some platforms pad the output of wc with.\n\nUse the test_file_size() helper, which outputs the size directly, and\nstore the result in a variable. Because \u0027git rev-parse two:two.t\u0027 is\nalso run multiple times, store its output in a variable as well.\n\nStoring them in variables outside the HERE-document has the added\nbenefit of preserving their exit statuses.\n\nMentored-by: Karthik Nayak \u003ckarthik.188@gmail.com\u003e\nMentored-by: Chandra Pratap \u003cchandrapratap3519@gmail.com\u003e\nSigned-off-by: Pablo Sabater \u003cpabloosabaterr@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "010afd3166ddc64c9863b1506f12cbcdda0d4ea1",
      "tree": "a2d44b3e277c174d457c3cee35ece9347aab6333",
      "parents": [
        "262508d27a9aa776d075f4e79725422e5ab4f999"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri Aug 07 12:02:39 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri Aug 07 14:48:01 2026 -0700"
      },
      "message": "The 12th batch\n\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "262508d27a9aa776d075f4e79725422e5ab4f999",
      "tree": "e860220f35f689cf0e4a82d348eb525b69bc6f8b",
      "parents": [
        "b12f37d600382d2a109cc665ad7658f83bd4f82c",
        "eede1e69fe4b852f14cade6c18abd156fbcc8cd1"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri Aug 07 14:48:01 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri Aug 07 14:48:01 2026 -0700"
      },
      "message": "Merge branch \u0027ds/sparse-index-ita-crash\u0027\n\nA crash in the \u0027sparse-index\u0027 collapse code when encountering an\ninvalidated cache-tree node (due to an intent-to-add path) has been\nfixed by avoiding collapsing such subtrees.\n\n* ds/sparse-index-ita-crash:\n  sparse-index: avoid crash on intent-to-add entry outside the cone\n"
    },
    {
      "commit": "b12f37d600382d2a109cc665ad7658f83bd4f82c",
      "tree": "28d1963facd3d98a006027da1be32b990b9a5fd0",
      "parents": [
        "aa2932aedde6b1fb40cdab6176f69ab9409bf2ae",
        "b56b48301ea221ae3dd6dc01f887f0b72e10e729"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri Aug 07 14:48:01 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri Aug 07 14:48:01 2026 -0700"
      },
      "message": "Merge branch \u0027dl/pack-bitmap-position-zero\u0027\n\nA boundary case check in reachability bitmap traversal has been\ncorrected to properly handle the object at position zero, which was\npreviously skipped, leading to redundant bitmap loading.\n\n* dl/pack-bitmap-position-zero:\n  pack-bitmap: handle objects at bitmap position zero\n"
    },
    {
      "commit": "aa2932aedde6b1fb40cdab6176f69ab9409bf2ae",
      "tree": "25b55a278d194b61db3a8b216f7498f991399812",
      "parents": [
        "93a85701abaa03790133c8a87529a726ae9bee36",
        "68cce04a028cac13fa1fd7a368801fac3d8b156b"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri Aug 07 14:48:00 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri Aug 07 14:48:01 2026 -0700"
      },
      "message": "Merge branch \u0027tc/merge-default-to-upstream-leakfix\u0027\n\nA memory leak in \u0027git merge\u0027 when run without arguments (which\ntriggers the default-to-upstream path) has been fixed.  A test has\nbeen added to cover this case.\n\n* tc/merge-default-to-upstream-leakfix:\n  merge: fix leak with merge.defaultToUpstream\n"
    },
    {
      "commit": "93a85701abaa03790133c8a87529a726ae9bee36",
      "tree": "3c73021df5a085f39057b355e877c2d26262316c",
      "parents": [
        "ef11815b1ef3271f79a9e15648acb20511de63f7",
        "2abc7f0304606e23199416ffa3dbc84fa2d431d3"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri Aug 07 14:48:00 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri Aug 07 14:48:00 2026 -0700"
      },
      "message": "Merge branch \u0027jk/cat-file-batch-wo-type-fix\u0027\n\n\u0027git cat-file --batch-command\u0027 that asked for \u0027contents\u0027 without\n\u0027type\u0027 segfaults, which has been corrected.\n\n* jk/cat-file-batch-wo-type-fix:\n  cat-file: handle content request for --batch-command without type\n"
    },
    {
      "commit": "ef11815b1ef3271f79a9e15648acb20511de63f7",
      "tree": "a4721f69364698235c25ad00bbb03603be76cf02",
      "parents": [
        "babe559ffb0a3ffd8c72641d318091c36e8ef2d5",
        "da0fb7e36e9864f7f41d3a2dd291ffd34fcec97f"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri Aug 07 14:48:00 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri Aug 07 14:48:00 2026 -0700"
      },
      "message": "Merge branch \u0027mm/revision-pure-get-commit-action\u0027\n\nThe get_commit_action() function has been refactored to be a pure\npredicate by moving the side-effecting line-level log range folding to\nsimplify_commit().  This ensures that evaluating a commit\u0027s action\nbefore the walk reaches it does not prematurely mutate its tracked\nline ranges, making it safer for potential lookahead evaluations.\n\n* mm/revision-pure-get-commit-action:\n  revision: make get_commit_action() a pure predicate\n"
    },
    {
      "commit": "babe559ffb0a3ffd8c72641d318091c36e8ef2d5",
      "tree": "e2528423555ad9ee8e53e59baa3cc6d0fbd1513f",
      "parents": [
        "2c78326f810173a4f3aefd8021f1e07575412481",
        "151726d3ca54cbd279d527dc048133ead5c8b582"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri Aug 07 14:48:00 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri Aug 07 14:48:00 2026 -0700"
      },
      "message": "Merge branch \u0027jk/diff-relative-cached-unmerged-more\u0027\n\nThe code path that deals with relative paths in the \u0027diff-lib\u0027 has\nbeen cleaned up.\n\n* jk/diff-relative-cached-unmerged-more:\n  diff-lib: skip paths outside prefix in oneway_diff()\n  diff-lib: drop stale comment about advancing o-\u003epos\n"
    },
    {
      "commit": "5bd4f43456aae6fa942eb6c6ace6244d09e01d08",
      "tree": "13ec0bcc3420706d6aa66d7dafa576f615c60496",
      "parents": [
        "21db416cd2bf658ce79fc928c65b86e981062e8e"
      ],
      "author": {
        "name": "Patrick Steinhardt",
        "email": "ps@pks.im",
        "time": "Fri Aug 07 08:18:07 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri Aug 07 08:57:26 2026 -0700"
      },
      "message": "fast-import: use writev(3p) to send cat-blob responses\n\nWhen answering a `cat-blob` command, `cat_blob()` issues three separate\ncalls to write(3p) on the cat-blob fd: one for the header line, one for\nthe full blob payload, and one for the trailing newline. Frontends like\ngit-filter-repo issue these commands in bulk, once per rewritten blob,\nso the syscall overhead adds up.\n\nUse `writev_in_full()` to send all three parts with a single syscall.\n\nThis can be benchmarked with the following setup:\n\n    $ git cat-file --unordered --filter\u003dobject:type\u003dblob\n        --batch-check\u003d\u0027cat-blob %(objectname)\u0027 --batch-all-objects \u003erequest\n    $ git fast-import --cat-blob-fd\u003d3 \u003crequest\n\nExecuting this with 100,000 objects in linux.git:\n\n  Benchmark 1: HEAD~\n    Time (mean ± σ):      1.320 s ±  0.003 s    [User: 1.154 s, System: 0.161 s]\n    Range (min … max):    1.314 s …  1.324 s    10 runs\n\n  Benchmark 2: HEAD\n    Time (mean ± σ):      1.270 s ±  0.022 s    [User: 1.133 s, System: 0.132 s]\n    Range (min … max):    1.209 s …  1.282 s    10 runs\n\n  Summary\n    HEAD ran\n      1.04 ± 0.02 times faster than HEAD~\n\nSigned-off-by: Patrick Steinhardt \u003cps@pks.im\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "21db416cd2bf658ce79fc928c65b86e981062e8e",
      "tree": "c0afcb0b8480d5d9621e95e9481247cab2fe21c3",
      "parents": [
        "a4e2c0fc81198fa84c1107daa0a33de6cc6d9c3a"
      ],
      "author": {
        "name": "Patrick Steinhardt",
        "email": "ps@pks.im",
        "time": "Fri Aug 07 08:18:06 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri Aug 07 08:57:25 2026 -0700"
      },
      "message": "sideband: use writev(3p) to send pktlines\n\nEvery pktline that we send out via `send_sideband()` currently requires\ntwo syscalls: one to write the pktline\u0027s length, and one to send its\ndata. This typically isn\u0027t all that much of a problem, but under extreme\nload the syscalls may cause contention in the kernel.\n\nRefactor the code to instead use the newly introduced writev(3p) infra\nso that we can send out the data with a single syscall. This reduces the\nnumber of syscalls from around 133,000 calls to write(3p) to around\n67,000 calls to writev(3p).\n\nThis change leads to a performance improvement for git-upload-pack(1),\nbut we have to cheat a bit to really make it measurable. Usually, the\ntime is strongly dominated by generating the packfile itself. But if we\nprecompute the pack and serve it via the pack-objects hook then we can\nessentially eliminate that overhead. The following setup is executed in\nthe Git repository:\n\n  $ cat \u003erequest \u003c\u003c-EOF\n  0048want 5ce91c059e41090e7d2cffad39c04af8acf98dc1 side-band no-progress\n  00000009done\n  EOF\n  $ echo 5ce91c059e41090e7d2cffad39c04af8acf98dc1 | git pack-objects --revs --stdout \u003epack\n  $ cat \u003ehook \u003c\u003c-EOF\n  #!/bin/sh\n  cat \u003e/dev/null\n  cat \"$(pwd)\"/pack\n  EOF\n  $ chmod u+x hook\n  $ git -c uploadpack.packObjectsHook\u003d\"$(pwd)\"/hook upload-pack . \u003crequest\n\nBenchmarking the last command leads to the following results:\n\n  Benchmark 1: HEAD~\n    Time (mean ± σ):     192.9 ms ±   0.6 ms    [User: 106.5 ms, System: 95.3 ms]\n    Range (min … max):   191.7 ms … 194.1 ms    50 runs\n\n  Benchmark 2: HEAD\n    Time (mean ± σ):     141.1 ms ±   0.7 ms    [User: 63.2 ms, System: 86.6 ms]\n    Range (min … max):   139.8 ms … 142.7 ms    50 runs\n\n  Summary\n    HEAD ran\n      1.37 ± 0.01 times faster than HEAD~\n\nThis might not be impressive in absolute numbers when you also take into\naccount the time it takes to generate the packfile itself. But GitLab\n(and supposedly other forges) have caching mechanisms in place that work\nexactly like the above setup, where repeated incoming requests can be\nserved from the same cached packfile. And in those cases, the impact is\nsizeable.\n\nMore importantly though, as hinted at above, GitLab has observed in the\npast that with enough cache hits we eventually start to saturate a\nsemaphore in the Linux kernel itself in the pipe write path. This\nbottleneck is being moved a bit by having to do less syscalls.\n\nSuggested-by: Jeff King \u003cpeff@peff.net\u003e\nSigned-off-by: Patrick Steinhardt \u003cps@pks.im\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "a4e2c0fc81198fa84c1107daa0a33de6cc6d9c3a",
      "tree": "2df29d49a4b5e758b8aa0464e6c116247e735502",
      "parents": [
        "d70eb7f3600db5fabb538ce35b186db68854b2a8"
      ],
      "author": {
        "name": "Patrick Steinhardt",
        "email": "ps@pks.im",
        "time": "Fri Aug 07 08:18:05 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri Aug 07 08:57:25 2026 -0700"
      },
      "message": "wrapper: properly handle MAX_IO_SIZE in writev(3p)\n\nSome systems like NonStop set a comparatively small `MAX_IO_SIZE`, which\nlimits the maximum number of bytes we\u0027re allowed to write in a single\ncall. We already handle this limit properly in `xwrite()`, but we have\nrecently introduced wrappers for writev(3p) where we don\u0027t. This will\ncause the syscall to return EINVAL in case somebody passes an iovec\nentry to writev(3p) that is larger than `MAX_IO_SIZE`.\n\nIntroduce a new function `xwritev()` that is similar to `xwrite()` in\nthat it handles such platform-specific nuances:\n\n  - We only pass the leading iovec entries to writev(3p) that fit into\n    `MAX_IO_SIZE`, pretending that the underlying syscall performed a\n    short write. This mirrors how `xwrite()` chomps overly large\n    requests before handing them to write(3p). As a consequence, callers\n    will never see writev(3p)\u0027s EINVAL error for requests whose summed\n    length would overflow an ssize_t, but observe a short write instead.\n\n  - If already the first iovec entry exceeds the limit we instead punt\n    to `xwrite()`, which knows to handle this case for us.\n\n  - We restart the underlying syscall on EINTR and EAGAIN, just like\n    `xwrite()` does for write(3p).\n\nAdapt `writev_in_full()` to use this new wrapper. With the retry logic\nnow living in `xwritev()`, the calling loop becomes the exact mirror\nimage of `write_in_full()`, which also retains the responsibility of\ntranslating a zero-length write into ENOSPC.\n\nReported-by: Randall Becker \u003crandall.becker@nexbridge.ca\u003e\nHelped-by: Jeff King \u003cpeff@peff.net\u003e\nHelped-by: Junio C Hamano \u003cgitster@pobox.com\u003e\nSigned-off-by: Patrick Steinhardt \u003cps@pks.im\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "d70eb7f3600db5fabb538ce35b186db68854b2a8",
      "tree": "4ba50bd59cdffc5caaa56dadfc2c13565482d356",
      "parents": [
        "8b0ab33247e7ac86f2cecd144991301b6fe6a55b"
      ],
      "author": {
        "name": "Patrick Steinhardt",
        "email": "ps@pks.im",
        "time": "Fri Aug 07 08:18:04 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri Aug 07 08:57:25 2026 -0700"
      },
      "message": "wrapper: introduce writev(3p) wrappers\n\nIn the preceding commit we have added a compatibility wrapper for the\nwritev(3p) syscall. Introduce some generic wrappers for this function\nthat we nowadays take for granted in the Git codebase.\n\nSigned-off-by: Patrick Steinhardt \u003cps@pks.im\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "8b0ab33247e7ac86f2cecd144991301b6fe6a55b",
      "tree": "f24734da25f7d2715ecf604d1e5873d5d7ae2ea0",
      "parents": [
        "d35c5399e3e54ac277bb391fc2f6be3e816d312b"
      ],
      "author": {
        "name": "Patrick Steinhardt",
        "email": "ps@pks.im",
        "time": "Fri Aug 07 08:18:03 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Fri Aug 07 08:57:25 2026 -0700"
      },
      "message": "compat/posix: introduce writev(3p) wrapper\n\nIn a subsequent commit we\u0027re going to add the first caller to\nwritev(3p). Introduce a compatibility wrapper for this syscall that we\ncan use on systems that don\u0027t have this syscall.\n\nThe syscall exists on modern Unixes like Linux and macOS, and seemingly\neven for NonStop according to [1]. It doesn\u0027t seem to exist on Windows\nthough.\n\n[1]: http://nonstoptools.com/manuals/OSS-SystemCalls.pdf\n[2]: https://www.gnu.org/software/gnulib/manual/html_node/writev.html\n\nHelped-by: Johannes Schindelin \u003cJohannes.Schindelin@gmx.de\u003e\nSigned-off-by: Patrick Steinhardt \u003cps@pks.im\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "e927cfeb21d6a217b708216862deb36f144f064b",
      "tree": "d3d8ee5ac74b600103e2b1c4bfb69c75d70528b0",
      "parents": [
        "335fe2545e4d64b79fc28acc945bc3278739d078"
      ],
      "author": {
        "name": "Patrick Steinhardt",
        "email": "ps@pks.im",
        "time": "Fri Aug 07 05:34:30 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Thu Aug 06 21:24:25 2026 -0700"
      },
      "message": "odb: make creation of on-disk structures pluggable\n\nWhen creating a new \"files\" object database source we have to create a\ncouple of directories. These directories are of course specific to this\nparticular backend, and a different backend may require a setup that is\ncompletely different.\n\nMake the creation of on-disk structures pluggable to accommodate for\nthis.\n\nNote that there is one exception though: the \"objects\" directory must\nexist in a repository regardless of which backend is in use. If it\ndoesn\u0027t exist then the repository is not treated as a Git repository at\nall. Consequently, we create this directory regardless of the backend.\n\nSigned-off-by: Patrick Steinhardt \u003cps@pks.im\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "335fe2545e4d64b79fc28acc945bc3278739d078",
      "tree": "c82ce99c40dbac2859bd493569958ad5d7b8926a",
      "parents": [
        "c1d233bd3001530042ff097f6aef0a658b7f79cb"
      ],
      "author": {
        "name": "Patrick Steinhardt",
        "email": "ps@pks.im",
        "time": "Fri Aug 07 05:34:29 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Thu Aug 06 21:24:25 2026 -0700"
      },
      "message": "odb/source: introduce function to map source type to name\n\nIntroduce a new function that maps an object source\u0027s type to a\nhuman-readable name. Use the function to provide better human-readable\nerror messages for the downcasting functions.\n\nSigned-off-by: Patrick Steinhardt \u003cps@pks.im\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "c1d233bd3001530042ff097f6aef0a658b7f79cb",
      "tree": "b2bdaf08bce35d8abaf2ea417b029624c1d3e78d",
      "parents": [
        "30bc6f0e8c2aef5f9280468fa2ca7c170209603f"
      ],
      "author": {
        "name": "Patrick Steinhardt",
        "email": "ps@pks.im",
        "time": "Fri Aug 07 05:34:28 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Thu Aug 06 21:24:25 2026 -0700"
      },
      "message": "setup: defer object database creation\n\nIn a subsequent commit we\u0027ll make the creation of the on-disk data\nstructures of an object database pluggable. This will lead to an\nin-between state where we have already configured the repository\u0027s\nobject database, but it\u0027s not usable yet until we eventually call\n`create_object_directory()`.\n\nLift the call to `odb_new()` out of `apply_repository_format()` so that\ncallers have more wiggle room with when exactly they call it, and adapt\nthem accordingly. The only exception is `init_db()`, where we now defer\ncreating the object database until we call `create_object_database()`.\n\nWith this change, initializing and creating the object database on disk\nis now neatly encapsulated in a single function, which will make it\neasier for a subsequent commit to move creation of the on-disk data\nstructures into the `struct odb_source` backends.\n\nSigned-off-by: Patrick Steinhardt \u003cps@pks.im\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "30bc6f0e8c2aef5f9280468fa2ca7c170209603f",
      "tree": "2ed96df22cfd781544d3105f04973d5959b3f6d3",
      "parents": [
        "8a1ba94eb5863cd7491899bb23a290081e760453"
      ],
      "author": {
        "name": "Patrick Steinhardt",
        "email": "ps@pks.im",
        "time": "Fri Aug 07 05:34:27 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Thu Aug 06 21:24:25 2026 -0700"
      },
      "message": "setup: handle ODB-related environment variables in `odb_new()`\n\nWhen initializing a repository\u0027s object database we have to respect the\nGIT_OBJECT_DIRECTORY and GIT_ALTERNATE_OBJECT_DIRECTORIES environment\nvariables, which can be set by the user to override the default location\nof where we write objects to and read objects from.\n\nThis is handled in `apply_repository_format()`, which is fine. But in a\nsubsequent commit we\u0027ll have to defer constructing the object database\nto a later point in some cases, and that will require a second site\nwhere we call `odb_new()`. And of course, that second site would have to\nhandle those environment variables, as well.\n\nIt would be somewhat awkward to duplicate the logic though. But there\u0027s\na better alternative: instead of handling this logic in \"setup.c\", we\ncan easily handle environment variables in `odb_new()` itself. This\nensures that object database creation is neatly self-contained, and we\ndon\u0027t have to duplicate any of the logic.\n\nAnother benefit is that in a future patch series we plan to move\nhandling of alternates into the backends themselves [1], and that will\nrequire us to also handle those environment variables in the \"files\"\nbackend itself. So moving the logic into the ODB level already gets us\none step closer to that goal.\n\nRefactor the logic accordingly.\n\n[1]: https://lore.kernel.org/git/amLgMqkqxR8mKIbT@pks.im/\n\nSigned-off-by: Patrick Steinhardt \u003cps@pks.im\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "8a1ba94eb5863cd7491899bb23a290081e760453",
      "tree": "c135e224a42279a867e0262931fe777de1f0e515",
      "parents": [
        "ca571025d86b55933d493e38d6e72824bcf5a80a"
      ],
      "author": {
        "name": "Patrick Steinhardt",
        "email": "ps@pks.im",
        "time": "Fri Aug 07 05:34:26 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Thu Aug 06 21:24:25 2026 -0700"
      },
      "message": "setup: detangle loading of loose object maps\n\nWhen a repository is configured to use a compatibility hash function\nthen we load the loose object map when we initialize the repository.\nThis object map provides the mappings between the canonical object hash\nand the compatibility object hash.\n\nLoading the object map happens in `repo_set_compat_hash_algo()`, which\ncalls `repo_read_loose_object_map()` in case the compatibility object\nhash is non-zero. This setup sequence has two major downsides:\n\n  - We assume that the primary object database is the \"files\" object\n    database and unconditionally downcast it. This will cause us to BUG\n    in case a different object database type was used together with a\n    compat hash algorithm.\n\n  - We require the object database to already have been initialized when\n    configuring the object database. This means that we must intermix\n    configuration of the repository and initialization of its\n    sub-structures in a weird way.\n\nRefactor the logic so that we instead load the loose object map via the\n\"loose\" backend, which fixes both of the above issues.\n\nSigned-off-by: Patrick Steinhardt \u003cps@pks.im\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "ca571025d86b55933d493e38d6e72824bcf5a80a",
      "tree": "49a66224c98d227297611f5fee06094d6231650a",
      "parents": [
        "9a0c4701dcd5725c4184599322b52933ff5005ca"
      ],
      "author": {
        "name": "Patrick Steinhardt",
        "email": "ps@pks.im",
        "time": "Fri Aug 07 05:34:25 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Thu Aug 06 21:24:25 2026 -0700"
      },
      "message": "loose: load loose object map for the correct source\n\nWhen loading the loose object map via `load_one_loose_object_map()` we\npass in both a repository and the corresponding source. We ultimately\ndon\u0027t really respect the passed-in source though as we instead always\nload the map via the common directory. This doesn\u0027t make any sense\nthough, as the function is called in a loop through all sources, and as\nsuch the expectation is that we\u0027ll load the map that belongs to the\ngiven source. The consequence is that we\u0027ll ignore loose object maps of\nany configured alternates.\n\nFix this bug by instead loading the map via the loose source\u0027s path.\n\nHelped-by: Toon Claes \u003ctoon@iotcl.com\u003e\nSigned-off-by: Patrick Steinhardt \u003cps@pks.im\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "0dc68f404af778338a4090a857d51f16b9ed54b8",
      "tree": "a2675ddf522d9356d9c28fd35224efee42a8ee6a",
      "parents": [
        "4cc9039ff094a99aa2754c7b98ba6621079f0ca1"
      ],
      "author": {
        "name": "Kristoffer Haugsbakk",
        "email": "code@khaugsbakk.name",
        "time": "Thu Aug 06 08:20:22 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Thu Aug 06 10:32:49 2026 -0700"
      },
      "message": "doc: refs: linkgit to git-maintenance(1)\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": "4cc9039ff094a99aa2754c7b98ba6621079f0ca1",
      "tree": "18f2a2f79f8bb6a82f1977d6b217d9cce5b580b6",
      "parents": [
        "a97fcc37c2bc6340a8d7ce78dedf227aac4e9aa7"
      ],
      "author": {
        "name": "Kristoffer Haugsbakk",
        "email": "code@khaugsbakk.name",
        "time": "Thu Aug 06 08:20:21 2026 +0200"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Thu Aug 06 10:32:49 2026 -0700"
      },
      "message": "doc: refs: put ref migration warning under the command\n\nI have to scroll down at least three screens in man(1) from the\n`migrate` description in order to see the “known limitations” for\nit. This is important information since the text says that concurrent\nwrites can lead to an inconsistent migrated state. Let’s move that text\nup to the command description and put it inside a Warning admonition.\n\nThis section made sense when it was added in 25a0023f (builtin/refs:\nnew command to migrate ref storage formats, 2024-06-06); `migrate` was\nthe only subcommand, and this section was visible from the command\ndescription. A one-page man page. But that is not the case anymore\nnow that the command has nine subcommands to describe.\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": "2c78326f810173a4f3aefd8021f1e07575412481",
      "tree": "cf21972264aee69051d99e3ecc6c818a73c48d76",
      "parents": [
        "c165f38e4a6694770723f4480c5cbc2a83b5e451"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed Aug 05 11:10:39 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed Aug 05 11:10:52 2026 -0700"
      },
      "message": "The 11th batch\n\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n"
    },
    {
      "commit": "c165f38e4a6694770723f4480c5cbc2a83b5e451",
      "tree": "43caff3abde08144cc0d1b403c6d46f451513793",
      "parents": [
        "7943c6b110644a2762e31b17095592f48ecb7338",
        "c57c052ae8d8486d88f93f983db4439241669c8a"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed Aug 05 11:10:52 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed Aug 05 11:10:52 2026 -0700"
      },
      "message": "Merge branch \u0027js/mingw-symlink-net-share-leak\u0027\n\nGit for Windows has been updated to avoid auto-detecting the symlink\ntype if the target path starts with a slash, preventing NTLM\ncredential leaks when checking out repositories with crafted\nsymbolic links pointing to network shares.\n\n* js/mingw-symlink-net-share-leak:\n  mingw: skip symlink type auto-detection for network share targets\n"
    },
    {
      "commit": "7943c6b110644a2762e31b17095592f48ecb7338",
      "tree": "cff8910dafcb724537c94c546e513115c5daec8a",
      "parents": [
        "2816039db09eb8044673cb07ca4dfdca83bff399",
        "bc57ecb91537c776d0f34233746b09a88000bd26"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed Aug 05 11:10:52 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed Aug 05 11:10:52 2026 -0700"
      },
      "message": "Merge branch \u0027jk/t0014-dynamic-deprecated-cmds\u0027\n\nThe alias tests in \u0027t/t0014-alias.sh\u0027 have been updated to dynamically\nquery the list of deprecated commands using \u0027git\n--list-cmds\u003ddeprecated\u0027 to avoid test failures when running with\n\u0027WITH_BREAKING_CHANGES\u0027 in a build directory that contains stale\nexecutables of formerly deprecated commands.\n\n* jk/t0014-dynamic-deprecated-cmds:\n  t0014: generate deprecated command names dynamically\n  t0014: factor out choice of deprecated commands\n"
    },
    {
      "commit": "2816039db09eb8044673cb07ca4dfdca83bff399",
      "tree": "280a4c17b04978bcacf9426122d31036ae246a66",
      "parents": [
        "67b1d2fa4304b27fed49a356098db13ba94741fb",
        "1a1579c42d9d4c78d4d4df5e4d3d8bc73e3ddf9b"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed Aug 05 11:10:51 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed Aug 05 11:10:51 2026 -0700"
      },
      "message": "Merge branch \u0027jk/ci-static-analysis-image-bump\u0027\n\nThe image version used by the static-analysis CI job has been bumped\nto ubuntu-latest (Ubuntu 24.04), which brings in a newer Coccinelle\nversion that resolves a severe performance regression.  A false\npositive warning from the \u0027CHECK_ASSERTION_SIDE_EFFECTS\u0027 build with\nGCC 15 in the Bloom filter code has also been silenced to facilitate\nthe image upgrade.\n\n* jk/ci-static-analysis-image-bump:\n  ci: bump ubuntu image version for static-analysis job\n  bloom: silence CHECK_ASSERTION_SIDE_EFFECTS false positive\n"
    },
    {
      "commit": "67b1d2fa4304b27fed49a356098db13ba94741fb",
      "tree": "f2cfda9f4404ec0c32e61762b6c86a5fe8eff620",
      "parents": [
        "82c48eae1fc883d1aade2ace83fef8a46eafde6f",
        "7780bff8d161fe42d65954e026dcc621c50bd128"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed Aug 05 11:10:51 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed Aug 05 11:10:51 2026 -0700"
      },
      "message": "Merge branch \u0027rs/branch-delete-bisect-warning\u0027\n\n\u0027git branch -d\u0027 has been taught to report when a branch cannot be\ndeleted because it is being used in an active bisect run.\n\n* rs/branch-delete-bisect-warning:\n  branch: report active bisect run when rejecting delete\n"
    },
    {
      "commit": "82c48eae1fc883d1aade2ace83fef8a46eafde6f",
      "tree": "b2e05cadf0d9c37832a4309e3ac5da64d185ed48",
      "parents": [
        "524d5ad5ed79bd47e867fcde80273431bcce4b9e",
        "56f3fc9520a52a43aef2cabaf30b71a79c9eca57"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed Aug 05 11:10:51 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed Aug 05 11:10:51 2026 -0700"
      },
      "message": "Merge branch \u0027ps/odb-pluggable-housekeeping\u0027\n\nObject database housekeeping in \u0027git gc\u0027 and \u0027git maintenance\u0027 has\nbeen refactored to be pluggable.  The files-backend-specific logic,\nincluding incremental and geometric repacking as well as object\npruning, has been moved out of the command implementation and into the\nfiles object database source, enabling future alternative object\ndatabase backends to implement their own housekeeping services.\n\n* ps/odb-pluggable-housekeeping:\n  odb: make optimizations pluggable\n  builtin/gc: fix signedness issues in ODB-related functionality\n  builtin/gc: refactor ODB optimizations to operate on \"files\" source\n  builtin/gc: introduce `odb_optimize_required()`\n  builtin/gc: move geometric repacking into `odb_optimize()`\n  builtin/gc: introduce object database optimization options\n  builtin/gc: inline config values specific to the \"files\" backend\n  builtin/gc: make repack arguments self-contained\n  builtin/gc: extract object database optimizations into separate function\n  builtin/gc: move worktree and rerere tasks before object optimizations\n  odb: run \"pre-auto-gc\" hook for all maintenance tasks\n  t7900: simplify how we check for maintenance tasks\n"
    },
    {
      "commit": "524d5ad5ed79bd47e867fcde80273431bcce4b9e",
      "tree": "4d3534a816cdeb7a76641e5c91a3adfe09138830",
      "parents": [
        "f072d0e4a270c9e0afb0f02a1de37daf5a277138",
        "4a3a8ee96c7c749b99c91345db190a2c3720abeb"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed Aug 05 11:10:51 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed Aug 05 11:10:51 2026 -0700"
      },
      "message": "Merge branch \u0027pw/rebase-fixup-fixes\u0027\n\nTwo bugs in how \u0027git rebase\u0027 handles skipped \u0027fixup\u0027 and \u0027squash\u0027\ncommands have been fixed.  One bug caused an incorrect commit count to\nbe shown in the template message when multiple commands were skipped,\nand another prevented the editor from opening when the final command\nin a chain containing \u0027fixup -c\u0027 was skipped.\n\n* pw/rebase-fixup-fixes:\n  rebase: remember fixup -c after skipping fixup/squash\n  rebase -i: fix counting of fixups after rebase --skip\n"
    },
    {
      "commit": "f072d0e4a270c9e0afb0f02a1de37daf5a277138",
      "tree": "64894c840f452744812b5eb14eaea65d5028f004",
      "parents": [
        "7a403c3ee5519770b2630b49a59eba7815c8c210",
        "447126ed7df66b396235766547a57649f925aac2"
      ],
      "author": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed Aug 05 11:10:50 2026 -0700"
      },
      "committer": {
        "name": "Junio C Hamano",
        "email": "gitster@pobox.com",
        "time": "Wed Aug 05 11:10:51 2026 -0700"
      },
      "message": "Merge branch \u0027jk/diff-relative-cached-unmerged\u0027\n\n\u0027git diff --relative\u0027 running with \u0027--cached\u0027 has been corrected to\navoid a segfault when encountering unmerged paths outside the\nprefix.\n\n* jk/diff-relative-cached-unmerged:\n  diff-lib: add idx/tree sanity check to oneway_diff\n  diff: ignore unmerged paths outside prefix with --relative --cached\n"
    }
  ],
  "next": "25285a6763543242514f3a58c504fd80e9996df2"
}
