t / t5324-split-commit-graph.shon commit Merge branch 'bc/hash-independent-tests-part-4' (a7b27d9)
   1#!/bin/sh
   2
   3test_description='split commit graph'
   4. ./test-lib.sh
   5
   6GIT_TEST_COMMIT_GRAPH=0
   7
   8test_expect_success 'setup repo' '
   9        git init &&
  10        git config core.commitGraph true &&
  11        infodir=".git/objects/info" &&
  12        graphdir="$infodir/commit-graphs" &&
  13        test_oid_init
  14'
  15
  16graph_read_expect() {
  17        NUM_BASE=0
  18        if test ! -z $2
  19        then
  20                NUM_BASE=$2
  21        fi
  22        cat >expect <<- EOF
  23        header: 43475048 1 1 3 $NUM_BASE
  24        num_commits: $1
  25        chunks: oid_fanout oid_lookup commit_metadata
  26        EOF
  27        git commit-graph read >output &&
  28        test_cmp expect output
  29}
  30
  31test_expect_success 'create commits and write commit-graph' '
  32        for i in $(test_seq 3)
  33        do
  34                test_commit $i &&
  35                git branch commits/$i || return 1
  36        done &&
  37        git commit-graph write --reachable &&
  38        test_path_is_file $infodir/commit-graph &&
  39        graph_read_expect 3
  40'
  41
  42graph_git_two_modes() {
  43        git -c core.commitGraph=true $1 >output
  44        git -c core.commitGraph=false $1 >expect
  45        test_cmp expect output
  46}
  47
  48graph_git_behavior() {
  49        MSG=$1
  50        BRANCH=$2
  51        COMPARE=$3
  52        test_expect_success "check normal git operations: $MSG" '
  53                graph_git_two_modes "log --oneline $BRANCH" &&
  54                graph_git_two_modes "log --topo-order $BRANCH" &&
  55                graph_git_two_modes "log --graph $COMPARE..$BRANCH" &&
  56                graph_git_two_modes "branch -vv" &&
  57                graph_git_two_modes "merge-base -a $BRANCH $COMPARE"
  58        '
  59}
  60
  61graph_git_behavior 'graph exists' commits/3 commits/1
  62
  63verify_chain_files_exist() {
  64        for hash in $(cat $1/commit-graph-chain)
  65        do
  66                test_path_is_file $1/graph-$hash.graph || return 1
  67        done
  68}
  69
  70test_expect_success 'add more commits, and write a new base graph' '
  71        git reset --hard commits/1 &&
  72        for i in $(test_seq 4 5)
  73        do
  74                test_commit $i &&
  75                git branch commits/$i || return 1
  76        done &&
  77        git reset --hard commits/2 &&
  78        for i in $(test_seq 6 10)
  79        do
  80                test_commit $i &&
  81                git branch commits/$i || return 1
  82        done &&
  83        git reset --hard commits/2 &&
  84        git merge commits/4 &&
  85        git branch merge/1 &&
  86        git reset --hard commits/4 &&
  87        git merge commits/6 &&
  88        git branch merge/2 &&
  89        git commit-graph write --reachable &&
  90        graph_read_expect 12
  91'
  92
  93test_expect_success 'fork and fail to base a chain on a commit-graph file' '
  94        test_when_finished rm -rf fork &&
  95        git clone . fork &&
  96        (
  97                cd fork &&
  98                rm .git/objects/info/commit-graph &&
  99                echo "$(pwd)/../.git/objects" >.git/objects/info/alternates &&
 100                test_commit new-commit &&
 101                git commit-graph write --reachable --split &&
 102                test_path_is_file $graphdir/commit-graph-chain &&
 103                test_line_count = 1 $graphdir/commit-graph-chain &&
 104                verify_chain_files_exist $graphdir
 105        )
 106'
 107
 108test_expect_success 'add three more commits, write a tip graph' '
 109        git reset --hard commits/3 &&
 110        git merge merge/1 &&
 111        git merge commits/5 &&
 112        git merge merge/2 &&
 113        git branch merge/3 &&
 114        git commit-graph write --reachable --split &&
 115        test_path_is_missing $infodir/commit-graph &&
 116        test_path_is_file $graphdir/commit-graph-chain &&
 117        ls $graphdir/graph-*.graph >graph-files &&
 118        test_line_count = 2 graph-files &&
 119        verify_chain_files_exist $graphdir
 120'
 121
 122graph_git_behavior 'split commit-graph: merge 3 vs 2' merge/3 merge/2
 123
 124test_expect_success 'add one commit, write a tip graph' '
 125        test_commit 11 &&
 126        git branch commits/11 &&
 127        git commit-graph write --reachable --split &&
 128        test_path_is_missing $infodir/commit-graph &&
 129        test_path_is_file $graphdir/commit-graph-chain &&
 130        ls $graphdir/graph-*.graph >graph-files &&
 131        test_line_count = 3 graph-files &&
 132        verify_chain_files_exist $graphdir
 133'
 134
 135graph_git_behavior 'three-layer commit-graph: commit 11 vs 6' commits/11 commits/6
 136
 137test_expect_success 'add one commit, write a merged graph' '
 138        test_commit 12 &&
 139        git branch commits/12 &&
 140        git commit-graph write --reachable --split &&
 141        test_path_is_file $graphdir/commit-graph-chain &&
 142        test_line_count = 2 $graphdir/commit-graph-chain &&
 143        ls $graphdir/graph-*.graph >graph-files &&
 144        test_line_count = 2 graph-files &&
 145        verify_chain_files_exist $graphdir
 146'
 147
 148graph_git_behavior 'merged commit-graph: commit 12 vs 6' commits/12 commits/6
 149
 150test_expect_success 'create fork and chain across alternate' '
 151        git clone . fork &&
 152        (
 153                cd fork &&
 154                git config core.commitGraph true &&
 155                rm -rf $graphdir &&
 156                echo "$(pwd)/../.git/objects" >.git/objects/info/alternates &&
 157                test_commit 13 &&
 158                git branch commits/13 &&
 159                git commit-graph write --reachable --split &&
 160                test_path_is_file $graphdir/commit-graph-chain &&
 161                test_line_count = 3 $graphdir/commit-graph-chain &&
 162                ls $graphdir/graph-*.graph >graph-files &&
 163                test_line_count = 1 graph-files &&
 164                git -c core.commitGraph=true  rev-list HEAD >expect &&
 165                git -c core.commitGraph=false rev-list HEAD >actual &&
 166                test_cmp expect actual &&
 167                test_commit 14 &&
 168                git commit-graph write --reachable --split --object-dir=.git/objects/ &&
 169                test_line_count = 3 $graphdir/commit-graph-chain &&
 170                ls $graphdir/graph-*.graph >graph-files &&
 171                test_line_count = 1 graph-files
 172        )
 173'
 174
 175graph_git_behavior 'alternate: commit 13 vs 6' commits/13 commits/6
 176
 177test_expect_success 'test merge stragety constants' '
 178        git clone . merge-2 &&
 179        (
 180                cd merge-2 &&
 181                git config core.commitGraph true &&
 182                test_line_count = 2 $graphdir/commit-graph-chain &&
 183                test_commit 14 &&
 184                git commit-graph write --reachable --split --size-multiple=2 &&
 185                test_line_count = 3 $graphdir/commit-graph-chain
 186
 187        ) &&
 188        git clone . merge-10 &&
 189        (
 190                cd merge-10 &&
 191                git config core.commitGraph true &&
 192                test_line_count = 2 $graphdir/commit-graph-chain &&
 193                test_commit 14 &&
 194                git commit-graph write --reachable --split --size-multiple=10 &&
 195                test_line_count = 1 $graphdir/commit-graph-chain &&
 196                ls $graphdir/graph-*.graph >graph-files &&
 197                test_line_count = 1 graph-files
 198        ) &&
 199        git clone . merge-10-expire &&
 200        (
 201                cd merge-10-expire &&
 202                git config core.commitGraph true &&
 203                test_line_count = 2 $graphdir/commit-graph-chain &&
 204                test_commit 15 &&
 205                git commit-graph write --reachable --split --size-multiple=10 --expire-time=1980-01-01 &&
 206                test_line_count = 1 $graphdir/commit-graph-chain &&
 207                ls $graphdir/graph-*.graph >graph-files &&
 208                test_line_count = 3 graph-files
 209        ) &&
 210        git clone --no-hardlinks . max-commits &&
 211        (
 212                cd max-commits &&
 213                git config core.commitGraph true &&
 214                test_line_count = 2 $graphdir/commit-graph-chain &&
 215                test_commit 16 &&
 216                test_commit 17 &&
 217                git commit-graph write --reachable --split --max-commits=1 &&
 218                test_line_count = 1 $graphdir/commit-graph-chain &&
 219                ls $graphdir/graph-*.graph >graph-files &&
 220                test_line_count = 1 graph-files
 221        )
 222'
 223
 224test_expect_success 'remove commit-graph-chain file after flattening' '
 225        git clone . flatten &&
 226        (
 227                cd flatten &&
 228                test_line_count = 2 $graphdir/commit-graph-chain &&
 229                git commit-graph write --reachable &&
 230                test_path_is_missing $graphdir/commit-graph-chain &&
 231                ls $graphdir >graph-files &&
 232                test_line_count = 0 graph-files
 233        )
 234'
 235
 236corrupt_file() {
 237        file=$1
 238        pos=$2
 239        data="${3:-\0}"
 240        chmod a+w "$file" &&
 241        printf "$data" | dd of="$file" bs=1 seek="$pos" conv=notrunc
 242}
 243
 244test_expect_success 'verify hashes along chain, even in shallow' '
 245        git clone --no-hardlinks . verify &&
 246        (
 247                cd verify &&
 248                git commit-graph verify &&
 249                base_file=$graphdir/graph-$(head -n 1 $graphdir/commit-graph-chain).graph &&
 250                corrupt_file "$base_file" 1760 "\01" &&
 251                test_must_fail git commit-graph verify --shallow 2>test_err &&
 252                grep -v "^+" test_err >err &&
 253                test_i18ngrep "incorrect checksum" err
 254        )
 255'
 256
 257test_expect_success 'verify --shallow does not check base contents' '
 258        git clone --no-hardlinks . verify-shallow &&
 259        (
 260                cd verify-shallow &&
 261                git commit-graph verify &&
 262                base_file=$graphdir/graph-$(head -n 1 $graphdir/commit-graph-chain).graph &&
 263                corrupt_file "$base_file" 1000 "\01" &&
 264                git commit-graph verify --shallow &&
 265                test_must_fail git commit-graph verify 2>test_err &&
 266                grep -v "^+" test_err >err &&
 267                test_i18ngrep "incorrect checksum" err
 268        )
 269'
 270
 271test_expect_success 'warn on base graph chunk incorrect' '
 272        git clone --no-hardlinks . base-chunk &&
 273        (
 274                cd base-chunk &&
 275                git commit-graph verify &&
 276                base_file=$graphdir/graph-$(tail -n 1 $graphdir/commit-graph-chain).graph &&
 277                corrupt_file "$base_file" 1376 "\01" &&
 278                git commit-graph verify --shallow 2>test_err &&
 279                grep -v "^+" test_err >err &&
 280                test_i18ngrep "commit-graph chain does not match" err
 281        )
 282'
 283
 284test_expect_success 'verify after commit-graph-chain corruption' '
 285        git clone --no-hardlinks . verify-chain &&
 286        (
 287                cd verify-chain &&
 288                corrupt_file "$graphdir/commit-graph-chain" 60 "G" &&
 289                git commit-graph verify 2>test_err &&
 290                grep -v "^+" test_err >err &&
 291                test_i18ngrep "invalid commit-graph chain" err &&
 292                corrupt_file "$graphdir/commit-graph-chain" 60 "A" &&
 293                git commit-graph verify 2>test_err &&
 294                grep -v "^+" test_err >err &&
 295                test_i18ngrep "unable to find all commit-graph files" err
 296        )
 297'
 298
 299test_expect_success 'verify across alternates' '
 300        git clone --no-hardlinks . verify-alt &&
 301        (
 302                cd verify-alt &&
 303                rm -rf $graphdir &&
 304                altdir="$(pwd)/../.git/objects" &&
 305                echo "$altdir" >.git/objects/info/alternates &&
 306                git commit-graph verify --object-dir="$altdir/" &&
 307                test_commit extra &&
 308                git commit-graph write --reachable --split &&
 309                tip_file=$graphdir/graph-$(tail -n 1 $graphdir/commit-graph-chain).graph &&
 310                corrupt_file "$tip_file" 100 "\01" &&
 311                test_must_fail git commit-graph verify --shallow 2>test_err &&
 312                grep -v "^+" test_err >err &&
 313                test_i18ngrep "commit-graph has incorrect fanout value" err
 314        )
 315'
 316
 317test_expect_success 'add octopus merge' '
 318        git reset --hard commits/10 &&
 319        git merge commits/3 commits/4 &&
 320        git branch merge/octopus &&
 321        git commit-graph write --reachable --split &&
 322        git commit-graph verify &&
 323        test_line_count = 3 $graphdir/commit-graph-chain
 324'
 325
 326graph_git_behavior 'graph exists' merge/octopus commits/12
 327
 328test_expect_success 'split across alternate where alternate is not split' '
 329        git commit-graph write --reachable &&
 330        test_path_is_file .git/objects/info/commit-graph &&
 331        cp .git/objects/info/commit-graph . &&
 332        git clone --no-hardlinks . alt-split &&
 333        (
 334                cd alt-split &&
 335                echo "$(pwd)"/../.git/objects >.git/objects/info/alternates &&
 336                test_commit 18 &&
 337                git commit-graph write --reachable --split &&
 338                test_line_count = 1 $graphdir/commit-graph-chain
 339        ) &&
 340        test_cmp commit-graph .git/objects/info/commit-graph
 341'
 342
 343test_done