@@ -159,6 +159,14 @@ impl<'cfg> RegistryData for RemoteRegistry<'cfg> {
159
159
self . config . assert_package_cache_locked ( path)
160
160
}
161
161
162
+ // `index_version` Is a string representing the version of the file used to construct the cached copy.
163
+ // Older versions of Cargo used the single value of the hash of the HEAD commit as a `index_version`.
164
+ // This is technically correct but a little too conservative. If a new commit is fetched all cached
165
+ // files need to be regenerated even if a particular file was not changed.
166
+ // Cargo now reads the `index_version` in two parts the cache file is considered valid if `index_version`
167
+ // ends with the hash of the HEAD commit OR if it starts with the hash of the file's contents.
168
+ // In the future cargo can write cached files with `index_version` = `git_file_hash + ":" + `git_commit_hash`,
169
+ // but for now it still uses `git_commit_hash` to be compatible with older Cargoes.
162
170
fn load (
163
171
& mut self ,
164
172
_root : & Path ,
@@ -169,8 +177,8 @@ impl<'cfg> RegistryData for RemoteRegistry<'cfg> {
169
177
return Poll :: Pending ;
170
178
}
171
179
// Check if the cache is valid.
172
- let current_version = self . current_version ( ) ;
173
- if let ( Some ( c) , Some ( i) ) = ( current_version , index_version) {
180
+ let git_commit_hash = self . current_version ( ) ;
181
+ if let ( Some ( c) , Some ( i) ) = ( git_commit_hash , index_version) {
174
182
if i. ends_with ( c. as_str ( ) ) {
175
183
return Poll :: Ready ( Ok ( LoadResponse :: CacheValid ) ) ;
176
184
}
@@ -181,15 +189,17 @@ impl<'cfg> RegistryData for RemoteRegistry<'cfg> {
181
189
fn load_helper (
182
190
registry : & RemoteRegistry < ' _ > ,
183
191
path : & Path ,
184
- current_version : Option < & str > ,
192
+ index_version : Option < & str > ,
193
+ git_commit_hash : Option < & str > ,
185
194
) -> CargoResult < LoadResponse > {
186
195
let repo = registry. repo ( ) ?;
187
196
let tree = registry. tree ( ) ?;
188
197
let entry = tree. get_path ( path) ;
189
198
let entry = entry?;
190
- let file_version = entry. id ( ) . to_string ( ) ;
191
- if let Some ( c) = current_version {
192
- if c. starts_with ( & file_version) {
199
+ let git_file_hash = entry. id ( ) . to_string ( ) ;
200
+
201
+ if let Some ( i) = index_version {
202
+ if i. starts_with ( git_file_hash. as_str ( ) ) {
193
203
return Ok ( LoadResponse :: CacheValid ) ;
194
204
}
195
205
}
@@ -202,13 +212,13 @@ impl<'cfg> RegistryData for RemoteRegistry<'cfg> {
202
212
203
213
Ok ( LoadResponse :: Data {
204
214
raw_data : blob. content ( ) . to_vec ( ) ,
205
- index_version : current_version . map ( String :: from) ,
206
- // TODO: When the reading code has been stable for long enough (Say 7 /2022)
207
- // change to `file_version + ":" + current_version `
215
+ index_version : git_commit_hash . map ( String :: from) ,
216
+ // TODO: When the reading code has been stable for long enough (Say 8 /2022)
217
+ // change to `git_file_hash + ":" + git_commit_hash `
208
218
} )
209
219
}
210
220
211
- match load_helper ( & self , path, current_version . as_deref ( ) ) {
221
+ match load_helper ( & self , path, index_version , git_commit_hash . as_deref ( ) ) {
212
222
Ok ( result) => Poll :: Ready ( Ok ( result) ) ,
213
223
Err ( _) if !self . updated => {
214
224
// If git returns an error and we haven't updated the repo, return
0 commit comments