)]}'
{
  "commit": "8f909ff4e9e883bf4938c0f0f67b9e1d48cc0167",
  "tree": "da38e54c200b1d5a8a6a84d921e3490c089aca40",
  "parents": [
    "22eef58fba36a6dd9cadfe606b9f711e89266ae3"
  ],
  "author": {
    "name": "Elijah Newren",
    "email": "newren@gmail.com",
    "time": "Sat Aug 29 07:00:31 2026 +0000"
  },
  "committer": {
    "name": "Junio C Hamano",
    "email": "gitster@pobox.com",
    "time": "Sun Aug 30 13:37:42 2026 -0700"
  },
  "message": "packfile: recover when a multi-pack-index names a removed pack\n\nA geometric repack writes a new pack and multi-pack-index and then\ndeletes the packs the new one subsumes.  A process still using the\nprevious MIDX keeps seeing a removed pack listed as the owner of some\nobjects.  Since a MIDX attributes each object to exactly one pack, such\nan object is served only through its recorded owner; if that owner was\njust removed, find_pack_entry() cannot serve it -- the MIDX lookup routes\nto the missing pack, and the regular pack fallback deliberately skips\nevery MIDX-covered pack, so a surviving copy in another covered pack\n(e.g. a kept base pack) is never consulted.\n\nUnlike the ordinary \"a pack\u0027s .idx is mapped but its .pack is gone\"\nrace, the second read does not rescue us.  Reloading the on-disk pack set\ndoes not reload the borrowed, cached MIDX (freeing it under the code that\ncaches the \"struct multi_pack_index *\" would be a use-after-free), so the\nstale MIDX keeps routing to the removed pack and the surviving copy stays\nhidden behind the covered-pack skip.  cat-file, rev-list and pack-objects\ncan thus all spuriously fail with \"unable to read object\".\n\nTeach find_pack_entry() to recover.  The MIDX lookup now returns a\ntri-state, distinguishing an object absent from the MIDX from one it owns\nvia a pack that can no longer be opened; in the latter case, once the\nregular fallback has also missed, scan the MIDX\u0027s packs directly for a\nsurviving copy.  Because the return value is no longer a boolean, rename\nfill_midx_entry() to midx_fill_entry() so callers must reckon with the\nnew enum rather than silently treat MIDX_FILL_OWNER_UNAVAILABLE as a hit.\n\nDo the scan only on the second read (OBJECT_INFO_SECOND_READ): by then\nthe cheaper on-disk reload has run, so an object merely relocated into a\nnew (uncovered) pack has already been found by the regular fallback, and\nonly a genuine hidden duplicate reaches the rescan.  A QUICK caller that\nskips the second read simply accepts the false negative, as QUICK is\ndesigned to.\n\nReloading the stale MIDX would be a more complete fix but is much more\ninvolved (the borrowers above need proper invalidation), so leave that\nfor later.\n\nAssisted-by: Claude Opus 4.8 \u0026 GPT-5.6 Sol\nHelped-by: Jeff King \u003cpeff@peff.net\u003e\nSigned-off-by: Elijah Newren \u003cnewren@gmail.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "399acd0f225d930b5d5c815caeeb583b0341bfbd",
      "old_mode": 33188,
      "old_path": "builtin/pack-objects.c",
      "new_id": "751d5d34498c8817550aa46bc6dc6ca805ccc0a4",
      "new_mode": 33188,
      "new_path": "builtin/pack-objects.c"
    },
    {
      "type": "modify",
      "old_id": "37f082dbdd5558304c40d780b92238f2ea3a241e",
      "old_mode": 33188,
      "old_path": "midx.c",
      "new_id": "6d1c548e3dae8e207558971f641862cac763fbfe",
      "new_mode": 33188,
      "new_path": "midx.c"
    },
    {
      "type": "modify",
      "old_id": "1f2f2d53214da5f5cc4100c087588d9d6cb3b18f",
      "old_mode": 33188,
      "old_path": "midx.h",
      "new_id": "4b768769b98a104b95cd686486217c66a0b0f932",
      "new_mode": 33188,
      "new_path": "midx.h"
    },
    {
      "type": "modify",
      "old_id": "1a12a605dbc62e71c88ba364a028ddff1eb71149",
      "old_mode": 33188,
      "old_path": "odb/source-packed.c",
      "new_id": "90d88c0a121c5e801aea92a380fa314b199749cc",
      "new_mode": 33188,
      "new_path": "odb/source-packed.c"
    },
    {
      "type": "modify",
      "old_id": "27a05da957afc2bb061a0414bd13db3d1b50fe73",
      "old_mode": 33188,
      "old_path": "t/helper/test-read-midx.c",
      "new_id": "9c5e30876102eb06af100176ed17047c9e2cb2d6",
      "new_mode": 33188,
      "new_path": "t/helper/test-read-midx.c"
    },
    {
      "type": "modify",
      "old_id": "68143cb5b76952586323b54a5aa71abcd00bf679",
      "old_mode": 33261,
      "old_path": "t/t5319-multi-pack-index.sh",
      "new_id": "2b8ff6f3ed28cd15b246afde9e3133f00cd73e73",
      "new_mode": 33261,
      "new_path": "t/t5319-multi-pack-index.sh"
    }
  ]
}
