)]}'
{
  "commit": "cef2d8c4cbca930c4f57e81739fe1663be7ab18d",
  "tree": "3bcd7e6d904cb858824f1f806f911615359f730e",
  "parents": [
    "72e75ffee70f2e898ae687734aa109f559b39e5c"
  ],
  "author": {
    "name": "Kristofer Karlsson",
    "email": "krka@spotify.com",
    "time": "Wed Oct 07 14:22:57 2026 +0000"
  },
  "committer": {
    "name": "Junio C Hamano",
    "email": "gitster@pobox.com",
    "time": "Wed Oct 07 09:50:48 2026 -0700"
  },
  "message": "fetch: write commit-graph using updated refs only\n\nWhen fetch.writeCommitGraph was introduced in 50f26bd035 (fetch: add\nfetch.writeCommitGraph config setting, 2019-09-02), the stated goal\nwas to stay updated with the latest commits after fetching new\nobjects.  The implementation used write_commit_graph_reachable()\nbecause it was the only API available, but two things have changed\nsince then:\n\n 1. write_commit_graph() was added, and it accepts an explicit set of\n    commits as seeds, enabling more targeted commit-graph updates.\n\n 2. The ref-scanning callback add_ref_to_set() became more expensive\n    in 630cd5194e (commit-graph.c: peel refs in \u0027add_ref_to_set\u0027,\n    2020-07-22) when it started to validate the refs against the odb\n    for correctness.  On a repository with many refs, this makes the\n    full reachable scan unnecessarily costly for a targeted fetch.\n\nOptimize the commit-graph write by using only the newly updated refs\nas seeds instead of scanning all refs after every fetch.  To keep\nthis change small, skip the optimization for multi-remote fetches\n(since that would require propagating the set of refs across process\nboundaries).\n\nThis relies on the commit-graph write being additive, keeping the\ncommits that are already in the graph.  fetch already operates in\nthis mode (COMMIT_GRAPH_WRITE_SPLIT) and now that becomes\nrequired for correctness.  Without that mode, the write would\nreplace the commit-graph and lose other commits.\n\nAfter fetch_one() returns, call prepare_commit_graph() (which is\nmade non-static by this commit) to determine the graph-write mode:\n\n - If no commit-graph exists yet, fall back to the full reachable\n   scan so the first graph creation covers all refs.\n\n - If a commit-graph exists and the fetch updated at least one ref,\n   write incrementally using only the new refs as seeds.\n\n - If a commit-graph exists but the fetch is a no-op, skip the\n   commit-graph write entirely.\n\n - For the multi-remote path (fetch --all), where child processes\n   do the actual fetching, fall back to the full reachable scan.\n\nFull commit-graph coverage of all refs remains the responsibility\nof \"git maintenance\", \"git gc\" and \"git commit-graph write\".\nRegular Git operations may trigger \"git maintenance run --auto\",\nwhich periodically rebuilds the commit-graph from all reachable\nrefs.\n\nThe effect was measured on a synthetic setup: git.git with 200K\nextra packed refs (~206K total), a local file:// remote, an existing\nsplit commit-graph and a warm page cache.  The times below are the\nmedian of 9 runs of the trace2 region fetch/write-commit-graph:\n\n    scenario          before    after\n    no-op fetch       380 ms    (skipped)\n    1 ref updated     357 ms    9.3 ms\n    10 refs updated   359 ms    8.9 ms\n\nSigned-off-by: Kristofer Karlsson \u003ckrka@spotify.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "533fdfe7d80e9de91e6998258e8e2738c5c35134",
      "old_mode": 33188,
      "old_path": "builtin/fetch.c",
      "new_id": "d73eca77aa6826b013819e9a6255dfee1aa1c53f",
      "new_mode": 33188,
      "new_path": "builtin/fetch.c"
    },
    {
      "type": "modify",
      "old_id": "983c11ce8534598734fd793472d3cff7e3584fa0",
      "old_mode": 33188,
      "old_path": "commit-graph.c",
      "new_id": "d042752ff46adda18d8bb0c106bb763a0a4ab43e",
      "new_mode": 33188,
      "new_path": "commit-graph.c"
    },
    {
      "type": "modify",
      "old_id": "13ca4ff010fa18580d2ae5041429bbe47019e3e4",
      "old_mode": 33188,
      "old_path": "commit-graph.h",
      "new_id": "7e48b0ccc0d47336ae8ca387c823bf379bcf2ab1",
      "new_mode": 33188,
      "new_path": "commit-graph.h"
    },
    {
      "type": "modify",
      "old_id": "a8d38d9176fec19ffe6fa4ac3c822a17fdae9769",
      "old_mode": 33261,
      "old_path": "t/t5510-fetch.sh",
      "new_id": "72dcb7fd43f54c169df4f2f777945c0dfb5e8fd4",
      "new_mode": 33261,
      "new_path": "t/t5510-fetch.sh"
    },
    {
      "type": "modify",
      "old_id": "f323ceebd2a7c254993930bb6d16c49563af8666",
      "old_mode": 33261,
      "old_path": "t/t5537-fetch-shallow.sh",
      "new_id": "16bfaba0f01e190abd6bd295715e7ec85d0519e4",
      "new_mode": 33261,
      "new_path": "t/t5537-fetch-shallow.sh"
    }
  ]
}
