entry: move conv_attrs lookup up to checkout_entry()
In a following patch, checkout_entry() will use conv_attrs to decide whether an entry should be enqueued for parallel checkout or not. But the attributes lookup only happens lower in this call stack. To avoid the unnecessary work of loading the attributes twice, let's move it up to checkout_entry(), and pass the loaded struct down to write_entry(). Signed-off-by: Matheus Tavares <matheus.bernardino@usp.br> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Matheus Tavares committed
Mar 23, 2021 at 11:19 UTC
30419e7e1d53232bb83dcace200d1295b326b22b
1 file changed
+27
-11
entry.c
+27
-11
@@ -263,8 +263,9 @@ void update_ce_after_write(const struct checkout *state, struct cache_entry *ce,
263
}
264
}
265
266
-static int write_entry(struct cache_entry *ce,
267
- char *path, const struct checkout *state, int to_tempfile)
266
+/* Note: ca is used (and required) iff the entry refers to a regular file. */
267
+static int write_entry(struct cache_entry *ce, char *path, struct conv_attrs *ca,
268
+ const struct checkout *state, int to_tempfile)
269
{
270
unsigned int ce_mode_s_ifmt = ce->ce_mode & S_IFMT;
271
struct delayed_checkout *dco = state->delayed_checkout;
@@ -281,8 +282,7 @@ static int write_entry(struct cache_entry *ce,
282
clone_checkout_metadata(&meta, &state->meta, &ce->oid);
283
284
if (ce_mode_s_ifmt == S_IFREG) {
284
- struct stream_filter *filter = get_stream_filter(state->istate, ce->name,
285
- &ce->oid);
285
+ struct stream_filter *filter = get_stream_filter_ca(ca, &ce->oid);
286
if (filter &&
287
!streaming_write_entry(ce, path, filter,
288
state, to_tempfile,
@@ -329,14 +329,17 @@ static int write_entry(struct cache_entry *ce,
329
* Convert from git internal format to working tree format
330
*/
331
if (dco && dco->state != CE_NO_DELAY) {
332
- ret = async_convert_to_working_tree(state->istate, ce->name, new_blob,
333
- size, &buf, &meta, dco);
332
+ ret = async_convert_to_working_tree_ca(ca, ce->name,
333
+ new_blob, size,
334
+ &buf, &meta, dco);
335
if (ret && string_list_has_string(&dco->paths, ce->name)) {
336
free(new_blob);
337
goto delayed;
338
}
338
- } else
339
- ret = convert_to_working_tree(state->istate, ce->name, new_blob, size, &buf, &meta);
339
+ } else {
340
+ ret = convert_to_working_tree_ca(ca, ce->name, new_blob,
341
+ size, &buf, &meta);
342
+ }
343
344
if (ret) {
345
free(new_blob);
@@ -442,6 +445,7 @@ int checkout_entry(struct cache_entry *ce, const struct checkout *state,
445
{
446
static struct strbuf path = STRBUF_INIT;
447
struct stat st;
448
+ struct conv_attrs ca_buf, *ca = NULL;
449
450
if (ce->ce_flags & CE_WT_REMOVE) {
451
if (topath)
@@ -454,8 +458,13 @@ int checkout_entry(struct cache_entry *ce, const struct checkout *state,
458
return 0;
459
}
460
457
- if (topath)
458
- return write_entry(ce, topath, state, 1);
461
+ if (topath) {
462
+ if (S_ISREG(ce->ce_mode)) {
463
+ convert_attrs(state->istate, &ca_buf, ce->name);
464
+ ca = &ca_buf;
465
+ }
466
+ return write_entry(ce, topath, ca, state, 1);
467
+ }
468
469
strbuf_reset(&path);
470
strbuf_add(&path, state->base_dir, state->base_dir_len);
@@ -517,9 +526,16 @@ int checkout_entry(struct cache_entry *ce, const struct checkout *state,
526
return 0;
527
528
create_directories(path.buf, path.len, state);
529
+
530
if (nr_checkouts)
531
(*nr_checkouts)++;
522
- return write_entry(ce, path.buf, state, 0);
532
+
533
+ if (S_ISREG(ce->ce_mode)) {
534
+ convert_attrs(state->istate, &ca_buf, ce->name);
535
+ ca = &ca_buf;
536
+ }
537
+
538
+ return write_entry(ce, path.buf, ca, state, 0);
539
}
540
541
void unlink_entry(const struct cache_entry *ce)