-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
moduleFileHash in MODULE.bazel.lock causes frequent Git merge conflicts #20369
Comments
This does sound like a very probable scenario, though I'm drawing a blank on how it should be resolved. We need the module file hash in the lockfile to know whether the locked stuff is up-to-date. Maybe if we had segmented MODULE.bazel files (#17880) and recorded the hash of each segment individually? Do you reckon that's enough? |
Options I see:
In fact, 3 is the only option I can think of that realizes "trust on first use" semantics for module files: With the current format, every merge conflict or change to the module file followed by a server restart will fetch module files again, relying on our promise of their immutability to ensure nobody has tampered with them. |
I like 3 best. We rarely run into merge conflicts in go.sum in Uber's Go monorepo because there is no check sum for the whole file and because it is sorted |
An example of the format I envision, borrowing heavily from {
"lockfileVersion": 5,
"moduleHashes": {
"rules_bar@2.3.4/MODULE.bazel": "sha256-...",
"rules_bar@2.3.4/source.json": "sha256-...",
"rules_foo@1.2.3/MODULE.bazel": "sha256-...",
"rules_foo@1.2.3/source.json": "sha256-...",
"rules_foo@1.2.4/MODULE.bazel": "sha256-...",
"rules_foo@1.2.4/source.json": "sha256-..."
},
"extensionResults": {
"@@rules_foo~1.2.3//extensions:my_ext.bzl%my_ext": {
"sha256-ABC..": {
"fileDeps": [
"@@//:foo.lock"
],
"generatedRepoSpecs": {
...
}
},
"sha256-CDE..": {
"fileDeps": [],
"generatedRepoSpecs": {
...
}
}
}
}
} The hashes in the keys of the inner
This format has a few new properties:
I haven't fully thought this through yet and may have missed crucial cons. |
When we use the latest `bazel` release in the `rules_python` module, then the lock file gets created, but I am not sure if we should commit it in. Since the lock file is very useful for local development as it speeds up dependency refetching, this PR disables it as advised in the issue below. Whilst at it, the `bzlmod` example also removes it for smaller diffs when we develop extensions. See bazelbuild/bazel#20369
Retaining `Postable`s across the graph increases the memory usage of every dependent Skyframe node. `ModuleExtensionResolutionEvent` is replaced with a lookup of the "done" Skyframe nodes for extension evaluation in `BazelLockFileModule#afterCommand`. `RootModuleFileFixupEvent` is replaced with direct storage in `SingleExtensionEvalValue`. The validation of repos imported from an extension is moved into a separate `SkyFunction`. This simplifies `bazel mod tidy`, which no longer needs to swallow certain exceptions, and allows cache hits when only the (invalid) imports of an extension are modified even without the lockfile. The `BazelModuleResolutionEvent` is kept for now, but will become obsolete with the new lockfile format. Work towards #20369 Closes #22058. PiperOrigin-RevId: 628213907 Change-Id: I8ba19f5151a8183be5051c8d9280f93476db2272
This effectively reverts most of 2a2a474: Module files of yanked versions are evaluated just like those of any other versions and "yankedness" is only checked for the final dep graph after selection. This greatly simplifies incremental fetching of (inherently mutable) yanked version information with the new lockfile format. Work towards #20369 RELNOTES: `print` statements in module files are now only executed for the root module and modules subject to non-registry overrides (e.g. `local_path_override`). Closes #22083. PiperOrigin-RevId: 627953972 Change-Id: Ie0aba02d187e000450a89ad2cd281c173582880a Commit 45982b4 Co-authored-by: Fabian Meumertzheim <fabian@meumertzhe.im>
Retaining `Postable`s across the graph increases the memory usage of every dependent Skyframe node. `ModuleExtensionResolutionEvent` is replaced with a lookup of the "done" Skyframe nodes for extension evaluation in `BazelLockFileModule#afterCommand`. `RootModuleFileFixupEvent` is replaced with direct storage in `SingleExtensionEvalValue`. The validation of repos imported from an extension is moved into a separate `SkyFunction`. This simplifies `bazel mod tidy`, which no longer needs to swallow certain exceptions, and allows cache hits when only the (invalid) imports of an extension are modified even without the lockfile. The `BazelModuleResolutionEvent` is kept for now, but will become obsolete with the new lockfile format. Work towards #20369 Closes #22058. PiperOrigin-RevId: 628213907 Change-Id: I8ba19f5151a8183be5051c8d9280f93476db2272 --------- Co-authored-by: Fabian Meumertzheim <fabian@meumertzhe.im>
`MODULE.bazel`, `bazel_registry.json` and `source.json` files obtained from remote registries are stored in the repository cache and their hashes are collected in the lockfile. This speeds up incremental module resolutions, such as after adding a new `bazel_dep`. Yanked versions are not stored in the lockfile. Their handling will be part of a follow-up PR. Implements part of https://docs.google.com/document/d/1TjA7-M5njkI1F38IC0pm305S9EOmxcUwaCIvaSmansg/edit Work towards #20369 Closes #21901. PiperOrigin-RevId: 631195852 Change-Id: I35c30af7f9c3626bdbcb04c85b8c2502eeaafd3e
`MODULE.bazel`, `bazel_registry.json` and `source.json` files obtained from remote registries are stored in the repository cache and their hashes are collected in the lockfile. This speeds up incremental module resolutions, such as after adding a new `bazel_dep`. Yanked versions are not stored in the lockfile. Their handling will be part of a follow-up PR. Implements part of https://docs.google.com/document/d/1TjA7-M5njkI1F38IC0pm305S9EOmxcUwaCIvaSmansg/edit Work towards #20369 Closes #21901. PiperOrigin-RevId: 631195852 Change-Id: I35c30af7f9c3626bdbcb04c85b8c2502eeaafd3e Co-authored-by: Fabian Meumertzheim <fabian@meumertzhe.im>
This is in preparation for tracking the hashes of remote (non-`file:` URL) files in the lockfile. If the tests use local registries, they wouldn't be representative of the default situation. Work towards bazelbuild#20369 Closes bazelbuild#21906. PiperOrigin-RevId: 622290283 Change-Id: Ibe825d2bede84c1b0672dbb699aaf3ee5168a813
Ensures that yanked version information is only downloaded once per module name, which reduces the number of files fetched during module resolution. On my machine, this reduces `bazel mod deps` runtime on Bazel itself by ~15%. This also prepares for storing yanked version information in the lockfile. Work towards bazelbuild#20369 Closes bazelbuild#21909. PiperOrigin-RevId: 625617556 Change-Id: Ie4184def3b868470f93d584bbbbd7f704e1e9a82
This gets rid of an ad-hoc cache maintained in `RegistryFactoryImpl` and prepares for making registries aware of hashes stored in the lockfile. Work towards bazelbuild#20369 Closes bazelbuild#22040. PiperOrigin-RevId: 626307340 Change-Id: I34b428553f7169c72ed7dddd2fe3ea5e6dca2a97
This effectively reverts most of 2a2a474: Module files of yanked versions are evaluated just like those of any other versions and "yankedness" is only checked for the final dep graph after selection. This greatly simplifies incremental fetching of (inherently mutable) yanked version information with the new lockfile format. Work towards bazelbuild#20369 RELNOTES: `print` statements in module files are now only executed for the root module and modules subject to non-registry overrides (e.g. `local_path_override`). Closes bazelbuild#22083. PiperOrigin-RevId: 627953972 Change-Id: Ie0aba02d187e000450a89ad2cd281c173582880a
Retaining `Postable`s across the graph increases the memory usage of every dependent Skyframe node. `ModuleExtensionResolutionEvent` is replaced with a lookup of the "done" Skyframe nodes for extension evaluation in `BazelLockFileModule#afterCommand`. `RootModuleFileFixupEvent` is replaced with direct storage in `SingleExtensionEvalValue`. The validation of repos imported from an extension is moved into a separate `SkyFunction`. This simplifies `bazel mod tidy`, which no longer needs to swallow certain exceptions, and allows cache hits when only the (invalid) imports of an extension are modified even without the lockfile. The `BazelModuleResolutionEvent` is kept for now, but will become obsolete with the new lockfile format. Work towards bazelbuild#20369 Closes bazelbuild#22058. PiperOrigin-RevId: 628213907 Change-Id: I8ba19f5151a8183be5051c8d9280f93476db2272
`MODULE.bazel`, `bazel_registry.json` and `source.json` files obtained from remote registries are stored in the repository cache and their hashes are collected in the lockfile. This speeds up incremental module resolutions, such as after adding a new `bazel_dep`. Yanked versions are not stored in the lockfile. Their handling will be part of a follow-up PR. Implements part of https://docs.google.com/document/d/1TjA7-M5njkI1F38IC0pm305S9EOmxcUwaCIvaSmansg/edit Work towards bazelbuild#20369 Closes bazelbuild#21901. PiperOrigin-RevId: 631195852 Change-Id: I35c30af7f9c3626bdbcb04c85b8c2502eeaafd3e
The old lockfile fields and all code related to it as well as the workarounds for local path inclusions are removed. The distribution archive lockfile needs to be checked in temporarily as the main `MODULE.bazel.lock` file does not contain the hashes for the registry files. Fixes #19621 Fixes #20369 RELNOTES: The format for MODULE.bazel.lock is now less likely to result in merge conflicts and is updated incrementally, with only new files downloaded from registries and existing ones taken from the repository cache (if configured). Closes #22154. PiperOrigin-RevId: 633233519 Change-Id: Ie2c3042e4141a36e472b2c25cbd67be4aad096a1
A fix for this issue has been included in Bazel 7.2.0 RC1. Please test out the release candidate and report any issues as soon as possible. |
The lockfile in it's current form is prone to generate complex merge conflicts. See bazelbuild/bazel#20369 Also, the bazel central registry never removes or alters existing versions. The lockfile can probably be added to Git in Bazel >= 7.2
The lockfile in it's current form is prone to generate complex merge conflicts. See bazelbuild/bazel#20369 Also, the bazel central registry never removes or alters existing versions. The lockfile can probably be added to Git in Bazel >= 7.2
The lockfile in it's current form is prone to generate complex merge conflicts. See bazelbuild/bazel#20369 Also, the bazel central registry never removes or alters existing versions. The lockfile can probably be added to Git in Bazel >= 7.2
The lockfile in it's current form is prone to generate complex merge conflicts. See bazelbuild/bazel#20369 Also, the bazel central registry never removes or alters existing versions. The lockfile can probably be added to Git in Bazel >= 7.2
See bazelbuild/bazel#20369 While working on refactoring, I kept hitting rebase conflicts due to issues with the MODULE lock. I guess it's because the Bazel version in e2e tests is much lower than the current one with the fix (7.2) but still, I don't think it adds much to have the lock in e2e testing.
See bazelbuild/bazel#20369 While working on refactoring, I kept hitting rebase conflicts due to issues with the MODULE lock. I guess it's because the Bazel version in e2e tests is much lower than the current one with the fix (7.2) but still, I don't think it adds much to have the lock in e2e testing.
…87) * fix: MODULE.bazel.lock conflicts See bazelbuild/bazel#20369 While working on refactoring, I kept hitting rebase conflicts due to issues with the MODULE lock. I guess it's because the Bazel version in e2e tests is much lower than the current one with the fix (7.2) but still, I don't think it adds much to have the lock in e2e testing. * fix: repo name in copy.sh script PR #73 added the `_resolve` and this breaks the buildozer fix / autofix * fix: remove dead locks It seemed like 75afff9 in #47 added the new locks but as new files, that is, the old ones were left behind.
Description of the bug:
The value of
moduleFileHash
changes every time any dependency in the whole repo is changed. This is not scalable in a monorepo with thousands of developers committing concurrently. Imagine the scenario:From base revision with
"moduleFileHash": "x"
Developer 1 upgrades library a, which produced this as part of the diff:
Meanwhile, developer 2 upgrades another library b, which is totally unrelated to a, and produce this:
If developer 1 landed her diff first, developer 2 won't be able to land hers due to Git merge conflict. So developer 2 will have to rebase onto the main branch and update her diff to be
While she went for a coffee break, developer 3 landed yet another diff that upgrade another unrelated library, causing moduleFileHash to change:
Now developer 2 has to rebase again... In the end, developer 2 has to yell to all developers in this big corporation: STOP UPGRADING ANY DEPENDENCIES BEFORE I LAND MY CHANGE
Which category does this issue belong to?
External Dependency
The text was updated successfully, but these errors were encountered: