@matheusbsbs / matheus-bagliano / commits / 4dcd4def3c
Fork 0

unpack-trees: add progress to clear_ce_flags()

When a large repository has many sparse-checkout patterns, the process for updating the skip-worktree bits can take long enough that a user gets confused why nothing is happening. Update the clear_ce_flags() method to write progress. Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Derrick Stolee committed Nov 21, 2019 at 22:04 UTC 4dcd4def3ca46fc0e8cb28cbfc815a35dd2c3f1d
2 files changed +43 -15
cache.h
+2
@@ -304,6 +304,7 @@ static inline unsigned int canon_mode(unsigned int mode)
304
305 struct split_index;
306 struct untracked_cache;
307 +struct progress;
308
309 struct index_state {
310 struct cache_entry **cache;
@@ -326,6 +327,7 @@ struct index_state {
327 uint64_t fsmonitor_last_update;
328 struct ewah_bitmap *fsmonitor_dirty;
329 struct mem_pool *ce_mem_pool;
330 + struct progress *progress;
331 };
332
333 /* Name hashing */
unpack-trees.c
+41 -15
@@ -1269,7 +1269,8 @@ static int clear_ce_flags_1(struct index_state *istate,
1269 struct strbuf *prefix,
1270 int select_mask, int clear_mask,
1271 struct pattern_list *pl,
1272 - enum pattern_match_result default_match);
1272 + enum pattern_match_result default_match,
1273 + int progress_nr);
1274
1275 /* Whole directory matching */
1276 static int clear_ce_flags_dir(struct index_state *istate,
@@ -1278,7 +1279,8 @@ static int clear_ce_flags_dir(struct index_state *istate,
1279 char *basename,
1280 int select_mask, int clear_mask,
1281 struct pattern_list *pl,
1281 - enum pattern_match_result default_match)
1282 + enum pattern_match_result default_match,
1283 + int progress_nr)
1284 {
1285 struct cache_entry **cache_end;
1286 int dtype = DT_DIR;
@@ -1315,7 +1317,8 @@ static int clear_ce_flags_dir(struct index_state *istate,
1317 rc = clear_ce_flags_1(istate, cache, cache_end - cache,
1318 prefix,
1319 select_mask, clear_mask,
1318 - pl, ret);
1320 + pl, ret,
1321 + progress_nr);
1322 }
1323
1324 strbuf_setlen(prefix, prefix->len - 1);
@@ -1342,7 +1345,8 @@ static int clear_ce_flags_1(struct index_state *istate,
1345 struct strbuf *prefix,
1346 int select_mask, int clear_mask,
1347 struct pattern_list *pl,
1345 - enum pattern_match_result default_match)
1348 + enum pattern_match_result default_match,
1349 + int progress_nr)
1350 {
1351 struct cache_entry **cache_end = cache + nr;
1352
@@ -1356,8 +1360,11 @@ static int clear_ce_flags_1(struct index_state *istate,
1360 int len, dtype;
1361 enum pattern_match_result ret;
1362
1363 + display_progress(istate->progress, progress_nr);
1364 +
1365 if (select_mask && !(ce->ce_flags & select_mask)) {
1366 cache++;
1367 + progress_nr++;
1368 continue;
1369 }
1370
@@ -1378,20 +1385,26 @@ static int clear_ce_flags_1(struct index_state *istate,
1385 prefix,
1386 prefix->buf + prefix->len - len,
1387 select_mask, clear_mask,
1381 - pl, default_match);
1388 + pl, default_match,
1389 + progress_nr);
1390
1391 /* clear_c_f_dir eats a whole dir already? */
1392 if (processed) {
1393 cache += processed;
1394 + progress_nr += processed;
1395 strbuf_setlen(prefix, prefix->len - len);
1396 continue;
1397 }
1398
1399 strbuf_addch(prefix, '/');
1391 - cache += clear_ce_flags_1(istate, cache, cache_end - cache,
1392 - prefix,
1393 - select_mask, clear_mask, pl,
1394 - default_match);
1400 + processed = clear_ce_flags_1(istate, cache, cache_end - cache,
1401 + prefix,
1402 + select_mask, clear_mask, pl,
1403 + default_match, progress_nr);
1404 +
1405 + cache += processed;
1406 + progress_nr += processed;
1407 +
1408 strbuf_setlen(prefix, prefix->len - len - 1);
1409 continue;
1410 }
@@ -1406,19 +1419,27 @@ static int clear_ce_flags_1(struct index_state *istate,
1419 if (ret == MATCHED)
1420 ce->ce_flags &= ~clear_mask;
1421 cache++;
1422 + progress_nr++;
1423 }
1424 +
1425 + display_progress(istate->progress, progress_nr);
1426 return nr - (cache_end - cache);
1427 }
1428
1429 static int clear_ce_flags(struct index_state *istate,
1430 int select_mask, int clear_mask,
1415 - struct pattern_list *pl)
1431 + struct pattern_list *pl,
1432 + int show_progress)
1433 {
1434 static struct strbuf prefix = STRBUF_INIT;
1435 char label[100];
1436 int rval;
1437
1438 strbuf_reset(&prefix);
1439 + if (show_progress)
1440 + istate->progress = start_delayed_progress(
1441 + _("Updating index flags"),
1442 + istate->cache_nr);
1443
1444 xsnprintf(label, sizeof(label), "clear_ce_flags(0x%08lx,0x%08lx)",
1445 (unsigned long)select_mask, (unsigned long)clear_mask);
@@ -1428,9 +1449,10 @@ static int clear_ce_flags(struct index_state *istate,
1449 istate->cache_nr,
1450 &prefix,
1451 select_mask, clear_mask,
1431 - pl, 0);
1452 + pl, 0, 0);
1453 trace2_region_leave("unpack_trees", label, the_repository);
1454
1455 + stop_progress(&istate->progress);
1456 return rval;
1457 }
1458
@@ -1439,7 +1461,8 @@ static int clear_ce_flags(struct index_state *istate,
1461 */
1462 static void mark_new_skip_worktree(struct pattern_list *pl,
1463 struct index_state *istate,
1442 - int select_flag, int skip_wt_flag)
1464 + int select_flag, int skip_wt_flag,
1465 + int show_progress)
1466 {
1467 int i;
1468
@@ -1463,7 +1486,7 @@ static void mark_new_skip_worktree(struct pattern_list *pl,
1486 * 2. Widen worktree according to sparse-checkout file.
1487 * Matched entries will have skip_wt_flag cleared (i.e. "in")
1488 */
1466 - clear_ce_flags(istate, select_flag, skip_wt_flag, pl);
1489 + clear_ce_flags(istate, select_flag, skip_wt_flag, pl, show_progress);
1490 }
1491
1492 static int verify_absent(const struct cache_entry *,
@@ -1525,7 +1548,8 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
1548 * Sparse checkout loop #1: set NEW_SKIP_WORKTREE on existing entries
1549 */
1550 if (!o->skip_sparse_checkout)
1528 - mark_new_skip_worktree(o->pl, o->src_index, 0, CE_NEW_SKIP_WORKTREE);
1551 + mark_new_skip_worktree(o->pl, o->src_index, 0,
1552 + CE_NEW_SKIP_WORKTREE, o->verbose_update);
1553
1554 if (!dfc)
1555 dfc = xcalloc(1, cache_entry_size(0));
@@ -1590,7 +1614,9 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
1614 * If the will have NEW_SKIP_WORKTREE, also set CE_SKIP_WORKTREE
1615 * so apply_sparse_checkout() won't attempt to remove it from worktree
1616 */
1593 - mark_new_skip_worktree(o->pl, &o->result, CE_ADDED, CE_SKIP_WORKTREE | CE_NEW_SKIP_WORKTREE);
1617 + mark_new_skip_worktree(o->pl, &o->result,
1618 + CE_ADDED, CE_SKIP_WORKTREE | CE_NEW_SKIP_WORKTREE,
1619 + o->verbose_update);
1620
1621 ret = 0;
1622 for (i = 0; i < o->result.cache_nr; i++) {