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++) {