mirror of
https://github.com/git/git.git
synced 2024-11-17 14:34:49 +01:00
ae4f07fbcc
When we use pack bitmaps rather than walking the object graph, we end up with the list of objects to include in the packfile, but we do not know the path at which any tree or blob objects would be found. In a recently packed repository, this is fine. A fetch would use the paths only as a heuristic in the delta compression phase, and a fully packed repository should not need to do much delta compression. As time passes, though, we may acquire more objects on top of our large bitmapped pack. If clients fetch frequently, then they never even look at the bitmapped history, and all works as usual. However, a client who has not fetched since the last bitmap repack will have "have" tips in the bitmapped history, but "want" newer objects. The bitmaps themselves degrade gracefully in this circumstance. We manually walk the more recent bits of history, and then use bitmaps when we hit them. But we would also like to perform delta compression between the newer objects and the bitmapped objects (both to delta against what we know the user already has, but also between "new" and "old" objects that the user is fetching). The lack of pathnames makes our delta heuristics much less effective. This patch adds an optional cache of the 32-bit name_hash values to the end of the bitmap file. If present, a reader can use it to match bitmapped and non-bitmapped names during delta compression. Here are perf results for p5310: Test origin/master HEAD^ HEAD ------------------------------------------------------------------------------------------------- 5310.2: repack to disk 36.81(37.82+1.43) 47.70(48.74+1.41) +29.6% 47.75(48.70+1.51) +29.7% 5310.3: simulated clone 30.78(29.70+2.14) 1.08(0.97+0.10) -96.5% 1.07(0.94+0.12) -96.5% 5310.4: simulated fetch 3.16(6.10+0.08) 3.54(10.65+0.06) +12.0% 1.70(3.07+0.06) -46.2% 5310.6: partial bitmap 36.76(43.19+1.81) 6.71(11.25+0.76) -81.7% 4.08(6.26+0.46) -88.9% You can see that the time spent on an incremental fetch goes down, as our delta heuristics are able to do their work. And we save time on the partial bitmap clone for the same reason. Signed-off-by: Vicent Marti <tanoku@gmail.com> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
139 lines
3.4 KiB
Bash
Executable file
139 lines
3.4 KiB
Bash
Executable file
#!/bin/sh
|
|
|
|
test_description='exercise basic bitmap functionality'
|
|
. ./test-lib.sh
|
|
|
|
test_expect_success 'setup repo with moderate-sized history' '
|
|
for i in $(test_seq 1 10); do
|
|
test_commit $i
|
|
done &&
|
|
git checkout -b other HEAD~5 &&
|
|
for i in $(test_seq 1 10); do
|
|
test_commit side-$i
|
|
done &&
|
|
git checkout master &&
|
|
blob=$(echo tagged-blob | git hash-object -w --stdin) &&
|
|
git tag tagged-blob $blob &&
|
|
git config pack.writebitmaps true &&
|
|
git config pack.writebitmaphashcache true
|
|
'
|
|
|
|
test_expect_success 'full repack creates bitmaps' '
|
|
git repack -ad &&
|
|
ls .git/objects/pack/ | grep bitmap >output &&
|
|
test_line_count = 1 output
|
|
'
|
|
|
|
test_expect_success 'rev-list --test-bitmap verifies bitmaps' '
|
|
git rev-list --test-bitmap HEAD
|
|
'
|
|
|
|
rev_list_tests() {
|
|
state=$1
|
|
|
|
test_expect_success "counting commits via bitmap ($state)" '
|
|
git rev-list --count HEAD >expect &&
|
|
git rev-list --use-bitmap-index --count HEAD >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_expect_success "counting partial commits via bitmap ($state)" '
|
|
git rev-list --count HEAD~5..HEAD >expect &&
|
|
git rev-list --use-bitmap-index --count HEAD~5..HEAD >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_expect_success "counting non-linear history ($state)" '
|
|
git rev-list --count other...master >expect &&
|
|
git rev-list --use-bitmap-index --count other...master >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_expect_success "enumerate --objects ($state)" '
|
|
git rev-list --objects --use-bitmap-index HEAD >tmp &&
|
|
cut -d" " -f1 <tmp >tmp2 &&
|
|
sort <tmp2 >actual &&
|
|
git rev-list --objects HEAD >tmp &&
|
|
cut -d" " -f1 <tmp >tmp2 &&
|
|
sort <tmp2 >expect &&
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_expect_success "bitmap --objects handles non-commit objects ($state)" '
|
|
git rev-list --objects --use-bitmap-index HEAD tagged-blob >actual &&
|
|
grep $blob actual
|
|
'
|
|
}
|
|
|
|
rev_list_tests 'full bitmap'
|
|
|
|
test_expect_success 'clone from bitmapped repository' '
|
|
git clone --no-local --bare . clone.git &&
|
|
git rev-parse HEAD >expect &&
|
|
git --git-dir=clone.git rev-parse HEAD >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_expect_success 'setup further non-bitmapped commits' '
|
|
for i in $(test_seq 1 10); do
|
|
test_commit further-$i
|
|
done
|
|
'
|
|
|
|
rev_list_tests 'partial bitmap'
|
|
|
|
test_expect_success 'fetch (partial bitmap)' '
|
|
git --git-dir=clone.git fetch origin master:master &&
|
|
git rev-parse HEAD >expect &&
|
|
git --git-dir=clone.git rev-parse HEAD >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_expect_success 'incremental repack cannot create bitmaps' '
|
|
test_commit more-1 &&
|
|
test_must_fail git repack -d
|
|
'
|
|
|
|
test_expect_success 'incremental repack can disable bitmaps' '
|
|
test_commit more-2 &&
|
|
git repack -d --no-write-bitmap-index
|
|
'
|
|
|
|
test_expect_success 'full repack, reusing previous bitmaps' '
|
|
git repack -ad &&
|
|
ls .git/objects/pack/ | grep bitmap >output &&
|
|
test_line_count = 1 output
|
|
'
|
|
|
|
test_expect_success 'fetch (full bitmap)' '
|
|
git --git-dir=clone.git fetch origin master:master &&
|
|
git rev-parse HEAD >expect &&
|
|
git --git-dir=clone.git rev-parse HEAD >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_lazy_prereq JGIT '
|
|
type jgit
|
|
'
|
|
|
|
test_expect_success JGIT 'we can read jgit bitmaps' '
|
|
git clone . compat-jgit &&
|
|
(
|
|
cd compat-jgit &&
|
|
rm -f .git/objects/pack/*.bitmap &&
|
|
jgit gc &&
|
|
git rev-list --test-bitmap HEAD
|
|
)
|
|
'
|
|
|
|
test_expect_success JGIT 'jgit can read our bitmaps' '
|
|
git clone . compat-us &&
|
|
(
|
|
cd compat-us &&
|
|
git repack -adb &&
|
|
# jgit gc will barf if it does not like our bitmaps
|
|
jgit gc
|
|
)
|
|
'
|
|
|
|
test_done
|