mirror of
https://github.com/git/git
synced 2024-08-28 12:09:19 +00:00
![Jeff King](/assets/img/avatar_default.png)
Commit0696232390
(pack-redundant: fix crash when one packfile in repo, 2020-12-16) added one some new tests to t5323. At the time, the sub-repo we used was called "master". But in a parallel branch, this was switched to "main". When the latter branch was merged in27d7c8599b
(Merge branch 'js/default-branch-name-tests-final-stretch', 2021-01-25), some of those spots caused textual conflicts, but some (for tests that were far enough away from other changed code) were just semantic. The merge resolution fixed up most spots, but missed this one. Even though this did impact actual code, it turned out not to fail the tests. Running 'cd "$master_repo"' ended up staying in the same directory, running the test in the main trash repo instead of the sub-repo. But because the point of the test is checking behavior when there are no packfiles, it worked in either repo (since both are empty at this point in the script). Reported-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
499 lines
14 KiB
Bash
Executable file
499 lines
14 KiB
Bash
Executable file
#!/bin/sh
|
|
#
|
|
# Copyright (c) 2018 Jiang Xin
|
|
#
|
|
|
|
test_description='Test git pack-redundant
|
|
|
|
In order to test git-pack-redundant, we will create a number of objects and
|
|
packs in the repository `main.git`. The relationship between packs (P1-P8)
|
|
and objects (T, A-R) is showed in the following chart. Objects of a pack will
|
|
be marked with letter x, while objects of redundant packs will be marked with
|
|
exclamation point, and redundant pack itself will be marked with asterisk.
|
|
|
|
| T A B C D E F G H I J K L M N O P Q R
|
|
----+--------------------------------------
|
|
P1 | x x x x x x x x
|
|
P2* | ! ! ! ! ! ! !
|
|
P3 | x x x x x x
|
|
P4* | ! ! ! ! !
|
|
P5 | x x x x
|
|
P6* | ! ! !
|
|
P7 | x x
|
|
P8* | !
|
|
----+--------------------------------------
|
|
ALL | x x x x x x x x x x x x x x x x x x x
|
|
|
|
Another repository `shared.git` has unique objects (X-Z), while other objects
|
|
(marked with letter s) are shared through alt-odb (of `main.git`). The
|
|
relationship between packs and objects is as follows:
|
|
|
|
| T A B C D E F G H I J K L M N O P Q R X Y Z
|
|
----+----------------------------------------------
|
|
Px1 | s s s x x x
|
|
Px2 | s s s x x x
|
|
'
|
|
|
|
. ./test-lib.sh
|
|
|
|
main_repo=main.git
|
|
shared_repo=shared.git
|
|
|
|
git_pack_redundant='git pack-redundant --i-still-use-this'
|
|
|
|
# Create commits in <repo> and assign each commit's oid to shell variables
|
|
# given in the arguments (A, B, and C). E.g.:
|
|
#
|
|
# create_commits_in <repo> A B C
|
|
#
|
|
# NOTE: Avoid calling this function from a subshell since variable
|
|
# assignments will disappear when subshell exits.
|
|
create_commits_in () {
|
|
repo="$1" &&
|
|
if ! parent=$(git -C "$repo" rev-parse HEAD^{} 2>/dev/null)
|
|
then
|
|
parent=
|
|
fi &&
|
|
T=$(git -C "$repo" write-tree) &&
|
|
shift &&
|
|
while test $# -gt 0
|
|
do
|
|
name=$1 &&
|
|
test_tick &&
|
|
if test -z "$parent"
|
|
then
|
|
oid=$(echo $name | git -C "$repo" commit-tree $T)
|
|
else
|
|
oid=$(echo $name | git -C "$repo" commit-tree -p $parent $T)
|
|
fi &&
|
|
eval $name=$oid &&
|
|
parent=$oid &&
|
|
shift ||
|
|
return 1
|
|
done &&
|
|
git -C "$repo" update-ref refs/heads/main $oid
|
|
}
|
|
|
|
# Create pack in <repo> and assign pack id to variable given in the 2nd argument
|
|
# (<name>). Commits in the pack will be read from stdin. E.g.:
|
|
#
|
|
# create_pack_in <repo> <name> <<-EOF
|
|
# ...
|
|
# EOF
|
|
#
|
|
# NOTE: commits from stdin should be given using heredoc, not using pipe, and
|
|
# avoid calling this function from a subshell since variable assignments will
|
|
# disappear when subshell exits.
|
|
create_pack_in () {
|
|
repo="$1" &&
|
|
name="$2" &&
|
|
pack=$(git -C "$repo/objects/pack" pack-objects -q pack) &&
|
|
eval $name=$pack &&
|
|
eval P$pack=$name:$pack
|
|
}
|
|
|
|
format_packfiles () {
|
|
sed \
|
|
-e "s#.*/pack-\(.*\)\.idx#\1#" \
|
|
-e "s#.*/pack-\(.*\)\.pack#\1#" |
|
|
sort -u |
|
|
while read p
|
|
do
|
|
if test -z "$(eval echo \${P$p})"
|
|
then
|
|
echo $p
|
|
else
|
|
eval echo "\${P$p}"
|
|
fi
|
|
done |
|
|
sort
|
|
}
|
|
|
|
test_expect_success 'setup main repo' '
|
|
git init --bare "$main_repo" &&
|
|
create_commits_in "$main_repo" A B C D E F G H I J K L M N O P Q R
|
|
'
|
|
|
|
test_expect_success 'main: pack-redundant works with no packfile' '
|
|
(
|
|
cd "$main_repo" &&
|
|
cat >expect <<-EOF &&
|
|
fatal: Zero packs found!
|
|
EOF
|
|
test_must_fail $git_pack_redundant --all >actual 2>&1 &&
|
|
test_cmp expect actual
|
|
)
|
|
'
|
|
|
|
#############################################################################
|
|
# Chart of packs and objects for this test case
|
|
#
|
|
# | T A B C D E F G H I J K L M N O P Q R
|
|
# ----+--------------------------------------
|
|
# P1 | x x x x x x x x
|
|
# ----+--------------------------------------
|
|
# ALL | x x x x x x x x
|
|
#
|
|
#############################################################################
|
|
test_expect_success 'main: pack-redundant works with one packfile' '
|
|
create_pack_in "$main_repo" P1 <<-EOF &&
|
|
$T
|
|
$A
|
|
$B
|
|
$C
|
|
$D
|
|
$E
|
|
$F
|
|
$R
|
|
EOF
|
|
(
|
|
cd "$main_repo" &&
|
|
$git_pack_redundant --all >out &&
|
|
test_must_be_empty out
|
|
)
|
|
'
|
|
|
|
#############################################################################
|
|
# Chart of packs and objects for this test case
|
|
#
|
|
# | T A B C D E F G H I J K L M N O P Q R
|
|
# ----+--------------------------------------
|
|
# P1 | x x x x x x x x
|
|
# P2 | x x x x x x x
|
|
# P3 | x x x x x x
|
|
# ----+--------------------------------------
|
|
# ALL | x x x x x x x x x x x x x x x
|
|
#
|
|
#############################################################################
|
|
test_expect_success 'main: no redundant for pack 1, 2, 3' '
|
|
create_pack_in "$main_repo" P2 <<-EOF &&
|
|
$B
|
|
$C
|
|
$D
|
|
$E
|
|
$G
|
|
$H
|
|
$I
|
|
EOF
|
|
create_pack_in "$main_repo" P3 <<-EOF &&
|
|
$F
|
|
$I
|
|
$J
|
|
$K
|
|
$L
|
|
$M
|
|
EOF
|
|
(
|
|
cd "$main_repo" &&
|
|
$git_pack_redundant --all >out &&
|
|
test_must_be_empty out
|
|
)
|
|
'
|
|
|
|
#############################################################################
|
|
# Chart of packs and objects for this test case
|
|
#
|
|
# | T A B C D E F G H I J K L M N O P Q R
|
|
# ----+--------------------------------------
|
|
# P1 | x x x x x x x x
|
|
# P2 | x x x x x x x
|
|
# P3* | ! ! ! ! ! !
|
|
# P4 | x x x x x
|
|
# P5 | x x x x
|
|
# ----+--------------------------------------
|
|
# ALL | x x x x x x x x x x x x x x x x x x
|
|
#
|
|
#############################################################################
|
|
test_expect_success 'main: one of pack-2/pack-3 is redundant' '
|
|
create_pack_in "$main_repo" P4 <<-EOF &&
|
|
$J
|
|
$K
|
|
$L
|
|
$M
|
|
$P
|
|
EOF
|
|
create_pack_in "$main_repo" P5 <<-EOF &&
|
|
$G
|
|
$H
|
|
$N
|
|
$O
|
|
EOF
|
|
(
|
|
cd "$main_repo" &&
|
|
cat >expect <<-EOF &&
|
|
P3:$P3
|
|
EOF
|
|
$git_pack_redundant --all >out &&
|
|
format_packfiles <out >actual &&
|
|
test_cmp expect actual
|
|
)
|
|
'
|
|
|
|
#############################################################################
|
|
# Chart of packs and objects for this test case
|
|
#
|
|
# | T A B C D E F G H I J K L M N O P Q R
|
|
# ----+--------------------------------------
|
|
# P1 | x x x x x x x x
|
|
# P2* | ! ! ! ! ! ! !
|
|
# P3 | x x x x x x
|
|
# P4* | ! ! ! ! !
|
|
# P5 | x x x x
|
|
# P6* | ! ! !
|
|
# P7 | x x
|
|
# ----+--------------------------------------
|
|
# ALL | x x x x x x x x x x x x x x x x x x x
|
|
#
|
|
#############################################################################
|
|
test_expect_success 'main: pack 2, 4, and 6 are redundant' '
|
|
create_pack_in "$main_repo" P6 <<-EOF &&
|
|
$N
|
|
$O
|
|
$Q
|
|
EOF
|
|
create_pack_in "$main_repo" P7 <<-EOF &&
|
|
$P
|
|
$Q
|
|
EOF
|
|
(
|
|
cd "$main_repo" &&
|
|
cat >expect <<-EOF &&
|
|
P2:$P2
|
|
P4:$P4
|
|
P6:$P6
|
|
EOF
|
|
$git_pack_redundant --all >out &&
|
|
format_packfiles <out >actual &&
|
|
test_cmp expect actual
|
|
)
|
|
'
|
|
|
|
#############################################################################
|
|
# Chart of packs and objects for this test case
|
|
#
|
|
# | T A B C D E F G H I J K L M N O P Q R
|
|
# ----+--------------------------------------
|
|
# P1 | x x x x x x x x
|
|
# P2* | ! ! ! ! ! ! !
|
|
# P3 | x x x x x x
|
|
# P4* | ! ! ! ! !
|
|
# P5 | x x x x
|
|
# P6* | ! ! !
|
|
# P7 | x x
|
|
# P8* | !
|
|
# ----+--------------------------------------
|
|
# ALL | x x x x x x x x x x x x x x x x x x x
|
|
#
|
|
#############################################################################
|
|
test_expect_success 'main: pack-8 (subset of pack-1) is also redundant' '
|
|
create_pack_in "$main_repo" P8 <<-EOF &&
|
|
$A
|
|
EOF
|
|
(
|
|
cd "$main_repo" &&
|
|
cat >expect <<-EOF &&
|
|
P2:$P2
|
|
P4:$P4
|
|
P6:$P6
|
|
P8:$P8
|
|
EOF
|
|
$git_pack_redundant --all >out &&
|
|
format_packfiles <out >actual &&
|
|
test_cmp expect actual
|
|
)
|
|
'
|
|
|
|
test_expect_success 'main: clean loose objects' '
|
|
(
|
|
cd "$main_repo" &&
|
|
git prune-packed &&
|
|
find objects -type f | sed -e "/objects\/pack\//d" >out &&
|
|
test_must_be_empty out
|
|
)
|
|
'
|
|
|
|
test_expect_success 'main: remove redundant packs and pass fsck' '
|
|
(
|
|
cd "$main_repo" &&
|
|
$git_pack_redundant --all | xargs rm &&
|
|
git fsck &&
|
|
$git_pack_redundant --all >out &&
|
|
test_must_be_empty out
|
|
)
|
|
'
|
|
|
|
# The following test cases will execute inside `shared.git`, instead of
|
|
# inside `main.git`.
|
|
test_expect_success 'setup shared.git' '
|
|
git clone --mirror "$main_repo" "$shared_repo" &&
|
|
(
|
|
cd "$shared_repo" &&
|
|
printf "../../$main_repo/objects\n" >objects/info/alternates
|
|
)
|
|
'
|
|
|
|
test_expect_success 'shared: all packs are redundant, but no output without --alt-odb' '
|
|
(
|
|
cd "$shared_repo" &&
|
|
$git_pack_redundant --all >out &&
|
|
test_must_be_empty out
|
|
)
|
|
'
|
|
|
|
#############################################################################
|
|
# Chart of packs and objects for this test case
|
|
#
|
|
# ================= main.git ================
|
|
# | T A B C D E F G H I J K L M N O P Q R <----------+
|
|
# ----+-------------------------------------- |
|
|
# P1 | x x x x x x x x |
|
|
# P3 | x x x x x x |
|
|
# P5 | x x x x |
|
|
# P7 | x x |
|
|
# ----+-------------------------------------- |
|
|
# ALL | x x x x x x x x x x x x x x x x x x x |
|
|
# |
|
|
# |
|
|
# ================ shared.git =============== |
|
|
# | T A B C D E F G H I J K L M N O P Q R <objects/info/alternates>
|
|
# ----+--------------------------------------
|
|
# P1* | s s s s s s s s
|
|
# P3* | s s s s s s
|
|
# P5* | s s s s
|
|
# P7* | s s
|
|
# ----+--------------------------------------
|
|
# ALL | x x x x x x x x x x x x x x x x x x x
|
|
#
|
|
#############################################################################
|
|
test_expect_success 'shared: show redundant packs in stderr for verbose mode' '
|
|
(
|
|
cd "$shared_repo" &&
|
|
cat >expect <<-EOF &&
|
|
P1:$P1
|
|
P3:$P3
|
|
P5:$P5
|
|
P7:$P7
|
|
EOF
|
|
$git_pack_redundant --all --verbose >out 2>out.err &&
|
|
test_must_be_empty out &&
|
|
grep "pack$" out.err | format_packfiles >actual &&
|
|
test_cmp expect actual
|
|
)
|
|
'
|
|
|
|
test_expect_success 'shared: remove redundant packs, no packs left' '
|
|
(
|
|
cd "$shared_repo" &&
|
|
cat >expect <<-EOF &&
|
|
fatal: Zero packs found!
|
|
EOF
|
|
$git_pack_redundant --all --alt-odb | xargs rm &&
|
|
git fsck &&
|
|
test_must_fail $git_pack_redundant --all --alt-odb >actual 2>&1 &&
|
|
test_cmp expect actual
|
|
)
|
|
'
|
|
|
|
test_expect_success 'shared: create new objects and packs' '
|
|
create_commits_in "$shared_repo" X Y Z &&
|
|
create_pack_in "$shared_repo" Px1 <<-EOF &&
|
|
$X
|
|
$Y
|
|
$Z
|
|
$A
|
|
$B
|
|
$C
|
|
EOF
|
|
create_pack_in "$shared_repo" Px2 <<-EOF
|
|
$X
|
|
$Y
|
|
$Z
|
|
$D
|
|
$E
|
|
$F
|
|
EOF
|
|
'
|
|
|
|
test_expect_success 'shared: no redundant without --alt-odb' '
|
|
(
|
|
cd "$shared_repo" &&
|
|
$git_pack_redundant --all >out &&
|
|
test_must_be_empty out
|
|
)
|
|
'
|
|
|
|
#############################################################################
|
|
# Chart of packs and objects for this test case
|
|
#
|
|
# ================= main.git ================
|
|
# | T A B C D E F G H I J K L M N O P Q R <----------------+
|
|
# ----+-------------------------------------- |
|
|
# P1 | x x x x x x x x |
|
|
# P3 | x x x x x x |
|
|
# P5 | x x x x |
|
|
# P7 | x x |
|
|
# ----+-------------------------------------- |
|
|
# ALL | x x x x x x x x x x x x x x x x x x x |
|
|
# |
|
|
# |
|
|
# ================ shared.git ======================= |
|
|
# | T A B C D E F G H I J K L M N O P Q R X Y Z <objects/info/alternates>
|
|
# ----+----------------------------------------------
|
|
# Px1 | s s s x x x
|
|
# Px2*| s s s ! ! !
|
|
# ----+----------------------------------------------
|
|
# ALL | s s s s s s s s s s s s s s s s s s s x x x
|
|
#
|
|
#############################################################################
|
|
test_expect_success 'shared: one pack is redundant with --alt-odb' '
|
|
(
|
|
cd "$shared_repo" &&
|
|
$git_pack_redundant --all --alt-odb >out &&
|
|
format_packfiles <out >actual &&
|
|
test_line_count = 1 actual
|
|
)
|
|
'
|
|
|
|
#############################################################################
|
|
# Chart of packs and objects for this test case
|
|
#
|
|
# ================= main.git ================
|
|
# | T A B C D E F G H I J K L M N O P Q R <----------------+
|
|
# ----+-------------------------------------- |
|
|
# P1 | x x x x x x x x |
|
|
# P3 | x x x x x x |
|
|
# P5 | x x x x |
|
|
# P7 | x x |
|
|
# ----+-------------------------------------- |
|
|
# ALL | x x x x x x x x x x x x x x x x x x x |
|
|
# |
|
|
# |
|
|
# ================ shared.git ======================= |
|
|
# | T A B C D E F G H I J K L M N O P Q R X Y Z <objects/info/alternates>
|
|
# ----+----------------------------------------------
|
|
# Px1*| s s s i i i
|
|
# Px2*| s s s i i i
|
|
# ----+----------------------------------------------
|
|
# ALL | s s s s s s s s s s s s s s s s s s s i i i
|
|
# (ignored objects, marked with i)
|
|
#
|
|
#############################################################################
|
|
test_expect_success 'shared: ignore unique objects and all two packs are redundant' '
|
|
(
|
|
cd "$shared_repo" &&
|
|
cat >expect <<-EOF &&
|
|
Px1:$Px1
|
|
Px2:$Px2
|
|
EOF
|
|
$git_pack_redundant --all --alt-odb >out <<-EOF &&
|
|
$X
|
|
$Y
|
|
$Z
|
|
EOF
|
|
format_packfiles <out >actual &&
|
|
test_cmp expect actual
|
|
)
|
|
'
|
|
|
|
test_done
|