@@ -102,33 +102,43 @@ issue][cargo-issues].
102
102
103
103
[ cargo-issues ] : https://github.com/rust-lang/cargo/issues
104
104
105
- ### Why do binaries have ` Cargo.lock ` in version control, but not libraries?
105
+ ### Why have ` Cargo.lock ` in version control?
106
+
107
+ Whether you do is dependent on the needs of your package.
106
108
107
109
The purpose of a ` Cargo.lock ` lockfile is to describe the state of the world at
108
- the time of a successful build. Cargo uses the lockfile to provide
109
- deterministic builds on different times and different systems, by ensuring that
110
- the exact same dependencies and versions are used as when the ` Cargo.lock ` file
111
- was originally generated.
112
-
113
- This property is most desirable from applications and packages which are at the
114
- very end of the dependency chain (binaries). As a result, it is recommended that
115
- all binaries check in their ` Cargo.lock ` .
116
-
117
- For libraries the situation is somewhat different. A library is not only used by
118
- the library developers, but also any downstream consumers of the library. Users
119
- dependent on the library will not inspect the library’s ` Cargo.lock ` (even if it
120
- exists). This is precisely because a library should ** not** be deterministically
121
- recompiled for all users of the library.
122
-
123
- If a library ends up being used transitively by several dependencies, it’s
124
- likely that just a single copy of the library is desired (based on semver
125
- compatibility). If Cargo used all of the dependencies' ` Cargo.lock ` files,
126
- then multiple copies of the library could be used, and perhaps even a version
127
- conflict.
128
-
129
- In other words, libraries specify SemVer requirements for their dependencies but
130
- cannot see the full picture. Only end products like binaries have a full
131
- picture to decide what versions of dependencies should be used.
110
+ the time of a successful build.
111
+ Cargo uses the lockfile to provide deterministic builds at different times and
112
+ on different systems,
113
+ by ensuring that the exact same dependencies and versions are used as when the
114
+ ` Cargo.lock ` file was originally generated.
115
+
116
+ Deterministic builds help with
117
+ - Running ` git bisect ` to find the root cause of a bug
118
+ - Ensuring CI only fails due to new commits and not external factors
119
+ - Reducing confusion when contributors see different behavior as compared to
120
+ other contributors or CI
121
+
122
+ Having this snapshot of dependencies can also help when projects need to be
123
+ verified against consistent versions of dependencies, like when
124
+ - Verifying a minimum-supported Rust version that is less than the what latest
125
+ version of a dependency supports
126
+ - Verifying human readable output which won't have compatibility guarantees
127
+ (e.g. snapshot testing error messages to ensure they are "understandable", a
128
+ metric too fuzzy to automate)
129
+
130
+ However, this determinism can give a false sense of security because
131
+ ` Cargo.lock ` does not affect the consumers of your package, only ` Cargo.toml ` does that.
132
+ For example:
133
+ - [ ` cargo install ` ] will select the latest dependencies unless ` --locked ` is
134
+ passed in.
135
+ - New dependencies, like those added with [ ` cargo add ` ] , will be locked to the latest version
136
+
137
+ For strategies to verify newer dependencies,
138
+ see [ Verifying Latest Dependencies] ( guide/continuous-integration.md#verifying-latest-dependencies ) .
139
+
140
+ [ `cargo add` ] : commands/cargo-add.md
141
+ [ `cargo install` ] : commands/cargo-install.md
132
142
133
143
### Can libraries use ` * ` as a version for their dependencies?
134
144
0 commit comments