available = string_list_lookup(available_paths, item->string);
if (available)
- available->util = (void *)item->string;
+ available->util = item->util;
return !available;
}
-int finish_delayed_checkout(struct checkout *state, int *nr_checkouts,
- int show_progress)
+int finish_delayed_checkout(struct checkout *state, int show_progress)
{
int errs = 0;
unsigned processed_paths = 0;
strlen(path->string), 0);
if (ce) {
display_progress(progress, ++processed_paths);
- errs |= checkout_entry(ce, state, NULL, nr_checkouts);
+ errs |= checkout_entry(ce, state, NULL, path->util);
filtered_bytes += ce->ce_stat_data.sd_size;
display_throughput(progress, filtered_bytes);
} else
/* Note: ca is used (and required) iff the entry refers to a regular file. */
static int write_entry(struct cache_entry *ce, char *path, struct conv_attrs *ca,
- const struct checkout *state, int to_tempfile)
+ const struct checkout *state, int to_tempfile,
+ int *nr_checkouts)
{
unsigned int ce_mode_s_ifmt = ce->ce_mode & S_IFMT;
struct delayed_checkout *dco = state->delayed_checkout;
struct stat st;
const struct submodule *sub;
struct checkout_metadata meta;
+ static int scratch_nr_checkouts;
clone_checkout_metadata(&meta, &state->meta, &ce->oid);
ret = async_convert_to_working_tree_ca(ca, ce->name,
new_blob, size,
&buf, &meta, dco);
- if (ret && string_list_has_string(&dco->paths, ce->name)) {
- free(new_blob);
- goto delayed;
+ if (ret) {
+ struct string_list_item *item =
+ string_list_lookup(&dco->paths, ce->name);
+ if (item) {
+ item->util = nr_checkouts ? nr_checkouts
+ : &scratch_nr_checkouts;
+ free(new_blob);
+ goto delayed;
+ }
}
} else {
ret = convert_to_working_tree_ca(ca, ce->name, new_blob,
ce->name);
update_ce_after_write(state, ce , &st);
}
+ if (nr_checkouts)
+ (*nr_checkouts)++;
delayed:
return 0;
}
convert_attrs(state->istate, &ca_buf, ce->name);
ca = &ca_buf;
}
- return write_entry(ce, topath, ca, state, 1);
+ return write_entry(ce, topath, ca, state, 1, nr_checkouts);
}
strbuf_reset(&path);
create_directories(path.buf, path.len, state);
- if (nr_checkouts)
- (*nr_checkouts)++;
-
if (S_ISREG(ce->ce_mode) && !ca) {
convert_attrs(state->istate, &ca_buf, ce->name);
ca = &ca_buf;
}
- if (!enqueue_checkout(ce, ca))
+ if (!enqueue_checkout(ce, ca, nr_checkouts))
return 0;
- return write_entry(ce, path.buf, ca, state, 0);
+ return write_entry(ce, path.buf, ca, state, 0, nr_checkouts);
}
void unlink_entry(const struct cache_entry *ce)
}
}
-int enqueue_checkout(struct cache_entry *ce, struct conv_attrs *ca)
+int enqueue_checkout(struct cache_entry *ce, struct conv_attrs *ca,
+ int *checkout_counter)
{
struct parallel_checkout_item *pc_item;
memcpy(&pc_item->ca, ca, sizeof(pc_item->ca));
pc_item->status = PC_ITEM_PENDING;
pc_item->id = parallel_checkout.nr;
+ pc_item->checkout_counter = checkout_counter;
parallel_checkout.nr++;
return 0;
switch(pc_item->status) {
case PC_ITEM_WRITTEN:
- /* Already handled */
+ if (pc_item->checkout_counter)
+ (*pc_item->checkout_counter)++;
break;
case PC_ITEM_COLLIDED:
/*
* add any extra overhead.
*/
ret |= checkout_entry_ca(pc_item->ce, &pc_item->ca,
- state, NULL, NULL);
+ state, NULL,
+ pc_item->checkout_counter);
advance_progress_meter();
break;
case PC_ITEM_PENDING: