Commit a7d32d6
committed
stash: avoid recomputing tree when committing worktree
When creating a new stash, we need to create there separate
commits storing differences stored in the index, untracked
changes as well as differences in the working directory. The
first two will only be done conditionally if the equivalent
options "git stash --keep-index --include-untracked" are being
passed to `git_stash_save`, but even when only creating a stash
of worktree changes we're much slower than git.git. Using our new
stash example:
$ time git stash
Saved working directory and index state WIP on (no branch): 2f7d9d47575e Linux 5.1.7
real 0m0.528s
user 0m0.309s
sys 0m0.381s
$ time lg2 stash
real 0m27.165s
user 0m13.645s
sys 0m6.403s
As can be seen, libgit2 is more than 50x slower than git.git!
When creating the stash commit that includes all worktree
changes, we create a completely new index to prepare for the new
commit and populate it with the entries contained in the index'
tree. Here comes the catch: by populating the index with a tree's
contents, we do not have any stat caches in the index. This means
that we have to re-validate every single file from the worktree
and see whether it has changed.
The issue can be fixed by populating the new index with the
repo's existing index instead of with the tree. This retains all
stat cache information, and thus we really only need to check
files that have changed stat information. This is semantically
equivalent to what we previously did: previously, we used the
tree of the commit computed from the index. Now we're just using
the index directly.
And, in fact, the cache is doing wonders:
time lg2 stash
real 0m1.836s
user 0m1.166s
sys 0m0.663s
We're now performing 15x faster than before and are only 3x
slower than git.git now.1 parent 88731e3 commit a7d32d6
1 file changed
+9
-14
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
398 | 398 | | |
399 | 399 | | |
400 | 400 | | |
401 | | - | |
402 | | - | |
403 | | - | |
404 | | - | |
405 | | - | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
406 | 405 | | |
407 | 406 | | |
408 | 407 | | |
409 | 408 | | |
410 | 409 | | |
411 | | - | |
412 | | - | |
413 | | - | |
414 | | - | |
415 | | - | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
416 | 414 | | |
417 | 415 | | |
418 | 416 | | |
419 | 417 | | |
420 | | - | |
421 | | - | |
422 | | - | |
423 | 418 | | |
424 | 419 | | |
425 | 420 | | |
| |||
436 | 431 | | |
437 | 432 | | |
438 | 433 | | |
439 | | - | |
440 | 434 | | |
441 | 435 | | |
| 436 | + | |
442 | 437 | | |
443 | 438 | | |
444 | 439 | | |
| |||
0 commit comments