[6.4.0] Fix unconditional Skyframe invalidation with --lockfile_mode=… (#19848)
…update
Ensure that `BazelLockFileModule` only updates `MODULE.bazel.lock` if
the content of the file needs to change. Every such update changes the
file's metadata, which results in Skyframe invalidation of, in
particular, all configurations. This broke `bazel config`, which uses
`MemoizingEvaluator#getDoneValues()` to directly observe Skyframe state.
Compared to the original commit
https://github.com/bazelbuild/bazel/commit/78db9ae9a545a9586dbb02d7831f5302594e01cb,
this cherry-pick does not include the change to `bazel config` as it may
not be backwards compatible (changes the exit code in certain
situations).
Fixes #19823
Closes #19842.
PiperOrigin-RevId: 574133346
Change-Id: I5886c91fc6b7b938a7dee59ea75aa7b8afb5b161
Fixes #19843
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BazelLockFileModule.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BazelLockFileModule.java
index a664ae3..4036eb3 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BazelLockFileModule.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BazelLockFileModule.java
@@ -106,8 +106,13 @@
combineModuleExtensions(lockfile.getModuleExtensions(), oldExtensionUsages))
.build();
- // Write the new value to the file
- updateLockfile(lockfilePath, lockfile);
+ // Write the new value to the file, but only if needed. This is not just a performance
+ // optimization: whenever the lockfile is updated, most Skyframe nodes will be marked as dirty
+ // on the next build, which breaks commands such as `bazel config` that rely on
+ // com.google.devtools.build.skyframe.MemoizingEvaluator#getDoneValues.
+ if (!lockfile.equals(oldLockfile)) {
+ updateLockfile(lockfilePath, lockfile);
+ }
this.moduleResolutionEvent = null;
this.extensionResolutionEventsMap.clear();
}