t / t5320-delta-islands.shon commit Merge branch 'sg/line-log-tree-diff-optim' (de67293)
   1#!/bin/sh
   2
   3test_description='exercise delta islands'
   4. ./test-lib.sh
   5
   6# returns true iff $1 is a delta based on $2
   7is_delta_base () {
   8        delta_base=$(echo "$1" | git cat-file --batch-check='%(deltabase)') &&
   9        echo >&2 "$1 has base $delta_base" &&
  10        test "$delta_base" = "$2"
  11}
  12
  13# generate a commit on branch $1 with a single file, "file", whose
  14# content is mostly based on the seed $2, but with a unique bit
  15# of content $3 appended. This should allow us to see whether
  16# blobs of different refs delta against each other.
  17commit() {
  18        blob=$({ test-tool genrandom "$2" 10240 && echo "$3"; } |
  19               git hash-object -w --stdin) &&
  20        tree=$(printf '100644 blob %s\tfile\n' "$blob" | git mktree) &&
  21        commit=$(echo "$2-$3" | git commit-tree "$tree" ${4:+-p "$4"}) &&
  22        git update-ref "refs/heads/$1" "$commit" &&
  23        eval "$1"'=$(git rev-parse $1:file)' &&
  24        eval "echo >&2 $1=\$$1"
  25}
  26
  27test_expect_success 'setup commits' '
  28        commit one seed 1 &&
  29        commit two seed 12
  30'
  31
  32# Note: This is heavily dependent on the "prefer larger objects as base"
  33# heuristic.
  34test_expect_success 'vanilla repack deltas one against two' '
  35        git repack -adf &&
  36        is_delta_base $one $two
  37'
  38
  39test_expect_success 'island repack with no island definition is vanilla' '
  40        git repack -adfi &&
  41        is_delta_base $one $two
  42'
  43
  44test_expect_success 'island repack with no matches is vanilla' '
  45        git -c "pack.island=refs/foo" repack -adfi &&
  46        is_delta_base $one $two
  47'
  48
  49test_expect_success 'separate islands disallows delta' '
  50        git -c "pack.island=refs/heads/(.*)" repack -adfi &&
  51        ! is_delta_base $one $two &&
  52        ! is_delta_base $two $one
  53'
  54
  55test_expect_success 'same island allows delta' '
  56        git -c "pack.island=refs/heads" repack -adfi &&
  57        is_delta_base $one $two
  58'
  59
  60test_expect_success 'coalesce same-named islands' '
  61        git \
  62                -c "pack.island=refs/(.*)/one" \
  63                -c "pack.island=refs/(.*)/two" \
  64                repack -adfi &&
  65        is_delta_base $one $two
  66'
  67
  68test_expect_success 'island restrictions drop reused deltas' '
  69        git repack -adfi &&
  70        is_delta_base $one $two &&
  71        git -c "pack.island=refs/heads/(.*)" repack -adi &&
  72        ! is_delta_base $one $two &&
  73        ! is_delta_base $two $one
  74'
  75
  76test_expect_success 'island regexes are left-anchored' '
  77        git -c "pack.island=heads/(.*)" repack -adfi &&
  78        is_delta_base $one $two
  79'
  80
  81test_expect_success 'island regexes follow last-one-wins scheme' '
  82        git \
  83                -c "pack.island=refs/heads/(.*)" \
  84                -c "pack.island=refs/heads/" \
  85                repack -adfi &&
  86        is_delta_base $one $two
  87'
  88
  89test_expect_success 'setup shared history' '
  90        commit root shared root &&
  91        commit one shared 1 root &&
  92        commit two shared 12-long root
  93'
  94
  95# We know that $two will be preferred as a base from $one,
  96# because we can transform it with a pure deletion.
  97#
  98# We also expect $root as a delta against $two by the "longest is base" rule.
  99test_expect_success 'vanilla delta goes between branches' '
 100        git repack -adf &&
 101        is_delta_base $one $two &&
 102        is_delta_base $root $two
 103'
 104
 105# Here we should allow $one to base itself on $root; even though
 106# they are in different islands, the objects in $root are in a superset
 107# of islands compared to those in $one.
 108#
 109# Similarly, $two can delta against $root by our rules. And unlike $one,
 110# in which we are just allowing it, the island rules actually put $root
 111# as a possible base for $two, which it would not otherwise be (due to the size
 112# sorting).
 113test_expect_success 'deltas allowed against superset islands' '
 114        git -c "pack.island=refs/heads/(.*)" repack -adfi &&
 115        is_delta_base $one $root &&
 116        is_delta_base $two $root
 117'
 118
 119# We are going to test the packfile order here, so we again have to make some
 120# assumptions. We assume that "$root", as part of our core "one", must come
 121# before "$two". This should be guaranteed by the island code. However, for
 122# this test to fail without islands, we are also assuming that it would not
 123# otherwise do so. This is true by the current write order, which will put
 124# commits (and their contents) before their parents.
 125test_expect_success 'island core places core objects first' '
 126        cat >expect <<-EOF &&
 127        $root
 128        $two
 129        EOF
 130        git -c "pack.island=refs/heads/(.*)" \
 131            -c "pack.islandcore=one" \
 132            repack -adfi &&
 133        git verify-pack -v .git/objects/pack/*.pack |
 134        cut -d" " -f1 |
 135        egrep "$root|$two" >actual &&
 136        test_cmp expect actual
 137'
 138
 139test_expect_success 'unmatched island core is not fatal' '
 140        git -c "pack.islandcore=one" repack -adfi
 141'
 142
 143test_done