1#!/bin/sh 2# 3# Copyright (c) 2018 Jiang Xin 4# 5 6test_description='Test git pack-redundant 7 8In order to test git-pack-redundant, we will create a number of objects and 9packs in the repository `master.git`. The relationship between packs (P1-P8) 10and objects (T, A-R) is showed in the following chart. Objects of a pack will 11be marked with letter x, while objects of redundant packs will be marked with 12exclamation point, and redundant pack itself will be marked with asterisk. 13 14 | T A B C D E F G H I J K L M N O P Q R 15 ----+-------------------------------------- 16 P1 | x x x x x x x x 17 P2* | ! ! ! ! ! ! ! 18 P3 | x x x x x x 19 P4* | ! ! ! ! ! 20 P5 | x x x x 21 P6* | ! ! ! 22 P7 | x x 23 P8* | ! 24 ----+-------------------------------------- 25 ALL | x x x x x x x x x x x x x x x x x x x 26 27Another repository `shared.git` has unique objects (X-Z), while other objects 28(marked with letter s) are shared through alt-odb (of `master.git`). The 29relationship between packs and objects is as follows: 30 31 | T A B C D E F G H I J K L M N O P Q R X Y Z 32 ----+---------------------------------------------- 33 Px1 | s s s x x x 34 Px2 | s s s x x x 35' 36 37. ./test-lib.sh 38 39master_repo=master.git 40shared_repo=shared.git 41 42# Create commits in <repo> and assign each commit's oid to shell variables 43# given in the arguments (A, B, and C). E.g.: 44# 45# create_commits_in <repo> A B C 46# 47# NOTE: Avoid calling this function from a subshell since variable 48# assignments will disappear when subshell exits. 49create_commits_in () { 50 repo="$1"&& 51if! parent=$(git -C "$repo" rev-parse HEAD^{} 2>/dev/null) 52then 53 parent= 54fi&& 55 T=$(git -C "$repo" write-tree)&& 56shift&& 57whiletest$#-gt0 58do 59 name=$1&& 60 test_tick && 61iftest -z"$parent" 62then 63 oid=$(echo $name | git -C "$repo" commit-tree $T) 64else 65 oid=$(echo $name | git -C "$repo" commit-tree -p $parent $T) 66fi&& 67eval$name=$oid&& 68 parent=$oid&& 69shift|| 70return1 71done&& 72 git -C"$repo" update-ref refs/heads/master $oid 73} 74 75# Create pack in <repo> and assign pack id to variable given in the 2nd argument 76# (<name>). Commits in the pack will be read from stdin. E.g.: 77# 78# create_pack_in <repo> <name> <<-EOF 79# ... 80# EOF 81# 82# NOTE: commits from stdin should be given using heredoc, not using pipe, and 83# avoid calling this function from a subshell since variable assignments will 84# disappear when subshell exits. 85create_pack_in () { 86 repo="$1"&& 87 name="$2"&& 88 pack=$(git -C "$repo/objects/pack" pack-objects -q pack)&& 89eval$name=$pack&& 90eval P$pack=$name:$pack 91} 92 93format_packfiles () { 94sed \ 95-e"s#.*/pack-\(.*\)\.idx#\1#" \ 96-e"s#.*/pack-\(.*\)\.pack#\1#"| 97sort-u| 98whileread p 99do 100iftest -z"$(eval echo \${P$p})" 101then 102echo$p 103else 104eval echo"\${P$p}" 105fi 106done| 107sort 108} 109 110test_expect_success 'setup master repo'' 111 git init --bare "$master_repo" && 112 create_commits_in "$master_repo" A B C D E F G H I J K L M N O P Q R 113' 114 115############################################################################# 116# Chart of packs and objects for this test case 117# 118# | T A B C D E F G H I J K L M N O P Q R 119# ----+-------------------------------------- 120# P1 | x x x x x x x x 121# P2 | x x x x x x x 122# P3 | x x x x x x 123# ----+-------------------------------------- 124# ALL | x x x x x x x x x x x x x x x 125# 126############################################################################# 127test_expect_success 'master: no redundant for pack 1, 2, 3'' 128 create_pack_in "$master_repo" P1 <<-EOF && 129$T 130$A 131$B 132$C 133$D 134$E 135$F 136$R 137 EOF 138 create_pack_in "$master_repo" P2 <<-EOF && 139$B 140$C 141$D 142$E 143$G 144$H 145$I 146 EOF 147 create_pack_in "$master_repo" P3 <<-EOF && 148$F 149$I 150$J 151$K 152$L 153$M 154 EOF 155 ( 156 cd "$master_repo" && 157 git pack-redundant --all >out && 158 test_must_be_empty out 159 ) 160' 161 162############################################################################# 163# Chart of packs and objects for this test case 164# 165# | T A B C D E F G H I J K L M N O P Q R 166# ----+-------------------------------------- 167# P1 | x x x x x x x x 168# P2 | x x x x x x x 169# P3* | ! ! ! ! ! ! 170# P4 | x x x x x 171# P5 | x x x x 172# ----+-------------------------------------- 173# ALL | x x x x x x x x x x x x x x x x x x 174# 175############################################################################# 176test_expect_success 'master: one of pack-2/pack-3 is redundant'' 177 create_pack_in "$master_repo" P4 <<-EOF && 178$J 179$K 180$L 181$M 182$P 183 EOF 184 create_pack_in "$master_repo" P5 <<-EOF && 185$G 186$H 187$N 188$O 189 EOF 190 ( 191 cd "$master_repo" && 192 cat >expect <<-EOF && 193 P3:$P3 194 EOF 195 git pack-redundant --all >out && 196 format_packfiles <out >actual && 197 test_cmp expect actual 198 ) 199' 200 201############################################################################# 202# Chart of packs and objects for this test case 203# 204# | T A B C D E F G H I J K L M N O P Q R 205# ----+-------------------------------------- 206# P1 | x x x x x x x x 207# P2* | ! ! ! ! ! ! ! 208# P3 | x x x x x x 209# P4* | ! ! ! ! ! 210# P5 | x x x x 211# P6* | ! ! ! 212# P7 | x x 213# ----+-------------------------------------- 214# ALL | x x x x x x x x x x x x x x x x x x x 215# 216############################################################################# 217test_expect_success 'master: pack 2, 4, and 6 are redundant'' 218 create_pack_in "$master_repo" P6 <<-EOF && 219$N 220$O 221$Q 222 EOF 223 create_pack_in "$master_repo" P7 <<-EOF && 224$P 225$Q 226 EOF 227 ( 228 cd "$master_repo" && 229 cat >expect <<-EOF && 230 P2:$P2 231 P4:$P4 232 P6:$P6 233 EOF 234 git pack-redundant --all >out && 235 format_packfiles <out >actual && 236 test_cmp expect actual 237 ) 238' 239 240############################################################################# 241# Chart of packs and objects for this test case 242# 243# | T A B C D E F G H I J K L M N O P Q R 244# ----+-------------------------------------- 245# P1 | x x x x x x x x 246# P2* | ! ! ! ! ! ! ! 247# P3 | x x x x x x 248# P4* | ! ! ! ! ! 249# P5 | x x x x 250# P6* | ! ! ! 251# P7 | x x 252# P8* | ! 253# ----+-------------------------------------- 254# ALL | x x x x x x x x x x x x x x x x x x x 255# 256############################################################################# 257test_expect_success 'master: pack-8 (subset of pack-1) is also redundant'' 258 create_pack_in "$master_repo" P8 <<-EOF && 259$A 260 EOF 261 ( 262 cd "$master_repo" && 263 cat >expect <<-EOF && 264 P2:$P2 265 P4:$P4 266 P6:$P6 267 P8:$P8 268 EOF 269 git pack-redundant --all >out && 270 format_packfiles <out >actual && 271 test_cmp expect actual 272 ) 273' 274 275test_expect_success 'master: clean loose objects'' 276 ( 277 cd "$master_repo" && 278 git prune-packed && 279 find objects -type f | sed -e "/objects\/pack\//d" >out && 280 test_must_be_empty out 281 ) 282' 283 284test_expect_success 'master: remove redundant packs and pass fsck'' 285 ( 286 cd "$master_repo" && 287 git pack-redundant --all | xargs rm && 288 git fsck && 289 git pack-redundant --all >out && 290 test_must_be_empty out 291 ) 292' 293 294# The following test cases will execute inside `shared.git`, instead of 295# inside `master.git`. 296test_expect_success 'setup shared.git'' 297 git clone --mirror "$master_repo" "$shared_repo" && 298 ( 299 cd "$shared_repo" && 300 printf "../../$master_repo/objects\n" >objects/info/alternates 301 ) 302' 303 304test_expect_success 'shared: all packs are redundant, but no output without --alt-odb'' 305 ( 306 cd "$shared_repo" && 307 git pack-redundant --all >out && 308 test_must_be_empty out 309 ) 310' 311 312############################################################################# 313# Chart of packs and objects for this test case 314# 315# ================ master.git =============== 316# | T A B C D E F G H I J K L M N O P Q R <----------+ 317# ----+-------------------------------------- | 318# P1 | x x x x x x x x | 319# P3 | x x x x x x | 320# P5 | x x x x | 321# P7 | x x | 322# ----+-------------------------------------- | 323# ALL | x x x x x x x x x x x x x x x x x x x | 324# | 325# | 326# ================ shared.git =============== | 327# | T A B C D E F G H I J K L M N O P Q R <objects/info/alternates> 328# ----+-------------------------------------- 329# P1* | s s s s s s s s 330# P3* | s s s s s s 331# P5* | s s s s 332# P7* | s s 333# ----+-------------------------------------- 334# ALL | x x x x x x x x x x x x x x x x x x x 335# 336############################################################################# 337test_expect_success 'shared: show redundant packs in stderr for verbose mode'' 338 ( 339 cd "$shared_repo" && 340 cat >expect <<-EOF && 341 P1:$P1 342 P3:$P3 343 P5:$P5 344 P7:$P7 345 EOF 346 git pack-redundant --all --verbose >out 2>out.err && 347 test_must_be_empty out && 348 grep "pack$" out.err | format_packfiles >actual && 349 test_cmp expect actual 350 ) 351' 352 353test_expect_success 'shared: remove redundant packs, no packs left'' 354 ( 355 cd "$shared_repo" && 356 cat >expect <<-EOF && 357 fatal: Zero packs found! 358 EOF 359 git pack-redundant --all --alt-odb | xargs rm && 360 git fsck && 361 test_must_fail git pack-redundant --all --alt-odb >actual 2>&1 && 362 test_cmp expect actual 363 ) 364' 365 366test_expect_success 'shared: create new objects and packs'' 367 create_commits_in "$shared_repo" X Y Z && 368 create_pack_in "$shared_repo" Px1 <<-EOF && 369$X 370$Y 371$Z 372$A 373$B 374$C 375 EOF 376 create_pack_in "$shared_repo" Px2 <<-EOF 377$X 378$Y 379$Z 380$D 381$E 382$F 383 EOF 384' 385 386test_expect_success 'shared: no redundant without --alt-odb'' 387 ( 388 cd "$shared_repo" && 389 git pack-redundant --all >out && 390 test_must_be_empty out 391 ) 392' 393 394############################################################################# 395# Chart of packs and objects for this test case 396# 397# ================ master.git =============== 398# | T A B C D E F G H I J K L M N O P Q R <----------------+ 399# ----+-------------------------------------- | 400# P1 | x x x x x x x x | 401# P3 | x x x x x x | 402# P5 | x x x x | 403# P7 | x x | 404# ----+-------------------------------------- | 405# ALL | x x x x x x x x x x x x x x x x x x x | 406# | 407# | 408# ================ shared.git ======================= | 409# | 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> 410# ----+---------------------------------------------- 411# Px1 | s s s x x x 412# Px2*| s s s ! ! ! 413# ----+---------------------------------------------- 414# ALL | s s s s s s s s s s s s s s s s s s s x x x 415# 416############################################################################# 417test_expect_success 'shared: one pack is redundant with --alt-odb'' 418 ( 419 cd "$shared_repo" && 420 git pack-redundant --all --alt-odb >out && 421 format_packfiles <out >actual && 422 test_line_count = 1 actual 423 ) 424' 425 426############################################################################# 427# Chart of packs and objects for this test case 428# 429# ================ master.git =============== 430# | T A B C D E F G H I J K L M N O P Q R <----------------+ 431# ----+-------------------------------------- | 432# P1 | x x x x x x x x | 433# P3 | x x x x x x | 434# P5 | x x x x | 435# P7 | x x | 436# ----+-------------------------------------- | 437# ALL | x x x x x x x x x x x x x x x x x x x | 438# | 439# | 440# ================ shared.git ======================= | 441# | 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> 442# ----+---------------------------------------------- 443# Px1*| s s s i i i 444# Px2*| s s s i i i 445# ----+---------------------------------------------- 446# ALL | s s s s s s s s s s s s s s s s s s s i i i 447# (ignored objects, marked with i) 448# 449############################################################################# 450test_expect_success 'shared: ignore unique objects and all two packs are redundant'' 451 ( 452 cd "$shared_repo" && 453 cat >expect <<-EOF && 454 Px1:$Px1 455 Px2:$Px2 456 EOF 457 git pack-redundant --all --alt-odb >out <<-EOF && 458$X 459$Y 460$Z 461 EOF 462 format_packfiles <out >actual && 463 test_cmp expect actual 464 ) 465' 466 467test_done