Skip to content

Commit bf6d819

Browse files
szedergitster
authored andcommitted
entry: show finer-grained counter in "Filtering content" progress line
The "Filtering content" progress in entry.c:finish_delayed_checkout() is unusual because of how it calculates the progress count and because it shows the progress of a nested loop. It works basically like this: start_delayed_progress(p, nr_of_paths_to_filter) for_each_filter { display_progress(p, nr_of_paths_to_filter - nr_of_paths_still_left_to_filter) for_each_path_handled_by_the_current_filter { checkout_entry() } } stop_progress(p) There are two issues with this approach: - The work done by the last filter (or the only filter if there is only one) is never counted, so if the last filter still has some paths to process, then the counter shown in the "done" progress line will not match the expected total. The partially-RFC series to add a GIT_TEST_CHECK_PROGRESS=1 mode[1] helps spot this issue. Under it the 'missing file in delayed checkout' and 'invalid file in delayed checkout' tests in 't0021-conversion.sh' fail, because both use only one filter. (The test 'delayed checkout in process filter' uses two filters but the first one does all the work, so that test already happens to succeed even with GIT_TEST_CHECK_PROGRESS=1.) - The progress counter is updated only once per filter, not once per processed path, so if a filter has a lot of paths to process, then the counter might stay unchanged for a long while and then make a big jump (though the user still gets a sense of progress, because we call display_throughput() after each processed path to show the amount of processed data). Move the display_progress() call to the inner loop, right next to that checkout_entry() call that does the hard work for each path, and use a dedicated counter variable that is incremented upon processing each path. After this change the 'invalid file in delayed checkout' in 't0021-conversion.sh' would succeed with the GIT_TEST_CHECK_PROGRESS=1 assertion discussed above, but the 'missing file in delayed checkout' test would still fail. It'll fail because its purposefully buggy filter doesn't process any paths, so we won't execute that inner loop at all, see [2] for how to spot that issue without GIT_TEST_CHECK_PROGRESS=1. It's not straightforward to fix it with the current progress.c library (see [3] for an attempt), so let's leave it for now. Let's also initialize the *progress to "NULL" while we're at it. Since 7a132c6 (checkout: make delayed checkout respect --quiet and --no-progress, 2021-08-26) we have had progress conditional on "show_progress", usually we use the idiom of a "NULL" initialization of the "*progress", rather than the more verbose ternary added in 7a132c6. 1. https://lore.kernel.org/git/[email protected]/ 2. http://lore.kernel.org/git/[email protected] 3. https://lore.kernel.org/git/[email protected]/ Signed-off-by: SZEDER Gábor <[email protected]> Signed-off-by: Ævar Arnfjörð Bjarmason <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 4011224 commit bf6d819

File tree

1 file changed

+5
-7
lines changed

1 file changed

+5
-7
lines changed

entry.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -163,24 +163,21 @@ int finish_delayed_checkout(struct checkout *state, int *nr_checkouts,
163163
int show_progress)
164164
{
165165
int errs = 0;
166-
unsigned delayed_object_count;
166+
unsigned processed_paths = 0;
167167
off_t filtered_bytes = 0;
168168
struct string_list_item *filter, *path;
169-
struct progress *progress;
169+
struct progress *progress = NULL;
170170
struct delayed_checkout *dco = state->delayed_checkout;
171171

172172
if (!state->delayed_checkout)
173173
return errs;
174174

175175
dco->state = CE_RETRY;
176-
delayed_object_count = dco->paths.nr;
177-
progress = show_progress
178-
? start_delayed_progress(_("Filtering content"), delayed_object_count)
179-
: NULL;
176+
if (show_progress)
177+
progress = start_delayed_progress(_("Filtering content"), dco->paths.nr);
180178
while (dco->filters.nr > 0) {
181179
for_each_string_list_item(filter, &dco->filters) {
182180
struct string_list available_paths = STRING_LIST_INIT_NODUP;
183-
display_progress(progress, delayed_object_count - dco->paths.nr);
184181

185182
if (!async_query_available_blobs(filter->string, &available_paths)) {
186183
/* Filter reported an error */
@@ -227,6 +224,7 @@ int finish_delayed_checkout(struct checkout *state, int *nr_checkouts,
227224
ce = index_file_exists(state->istate, path->string,
228225
strlen(path->string), 0);
229226
if (ce) {
227+
display_progress(progress, ++processed_paths);
230228
errs |= checkout_entry(ce, state, NULL, nr_checkouts);
231229
filtered_bytes += ce->ce_stat_data.sd_size;
232230
display_throughput(progress, filtered_bytes);

0 commit comments

Comments
 (0)