git/t/t5324-split-commit-graph.sh
Derrick Stolee 3b0199d4c3 commit-graph: start parsing generation v2 (again)
The 'read_generation_data' member of 'struct commit_graph' was
introduced by 1fdc383c5 (commit-graph: use generation v2 only if entire
chain does, 2021-01-16). The intention was to avoid using corrected
commit dates if not all layers of a commit-graph had that data stored.
The logic in validate_mixed_generation_chain() at that point incorrectly
initialized read_generation_data to 1 if and only if the tip
commit-graph contained the Corrected Commit Date chunk.

This was "fixed" in 448a39e65 (commit-graph: validate layers for
generation data, 2021-02-02) to validate that read_generation_data was
either non-zero for all layers, or it would set read_generation_data to
zero for all layers.

The problem here is that read_generation_data is not initialized to be
non-zero anywhere!

This change initializes read_generation_data immediately after the chunk
is parsed, so each layer will have its value present as soon as
possible.

The read_generation_data member is used in fill_commit_graph_info() to
determine if we should use the corrected commit date or the topological
levels stored in the Commit Data chunk. Due to this bug, all previous
versions of Git were defaulting to topological levels in all cases!

This can be measured with some performance tests. Using the Linux kernel
as a testbed, I generated a complete commit-graph containing corrected
commit dates and tested the 'new' version against the previous, 'old'
version.

First, rev-list with --topo-order demonstrates a 26% improvement using
corrected commit dates:

hyperfine \
	-n "old" "$OLD_GIT rev-list --topo-order -1000 v3.6" \
	-n "new" "$NEW_GIT rev-list --topo-order -1000 v3.6" \
	--warmup=10

Benchmark 1: old
  Time (mean ± σ):      57.1 ms ±   3.1 ms
  Range (min … max):    52.9 ms …  62.0 ms    55 runs

Benchmark 2: new
  Time (mean ± σ):      45.5 ms ±   3.3 ms
  Range (min … max):    39.9 ms …  51.7 ms    59 runs

Summary
  'new' ran
    1.26 ± 0.11 times faster than 'old'

These performance improvements are due to the algorithmic improvements
given by walking fewer commits due to the higher cutoffs from corrected
commit dates.

However, this comes at a cost. The additional I/O cost of parsing the
corrected commit dates is visible in case of merge-base commands that do
not reduce the overall number of walked commits.

hyperfine \
        -n "old" "$OLD_GIT merge-base v4.8 v4.9" \
        -n "new" "$NEW_GIT merge-base v4.8 v4.9" \
        --warmup=10

Benchmark 1: old
  Time (mean ± σ):     110.4 ms ±   6.4 ms
  Range (min … max):    96.0 ms … 118.3 ms    25 runs

Benchmark 2: new
  Time (mean ± σ):     150.7 ms ±   1.1 ms
  Range (min … max):   149.3 ms … 153.4 ms    19 runs

Summary
  'old' ran
    1.36 ± 0.08 times faster than 'new'

Performance issues like this are what motivated 702110aac (commit-graph:
use config to specify generation type, 2021-02-25).

In the future, we could fix this performance problem by inserting the
corrected commit date offsets into the Commit Date chunk instead of
having that data in an extra chunk.

Signed-off-by: Derrick Stolee <derrickstolee@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-03-01 12:15:06 -08:00

651 lines
20 KiB
Bash
Executable file

#!/bin/sh
test_description='split commit graph'
. ./test-lib.sh
GIT_TEST_COMMIT_GRAPH=0
GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS=0
test_expect_success 'setup repo' '
git init &&
git config core.commitGraph true &&
git config gc.writeCommitGraph false &&
infodir=".git/objects/info" &&
graphdir="$infodir/commit-graphs" &&
test_oid_cache <<-EOM
shallow sha1:2132
shallow sha256:2436
base sha1:1408
base sha256:1528
oid_version sha1:1
oid_version sha256:2
EOM
'
graph_read_expect() {
NUM_BASE=0
if test ! -z $2
then
NUM_BASE=$2
fi
OPTIONS=
if test -z "$3"
then
OPTIONS=" read_generation_data"
fi
cat >expect <<- EOF
header: 43475048 1 $(test_oid oid_version) 4 $NUM_BASE
num_commits: $1
chunks: oid_fanout oid_lookup commit_metadata generation_data
options:$OPTIONS
EOF
test-tool read-graph >output &&
test_cmp expect output
}
test_expect_success POSIXPERM 'tweak umask for modebit tests' '
umask 022
'
test_expect_success 'create commits and write commit-graph' '
for i in $(test_seq 3)
do
test_commit $i &&
git branch commits/$i || return 1
done &&
git commit-graph write --reachable &&
test_path_is_file $infodir/commit-graph &&
graph_read_expect 3
'
graph_git_two_modes() {
git ${2:+ -C "$2"} -c core.commitGraph=true $1 >output &&
git ${2:+ -C "$2"} -c core.commitGraph=false $1 >expect &&
test_cmp expect output
}
graph_git_behavior() {
MSG=$1
BRANCH=$2
COMPARE=$3
DIR=$4
test_expect_success "check normal git operations: $MSG" '
graph_git_two_modes "log --oneline $BRANCH" "$DIR" &&
graph_git_two_modes "log --topo-order $BRANCH" "$DIR" &&
graph_git_two_modes "log --graph $COMPARE..$BRANCH" "$DIR" &&
graph_git_two_modes "branch -vv" "$DIR" &&
graph_git_two_modes "merge-base -a $BRANCH $COMPARE" "$DIR"
'
}
graph_git_behavior 'graph exists' commits/3 commits/1
verify_chain_files_exist() {
for hash in $(cat $1/commit-graph-chain)
do
test_path_is_file $1/graph-$hash.graph || return 1
done
}
test_expect_success 'add more commits, and write a new base graph' '
git reset --hard commits/1 &&
for i in $(test_seq 4 5)
do
test_commit $i &&
git branch commits/$i || return 1
done &&
git reset --hard commits/2 &&
for i in $(test_seq 6 10)
do
test_commit $i &&
git branch commits/$i || return 1
done &&
git reset --hard commits/2 &&
git merge commits/4 &&
git branch merge/1 &&
git reset --hard commits/4 &&
git merge commits/6 &&
git branch merge/2 &&
git commit-graph write --reachable &&
graph_read_expect 12
'
test_expect_success 'fork and fail to base a chain on a commit-graph file' '
test_when_finished rm -rf fork &&
git clone . fork &&
(
cd fork &&
rm .git/objects/info/commit-graph &&
echo "$(pwd)/../.git/objects" >.git/objects/info/alternates &&
test_commit new-commit &&
git commit-graph write --reachable --split &&
test_path_is_file $graphdir/commit-graph-chain &&
test_line_count = 1 $graphdir/commit-graph-chain &&
verify_chain_files_exist $graphdir
)
'
test_expect_success 'add three more commits, write a tip graph' '
git reset --hard commits/3 &&
git merge merge/1 &&
git merge commits/5 &&
git merge merge/2 &&
git branch merge/3 &&
git commit-graph write --reachable --split &&
test_path_is_missing $infodir/commit-graph &&
test_path_is_file $graphdir/commit-graph-chain &&
ls $graphdir/graph-*.graph >graph-files &&
test_line_count = 2 graph-files &&
verify_chain_files_exist $graphdir
'
graph_git_behavior 'split commit-graph: merge 3 vs 2' merge/3 merge/2
test_expect_success 'add one commit, write a tip graph' '
test_commit 11 &&
git branch commits/11 &&
git commit-graph write --reachable --split &&
test_path_is_missing $infodir/commit-graph &&
test_path_is_file $graphdir/commit-graph-chain &&
ls $graphdir/graph-*.graph >graph-files &&
test_line_count = 3 graph-files &&
verify_chain_files_exist $graphdir
'
graph_git_behavior 'three-layer commit-graph: commit 11 vs 6' commits/11 commits/6
test_expect_success 'add one commit, write a merged graph' '
test_commit 12 &&
git branch commits/12 &&
git commit-graph write --reachable --split &&
test_path_is_file $graphdir/commit-graph-chain &&
test_line_count = 2 $graphdir/commit-graph-chain &&
ls $graphdir/graph-*.graph >graph-files &&
test_line_count = 2 graph-files &&
verify_chain_files_exist $graphdir
'
graph_git_behavior 'merged commit-graph: commit 12 vs 6' commits/12 commits/6
test_expect_success 'create fork and chain across alternate' '
git clone . fork &&
(
cd fork &&
git config core.commitGraph true &&
rm -rf $graphdir &&
echo "$(pwd)/../.git/objects" >.git/objects/info/alternates &&
test_commit 13 &&
git branch commits/13 &&
git commit-graph write --reachable --split &&
test_path_is_file $graphdir/commit-graph-chain &&
test_line_count = 3 $graphdir/commit-graph-chain &&
ls $graphdir/graph-*.graph >graph-files &&
test_line_count = 1 graph-files &&
git -c core.commitGraph=true rev-list HEAD >expect &&
git -c core.commitGraph=false rev-list HEAD >actual &&
test_cmp expect actual &&
test_commit 14 &&
git commit-graph write --reachable --split --object-dir=.git/objects/ &&
test_line_count = 3 $graphdir/commit-graph-chain &&
ls $graphdir/graph-*.graph >graph-files &&
test_line_count = 1 graph-files
)
'
if test -d fork
then
graph_git_behavior 'alternate: commit 13 vs 6' commits/13 origin/commits/6 "fork"
fi
test_expect_success 'test merge stragety constants' '
git clone . merge-2 &&
(
cd merge-2 &&
git config core.commitGraph true &&
test_line_count = 2 $graphdir/commit-graph-chain &&
test_commit 14 &&
git commit-graph write --reachable --split --size-multiple=2 &&
test_line_count = 3 $graphdir/commit-graph-chain
) &&
git clone . merge-10 &&
(
cd merge-10 &&
git config core.commitGraph true &&
test_line_count = 2 $graphdir/commit-graph-chain &&
test_commit 14 &&
git commit-graph write --reachable --split --size-multiple=10 &&
test_line_count = 1 $graphdir/commit-graph-chain &&
ls $graphdir/graph-*.graph >graph-files &&
test_line_count = 1 graph-files
) &&
git clone . merge-10-expire &&
(
cd merge-10-expire &&
git config core.commitGraph true &&
test_line_count = 2 $graphdir/commit-graph-chain &&
test_commit 15 &&
touch $graphdir/to-delete.graph $graphdir/to-keep.graph &&
test-tool chmtime =1546362000 $graphdir/to-delete.graph &&
test-tool chmtime =1546362001 $graphdir/to-keep.graph &&
git commit-graph write --reachable --split --size-multiple=10 \
--expire-time="2019-01-01 12:00 -05:00" &&
test_line_count = 1 $graphdir/commit-graph-chain &&
test_path_is_missing $graphdir/to-delete.graph &&
test_path_is_file $graphdir/to-keep.graph &&
ls $graphdir/graph-*.graph >graph-files &&
test_line_count = 3 graph-files
) &&
git clone --no-hardlinks . max-commits &&
(
cd max-commits &&
git config core.commitGraph true &&
test_line_count = 2 $graphdir/commit-graph-chain &&
test_commit 16 &&
test_commit 17 &&
git commit-graph write --reachable --split --max-commits=1 &&
test_line_count = 1 $graphdir/commit-graph-chain &&
ls $graphdir/graph-*.graph >graph-files &&
test_line_count = 1 graph-files
)
'
test_expect_success 'remove commit-graph-chain file after flattening' '
git clone . flatten &&
(
cd flatten &&
test_line_count = 2 $graphdir/commit-graph-chain &&
git commit-graph write --reachable &&
test_path_is_missing $graphdir/commit-graph-chain &&
ls $graphdir >graph-files &&
test_line_count = 0 graph-files
)
'
corrupt_file() {
file=$1
pos=$2
data="${3:-\0}"
chmod a+w "$file" &&
printf "$data" | dd of="$file" bs=1 seek="$pos" conv=notrunc
}
test_expect_success 'verify hashes along chain, even in shallow' '
git clone --no-hardlinks . verify &&
(
cd verify &&
git commit-graph verify &&
base_file=$graphdir/graph-$(head -n 1 $graphdir/commit-graph-chain).graph &&
corrupt_file "$base_file" $(test_oid shallow) "\01" &&
test_must_fail git commit-graph verify --shallow 2>test_err &&
grep -v "^+" test_err >err &&
test_i18ngrep "incorrect checksum" err
)
'
test_expect_success 'verify --shallow does not check base contents' '
git clone --no-hardlinks . verify-shallow &&
(
cd verify-shallow &&
git commit-graph verify &&
base_file=$graphdir/graph-$(head -n 1 $graphdir/commit-graph-chain).graph &&
corrupt_file "$base_file" 1000 "\01" &&
git commit-graph verify --shallow &&
test_must_fail git commit-graph verify 2>test_err &&
grep -v "^+" test_err >err &&
test_i18ngrep "incorrect checksum" err
)
'
test_expect_success 'warn on base graph chunk incorrect' '
git clone --no-hardlinks . base-chunk &&
(
cd base-chunk &&
git commit-graph verify &&
base_file=$graphdir/graph-$(tail -n 1 $graphdir/commit-graph-chain).graph &&
corrupt_file "$base_file" $(test_oid base) "\01" &&
git commit-graph verify --shallow 2>test_err &&
grep -v "^+" test_err >err &&
test_i18ngrep "commit-graph chain does not match" err
)
'
test_expect_success 'verify after commit-graph-chain corruption' '
git clone --no-hardlinks . verify-chain &&
(
cd verify-chain &&
corrupt_file "$graphdir/commit-graph-chain" 60 "G" &&
git commit-graph verify 2>test_err &&
grep -v "^+" test_err >err &&
test_i18ngrep "invalid commit-graph chain" err &&
corrupt_file "$graphdir/commit-graph-chain" 60 "A" &&
git commit-graph verify 2>test_err &&
grep -v "^+" test_err >err &&
test_i18ngrep "unable to find all commit-graph files" err
)
'
test_expect_success 'verify across alternates' '
git clone --no-hardlinks . verify-alt &&
(
cd verify-alt &&
rm -rf $graphdir &&
altdir="$(pwd)/../.git/objects" &&
echo "$altdir" >.git/objects/info/alternates &&
git commit-graph verify --object-dir="$altdir/" &&
test_commit extra &&
git commit-graph write --reachable --split &&
tip_file=$graphdir/graph-$(tail -n 1 $graphdir/commit-graph-chain).graph &&
corrupt_file "$tip_file" 100 "\01" &&
test_must_fail git commit-graph verify --shallow 2>test_err &&
grep -v "^+" test_err >err &&
test_i18ngrep "commit-graph has incorrect fanout value" err
)
'
test_expect_success 'add octopus merge' '
git reset --hard commits/10 &&
git merge commits/3 commits/4 &&
git branch merge/octopus &&
git commit-graph write --reachable --split &&
git commit-graph verify --progress 2>err &&
test_line_count = 3 err &&
test_i18ngrep ! warning err &&
test_line_count = 3 $graphdir/commit-graph-chain
'
graph_git_behavior 'graph exists' merge/octopus commits/12
test_expect_success 'split across alternate where alternate is not split' '
git commit-graph write --reachable &&
test_path_is_file .git/objects/info/commit-graph &&
cp .git/objects/info/commit-graph . &&
git clone --no-hardlinks . alt-split &&
(
cd alt-split &&
rm -f .git/objects/info/commit-graph &&
echo "$(pwd)"/../.git/objects >.git/objects/info/alternates &&
test_commit 18 &&
git commit-graph write --reachable --split &&
test_line_count = 1 $graphdir/commit-graph-chain
) &&
test_cmp commit-graph .git/objects/info/commit-graph
'
test_expect_success '--split=no-merge always writes an incremental' '
test_when_finished rm -rf a b &&
rm -rf $graphdir $infodir/commit-graph &&
git reset --hard commits/2 &&
git rev-list HEAD~1 >a &&
git rev-list HEAD >b &&
git commit-graph write --split --stdin-commits <a &&
git commit-graph write --split=no-merge --stdin-commits <b &&
test_line_count = 2 $graphdir/commit-graph-chain
'
test_expect_success '--split=replace replaces the chain' '
rm -rf $graphdir $infodir/commit-graph &&
git reset --hard commits/3 &&
git rev-list -1 HEAD~2 >a &&
git rev-list -1 HEAD~1 >b &&
git rev-list -1 HEAD >c &&
git commit-graph write --split=no-merge --stdin-commits <a &&
git commit-graph write --split=no-merge --stdin-commits <b &&
git commit-graph write --split=no-merge --stdin-commits <c &&
test_line_count = 3 $graphdir/commit-graph-chain &&
git commit-graph write --stdin-commits --split=replace <b &&
test_path_is_missing $infodir/commit-graph &&
test_path_is_file $graphdir/commit-graph-chain &&
ls $graphdir/graph-*.graph >graph-files &&
test_line_count = 1 graph-files &&
verify_chain_files_exist $graphdir &&
graph_read_expect 2
'
test_expect_success ULIMIT_FILE_DESCRIPTORS 'handles file descriptor exhaustion' '
git init ulimit &&
(
cd ulimit &&
for i in $(test_seq 64)
do
test_commit $i &&
run_with_limited_open_files test_might_fail git commit-graph write \
--split=no-merge --reachable || return 1
done
)
'
while read mode modebits
do
test_expect_success POSIXPERM "split commit-graph respects core.sharedrepository $mode" '
rm -rf $graphdir $infodir/commit-graph &&
git reset --hard commits/1 &&
test_config core.sharedrepository "$mode" &&
git commit-graph write --split --reachable &&
ls $graphdir/graph-*.graph >graph-files &&
test_line_count = 1 graph-files &&
echo "$modebits" >expect &&
test_modebits $graphdir/graph-*.graph >actual &&
test_cmp expect actual &&
test_modebits $graphdir/commit-graph-chain >actual &&
test_cmp expect actual
'
done <<\EOF
0666 -r--r--r--
0600 -r--------
EOF
test_expect_success '--split=replace with partial Bloom data' '
rm -rf $graphdir $infodir/commit-graph &&
git reset --hard commits/3 &&
git rev-list -1 HEAD~2 >a &&
git rev-list -1 HEAD~1 >b &&
git commit-graph write --split=no-merge --stdin-commits --changed-paths <a &&
git commit-graph write --split=no-merge --stdin-commits <b &&
git commit-graph write --split=replace --stdin-commits --changed-paths <c &&
ls $graphdir/graph-*.graph >graph-files &&
test_line_count = 1 graph-files &&
verify_chain_files_exist $graphdir
'
test_expect_success 'prevent regression for duplicate commits across layers' '
git init dup &&
git -C dup commit --allow-empty -m one &&
git -C dup -c core.commitGraph=false commit-graph write --split=no-merge --reachable 2>err &&
test_i18ngrep "attempting to write a commit-graph" err &&
git -C dup commit-graph write --split=no-merge --reachable &&
git -C dup commit --allow-empty -m two &&
git -C dup commit-graph write --split=no-merge --reachable &&
git -C dup commit --allow-empty -m three &&
git -C dup commit-graph write --split --reachable &&
git -C dup commit-graph verify
'
NUM_FIRST_LAYER_COMMITS=64
NUM_SECOND_LAYER_COMMITS=16
NUM_THIRD_LAYER_COMMITS=7
NUM_FOURTH_LAYER_COMMITS=8
NUM_FIFTH_LAYER_COMMITS=16
SECOND_LAYER_SEQUENCE_START=$(($NUM_FIRST_LAYER_COMMITS + 1))
SECOND_LAYER_SEQUENCE_END=$(($SECOND_LAYER_SEQUENCE_START + $NUM_SECOND_LAYER_COMMITS - 1))
THIRD_LAYER_SEQUENCE_START=$(($SECOND_LAYER_SEQUENCE_END + 1))
THIRD_LAYER_SEQUENCE_END=$(($THIRD_LAYER_SEQUENCE_START + $NUM_THIRD_LAYER_COMMITS - 1))
FOURTH_LAYER_SEQUENCE_START=$(($THIRD_LAYER_SEQUENCE_END + 1))
FOURTH_LAYER_SEQUENCE_END=$(($FOURTH_LAYER_SEQUENCE_START + $NUM_FOURTH_LAYER_COMMITS - 1))
FIFTH_LAYER_SEQUENCE_START=$(($FOURTH_LAYER_SEQUENCE_END + 1))
FIFTH_LAYER_SEQUENCE_END=$(($FIFTH_LAYER_SEQUENCE_START + $NUM_FIFTH_LAYER_COMMITS - 1))
# Current split graph chain:
#
# 16 commits (No GDAT)
# ------------------------
# 64 commits (GDAT)
#
test_expect_success 'setup repo for mixed generation commit-graph-chain' '
graphdir=".git/objects/info/commit-graphs" &&
test_oid_cache <<-EOF &&
oid_version sha1:1
oid_version sha256:2
EOF
git init mixed &&
(
cd mixed &&
git config core.commitGraph true &&
git config gc.writeCommitGraph false &&
for i in $(test_seq $NUM_FIRST_LAYER_COMMITS)
do
test_commit $i &&
git branch commits/$i || return 1
done &&
git -c commitGraph.generationVersion=2 commit-graph write --reachable --split &&
graph_read_expect $NUM_FIRST_LAYER_COMMITS &&
test_line_count = 1 $graphdir/commit-graph-chain &&
for i in $(test_seq $SECOND_LAYER_SEQUENCE_START $SECOND_LAYER_SEQUENCE_END)
do
test_commit $i &&
git branch commits/$i || return 1
done &&
git -c commitGraph.generationVersion=1 commit-graph write --reachable --split=no-merge &&
test_line_count = 2 $graphdir/commit-graph-chain &&
test-tool read-graph >output &&
cat >expect <<-EOF &&
header: 43475048 1 $(test_oid oid_version) 4 1
num_commits: $NUM_SECOND_LAYER_COMMITS
chunks: oid_fanout oid_lookup commit_metadata
options:
EOF
test_cmp expect output &&
git commit-graph verify &&
cat $graphdir/commit-graph-chain
)
'
# The new layer will be added without generation data chunk as it was not
# present on the layer underneath it.
#
# 7 commits (No GDAT)
# ------------------------
# 16 commits (No GDAT)
# ------------------------
# 64 commits (GDAT)
#
test_expect_success 'do not write generation data chunk if not present on existing tip' '
git clone mixed mixed-no-gdat &&
(
cd mixed-no-gdat &&
for i in $(test_seq $THIRD_LAYER_SEQUENCE_START $THIRD_LAYER_SEQUENCE_END)
do
test_commit $i &&
git branch commits/$i || return 1
done &&
git commit-graph write --reachable --split=no-merge &&
test_line_count = 3 $graphdir/commit-graph-chain &&
test-tool read-graph >output &&
cat >expect <<-EOF &&
header: 43475048 1 $(test_oid oid_version) 4 2
num_commits: $NUM_THIRD_LAYER_COMMITS
chunks: oid_fanout oid_lookup commit_metadata
options:
EOF
test_cmp expect output &&
git commit-graph verify
)
'
# Number of commits in each layer of the split-commit graph before merge:
#
# 8 commits (No GDAT)
# ------------------------
# 7 commits (No GDAT)
# ------------------------
# 16 commits (No GDAT)
# ------------------------
# 64 commits (GDAT)
#
# The top two layers are merged and do not have generation data chunk as layer below them does
# not have generation data chunk.
#
# 15 commits (No GDAT)
# ------------------------
# 16 commits (No GDAT)
# ------------------------
# 64 commits (GDAT)
#
test_expect_success 'do not write generation data chunk if the topmost remaining layer does not have generation data chunk' '
git clone mixed-no-gdat mixed-merge-no-gdat &&
(
cd mixed-merge-no-gdat &&
for i in $(test_seq $FOURTH_LAYER_SEQUENCE_START $FOURTH_LAYER_SEQUENCE_END)
do
test_commit $i &&
git branch commits/$i || return 1
done &&
git commit-graph write --reachable --split --size-multiple 1 &&
test_line_count = 3 $graphdir/commit-graph-chain &&
test-tool read-graph >output &&
cat >expect <<-EOF &&
header: 43475048 1 $(test_oid oid_version) 4 2
num_commits: $(($NUM_THIRD_LAYER_COMMITS + $NUM_FOURTH_LAYER_COMMITS))
chunks: oid_fanout oid_lookup commit_metadata
options:
EOF
test_cmp expect output &&
git commit-graph verify
)
'
# Number of commits in each layer of the split-commit graph before merge:
#
# 16 commits (No GDAT)
# ------------------------
# 15 commits (No GDAT)
# ------------------------
# 16 commits (No GDAT)
# ------------------------
# 64 commits (GDAT)
#
# The top three layers are merged and has generation data chunk as the topmost remaining layer
# has generation data chunk.
#
# 47 commits (GDAT)
# ------------------------
# 64 commits (GDAT)
#
test_expect_success 'write generation data chunk if topmost remaining layer has generation data chunk' '
git clone mixed-merge-no-gdat mixed-merge-gdat &&
(
cd mixed-merge-gdat &&
for i in $(test_seq $FIFTH_LAYER_SEQUENCE_START $FIFTH_LAYER_SEQUENCE_END)
do
test_commit $i &&
git branch commits/$i || return 1
done &&
git commit-graph write --reachable --split --size-multiple 1 &&
test_line_count = 2 $graphdir/commit-graph-chain &&
test-tool read-graph >output &&
cat >expect <<-EOF &&
header: 43475048 1 $(test_oid oid_version) 5 1
num_commits: $(($NUM_SECOND_LAYER_COMMITS + $NUM_THIRD_LAYER_COMMITS + $NUM_FOURTH_LAYER_COMMITS + $NUM_FIFTH_LAYER_COMMITS))
chunks: oid_fanout oid_lookup commit_metadata generation_data
options: read_generation_data
EOF
test_cmp expect output
)
'
test_expect_success 'write generation data chunk when commit-graph chain is replaced' '
git clone mixed mixed-replace &&
(
cd mixed-replace &&
git commit-graph write --reachable --split=replace &&
test_path_is_file $graphdir/commit-graph-chain &&
test_line_count = 1 $graphdir/commit-graph-chain &&
verify_chain_files_exist $graphdir &&
graph_read_expect $(($NUM_FIRST_LAYER_COMMITS + $NUM_SECOND_LAYER_COMMITS)) &&
git commit-graph verify
)
'
test_done