Commit 844a185
committed
unpack-trees: skip lstats for deleted VFS entries in checkout (#865)
When core_virtualfilesystem is set and a branch switch deletes entries
(present in old tree, absent in new tree), deleted_entry() calls
verify_absent_if_directory() with 'ce' pointing to a tree entry from
traverse_trees(). This tree entry lacks CE_NEW_SKIP_WORKTREE because
that flag is only set on src_index entries by mark_new_skip_worktree().
The missing flag causes verify_absent_if_directory()'s fast-path to
fail, falling through to verify_absent_1() which lstats every such path.
In a VFS repo each lstat may trigger callbacks, creating placeholders.
On a large repo switching between LTS releases this produces tens of
thousands of placeholders that the VFS must then clean up when they are
deleted as part of the checkout.
Fix this by propagating CE_NEW_SKIP_WORKTREE from the index entry (old)
to the tree entry (ce) when core_virtualfilesystem is set. This allows
the existing fast-path to work, eliminating the unnecessary lstats
entirely.
Measured on a 2.8M file VFS repo (0% hydrated):
Before: ~135s checkout, ~23k folder placeholders created
After: ~25s checkout, 0 folder placeholders created
* [x] This change only applies to the virtualization hook and VFS for
Git.2 files changed
Lines changed: 63 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
368 | 368 | | |
369 | 369 | | |
370 | 370 | | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
371 | 422 | | |
372 | 423 | | |
373 | 424 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2721 | 2721 | | |
2722 | 2722 | | |
2723 | 2723 | | |
| 2724 | + | |
| 2725 | + | |
| 2726 | + | |
| 2727 | + | |
| 2728 | + | |
| 2729 | + | |
| 2730 | + | |
| 2731 | + | |
| 2732 | + | |
| 2733 | + | |
| 2734 | + | |
| 2735 | + | |
2724 | 2736 | | |
2725 | 2737 | | |
2726 | 2738 | | |
| |||
0 commit comments