)]}'
{
  "commit": "6a9975eb756c024ad229faeba753acc11b9d69ee",
  "tree": "1d7ab6dad754c1bf0fd4d02ad185225de1723d8e",
  "parents": [
    "821f774a4005ff1ee35f36b56420c592054b1a37"
  ],
  "author": {
    "name": "Fabian Meumertzheim",
    "email": "fabian@meumertzhe.im",
    "time": "Mon Sep 14 11:03:17 2026 -0700"
  },
  "committer": {
    "name": "Copybara-Service",
    "email": "copybara-worker@google.com",
    "time": "Mon Sep 14 11:04:57 2026 -0700"
  },
  "message": "Don\u0027t mistake a refetched repo for an externally modified one (#31108)\n\n### Description\n\nAfter `bazel fetch --force` (or any other command that refetches a repo without loading its packages), the next `bazel build` warned that a file of the repo \"has been modified externally\" and fetched the repo a second time.\n\nThe check for external modifications of repo files scanned all `FileStateValue` nodes in the graph via `MemoizingEvaluator#getValues()`, which also returns the last values of nodes that are already dirty. Refetching a repo re-evaluates its `RepositoryDirectoryValue`, which is not comparable and thus dirties the file state nodes of all files in the repo. A build re-evaluates these nodes when it loads the affected packages, but `fetch` doesn\u0027t request them and, unlike `BuildTool`, also doesn\u0027t delete dirty nodes at the end of the command. The stale nodes then survived until the next build, where the `ExternalDirtinessChecker` compared their old contents proxies with the rewritten files, reported an external modification and deleted the marker file to force another fetch.\n\nOnly scan nodes that are done: dirty nodes are re-evaluated when they are next requested anyway, so their last values can\u0027t be used to detect changes that Skyframe doesn\u0027t already know about.\n\n### Motivation\n\nEvery `bazel fetch --force` was followed by a second fetch of the same repos in the next build, together with a misleading warning about external modifications.\n\n### Build API Changes\n\nNo\n\n### Release Notes\n\nRELNOTES: `bazel fetch --force` no longer causes the fetched repos to be fetched again by the next build with a spurious warning about external modifications.\n\nCloses #31108\n\nCOPYBARA_INTEGRATE_REVIEW\u003dhttps://github.com/bazelbuild/bazel/pull/31108 from fmeum:fix-stale-external-repo-file-check 739a90bd6f1b0d3d1d9f2ad88078fca2762fe2bf\nPiperOrigin-RevId: 981245657\nChange-Id: I98bc3c1162e55361ca435823c749f25759a0469f\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "66c9544d92b2e6b72d4dacad5fe4f86f897b1dcc",
      "old_mode": 33188,
      "old_path": "src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java",
      "new_id": "63faf819610eabd748d737f6d1be3d650f0aae23",
      "new_mode": 33188,
      "new_path": "src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java"
    },
    {
      "type": "modify",
      "old_id": "bd37ec60a2ec31a9fa1ae902b6d32408a09d484b",
      "old_mode": 33188,
      "old_path": "src/test/py/bazel/bzlmod/bazel_fetch_test.py",
      "new_id": "37ddde6679d6ae979ff9248872a7e3d7145c3711",
      "new_mode": 33188,
      "new_path": "src/test/py/bazel/bzlmod/bazel_fetch_test.py"
    }
  ]
}
