t / t6002-rev-list-bisect.shon commit untracked-cache: be defensive about missing NULs in index (c6909f9)
   1#!/bin/sh
   2#
   3# Copyright (c) 2005 Jon Seymour
   4#
   5test_description='Tests git rev-list --bisect functionality'
   6
   7. ./test-lib.sh
   8. "$TEST_DIRECTORY"/lib-t6000.sh # t6xxx specific functions
   9
  10# usage: test_bisection max-diff bisect-option head ^prune...
  11#
  12# e.g. test_bisection 1 --bisect l1 ^l0
  13#
  14test_bisection_diff()
  15{
  16        _max_diff=$1
  17        _bisect_option=$2
  18        shift 2
  19        _bisection=$(git rev-list $_bisect_option "$@")
  20        _list_size=$(git rev-list "$@" | wc -l)
  21        _head=$1
  22        shift 1
  23        _bisection_size=$(git rev-list $_bisection "$@" | wc -l)
  24        [ -n "$_list_size" -a -n "$_bisection_size" ] ||
  25        error "test_bisection_diff failed"
  26
  27        # Test if bisection size is close to half of list size within
  28        # tolerance.
  29        #
  30        _bisect_err=$(expr $_list_size - $_bisection_size \* 2)
  31        test "$_bisect_err" -lt 0 && _bisect_err=$(expr 0 - $_bisect_err)
  32        _bisect_err=$(expr $_bisect_err / 2) ; # floor
  33
  34        test_expect_success \
  35        "bisection diff $_bisect_option $_head $* <= $_max_diff" \
  36        'test $_bisect_err -le $_max_diff'
  37}
  38
  39date >path0
  40git update-index --add path0
  41save_tag tree git write-tree
  42on_committer_date "00:00" hide_error save_tag root unique_commit root tree
  43on_committer_date "00:01" save_tag l0 unique_commit l0 tree -p root
  44on_committer_date "00:02" save_tag l1 unique_commit l1 tree -p l0
  45on_committer_date "00:03" save_tag l2 unique_commit l2 tree -p l1
  46on_committer_date "00:04" save_tag a0 unique_commit a0 tree -p l2
  47on_committer_date "00:05" save_tag a1 unique_commit a1 tree -p a0
  48on_committer_date "00:06" save_tag b1 unique_commit b1 tree -p a0
  49on_committer_date "00:07" save_tag c1 unique_commit c1 tree -p b1
  50on_committer_date "00:08" save_tag b2 unique_commit b2 tree -p b1
  51on_committer_date "00:09" save_tag b3 unique_commit b2 tree -p b2
  52on_committer_date "00:10" save_tag c2 unique_commit c2 tree -p c1 -p b2
  53on_committer_date "00:11" save_tag c3 unique_commit c3 tree -p c2
  54on_committer_date "00:12" save_tag a2 unique_commit a2 tree -p a1
  55on_committer_date "00:13" save_tag a3 unique_commit a3 tree -p a2
  56on_committer_date "00:14" save_tag b4 unique_commit b4 tree -p b3 -p a3
  57on_committer_date "00:15" save_tag a4 unique_commit a4 tree -p a3 -p b4 -p c3
  58on_committer_date "00:16" save_tag l3 unique_commit l3 tree -p a4
  59on_committer_date "00:17" save_tag l4 unique_commit l4 tree -p l3
  60on_committer_date "00:18" save_tag l5 unique_commit l5 tree -p l4
  61git update-ref HEAD $(tag l5)
  62
  63
  64#     E
  65#    / \
  66#   e1  |
  67#   |   |
  68#   e2  |
  69#   |   |
  70#   e3  |
  71#   |   |
  72#   e4  |
  73#   |   |
  74#   |   f1
  75#   |   |
  76#   |   f2
  77#   |   |
  78#   |   f3
  79#   |   |
  80#   |   f4
  81#   |   |
  82#   e5  |
  83#   |   |
  84#   e6  |
  85#   |   |
  86#   e7  |
  87#   |   |
  88#   e8  |
  89#    \ /
  90#     F
  91
  92
  93on_committer_date "00:00" hide_error save_tag F unique_commit F tree
  94on_committer_date "00:01" save_tag e8 unique_commit e8 tree -p F
  95on_committer_date "00:02" save_tag e7 unique_commit e7 tree -p e8
  96on_committer_date "00:03" save_tag e6 unique_commit e6 tree -p e7
  97on_committer_date "00:04" save_tag e5 unique_commit e5 tree -p e6
  98on_committer_date "00:05" save_tag f4 unique_commit f4 tree -p F
  99on_committer_date "00:06" save_tag f3 unique_commit f3 tree -p f4
 100on_committer_date "00:07" save_tag f2 unique_commit f2 tree -p f3
 101on_committer_date "00:08" save_tag f1 unique_commit f1 tree -p f2
 102on_committer_date "00:09" save_tag e4 unique_commit e4 tree -p e5
 103on_committer_date "00:10" save_tag e3 unique_commit e3 tree -p e4
 104on_committer_date "00:11" save_tag e2 unique_commit e2 tree -p e3
 105on_committer_date "00:12" save_tag e1 unique_commit e1 tree -p e2
 106on_committer_date "00:13" save_tag E unique_commit E tree -p e1 -p f1
 107
 108on_committer_date "00:00" hide_error save_tag U unique_commit U tree
 109on_committer_date "00:01" save_tag u0 unique_commit u0 tree -p U
 110on_committer_date "00:01" save_tag u1 unique_commit u1 tree -p u0
 111on_committer_date "00:02" save_tag u2 unique_commit u2 tree -p u0
 112on_committer_date "00:03" save_tag u3 unique_commit u3 tree -p u0
 113on_committer_date "00:04" save_tag u4 unique_commit u4 tree -p u0
 114on_committer_date "00:05" save_tag u5 unique_commit u5 tree -p u0
 115on_committer_date "00:06" save_tag V unique_commit V tree -p u1 -p u2 -p u3 -p u4 -p u5
 116
 117test_sequence()
 118{
 119        _bisect_option=$1
 120
 121        test_bisection_diff 0 $_bisect_option l0 ^root
 122        test_bisection_diff 0 $_bisect_option l1 ^root
 123        test_bisection_diff 0 $_bisect_option l2 ^root
 124        test_bisection_diff 0 $_bisect_option a0 ^root
 125        test_bisection_diff 0 $_bisect_option a1 ^root
 126        test_bisection_diff 0 $_bisect_option a2 ^root
 127        test_bisection_diff 0 $_bisect_option a3 ^root
 128        test_bisection_diff 0 $_bisect_option b1 ^root
 129        test_bisection_diff 0 $_bisect_option b2 ^root
 130        test_bisection_diff 0 $_bisect_option b3 ^root
 131        test_bisection_diff 0 $_bisect_option c1 ^root
 132        test_bisection_diff 0 $_bisect_option c2 ^root
 133        test_bisection_diff 0 $_bisect_option c3 ^root
 134        test_bisection_diff 0 $_bisect_option E ^F
 135        test_bisection_diff 0 $_bisect_option e1 ^F
 136        test_bisection_diff 0 $_bisect_option e2 ^F
 137        test_bisection_diff 0 $_bisect_option e3 ^F
 138        test_bisection_diff 0 $_bisect_option e4 ^F
 139        test_bisection_diff 0 $_bisect_option e5 ^F
 140        test_bisection_diff 0 $_bisect_option e6 ^F
 141        test_bisection_diff 0 $_bisect_option e7 ^F
 142        test_bisection_diff 0 $_bisect_option f1 ^F
 143        test_bisection_diff 0 $_bisect_option f2 ^F
 144        test_bisection_diff 0 $_bisect_option f3 ^F
 145        test_bisection_diff 0 $_bisect_option f4 ^F
 146        test_bisection_diff 0 $_bisect_option E ^F
 147
 148        test_bisection_diff 1 $_bisect_option V ^U
 149        test_bisection_diff 0 $_bisect_option V ^U ^u1 ^u2 ^u3
 150        test_bisection_diff 0 $_bisect_option u1 ^U
 151        test_bisection_diff 0 $_bisect_option u2 ^U
 152        test_bisection_diff 0 $_bisect_option u3 ^U
 153        test_bisection_diff 0 $_bisect_option u4 ^U
 154        test_bisection_diff 0 $_bisect_option u5 ^U
 155
 156#
 157# the following illustrates Linus' binary bug blatt idea.
 158#
 159# assume the bug is actually at l3, but you don't know that - all you know is that l3 is broken
 160# and it wasn't broken before
 161#
 162# keep bisecting the list, advancing the "bad" head and accumulating "good" heads until
 163# the bisection point is the head - this is the bad point.
 164#
 165
 166test_output_expect_success "$_bisect_option l5 ^root" 'git rev-list $_bisect_option l5 ^root' <<EOF
 167c3
 168EOF
 169
 170test_output_expect_success "$_bisect_option l5 ^root ^c3" 'git rev-list $_bisect_option l5 ^root ^c3' <<EOF
 171b4
 172EOF
 173
 174test_output_expect_success "$_bisect_option l5 ^root ^c3 ^b4" 'git rev-list $_bisect_option l5 ^c3 ^b4' <<EOF
 175l3
 176EOF
 177
 178test_output_expect_success "$_bisect_option l3 ^root ^c3 ^b4" 'git rev-list $_bisect_option l3 ^root ^c3 ^b4' <<EOF
 179a4
 180EOF
 181
 182test_output_expect_success "$_bisect_option l5 ^b3 ^a3 ^b4 ^a4" 'git rev-list $_bisect_option l3 ^b3 ^a3 ^a4' <<EOF
 183l3
 184EOF
 185
 186#
 187# if l3 is bad, then l4 is bad too - so advance the bad pointer by making b4 the known bad head
 188#
 189
 190test_output_expect_success "$_bisect_option l4 ^a2 ^a3 ^b ^a4" 'git rev-list $_bisect_option l4 ^a2 ^a3 ^a4' <<EOF
 191l3
 192EOF
 193
 194test_output_expect_success "$_bisect_option l3 ^a2 ^a3 ^b ^a4" 'git rev-list $_bisect_option l3 ^a2 ^a3 ^a4' <<EOF
 195l3
 196EOF
 197
 198# found!
 199
 200#
 201# as another example, let's consider a4 to be the bad head, in which case
 202#
 203
 204test_output_expect_success "$_bisect_option a4 ^a2 ^a3 ^b4" 'git rev-list $_bisect_option a4 ^a2 ^a3 ^b4' <<EOF
 205c2
 206EOF
 207
 208test_output_expect_success "$_bisect_option a4 ^a2 ^a3 ^b4 ^c2" 'git rev-list $_bisect_option a4 ^a2 ^a3 ^b4 ^c2' <<EOF
 209c3
 210EOF
 211
 212test_output_expect_success "$_bisect_option a4 ^a2 ^a3 ^b4 ^c2 ^c3" 'git rev-list $_bisect_option a4 ^a2 ^a3 ^b4 ^c2 ^c3' <<EOF
 213a4
 214EOF
 215
 216# found!
 217
 218#
 219# or consider c3 to be the bad head
 220#
 221
 222test_output_expect_success "$_bisect_option a4 ^a2 ^a3 ^b4" 'git rev-list $_bisect_option a4 ^a2 ^a3 ^b4' <<EOF
 223c2
 224EOF
 225
 226test_output_expect_success "$_bisect_option c3 ^a2 ^a3 ^b4 ^c2" 'git rev-list $_bisect_option c3 ^a2 ^a3 ^b4 ^c2' <<EOF
 227c3
 228EOF
 229
 230# found!
 231
 232}
 233
 234test_sequence "--bisect"
 235
 236#
 237#
 238
 239test_expect_success 'set up fake --bisect refs' '
 240        git update-ref refs/bisect/bad c3 &&
 241        good=$(git rev-parse b1) &&
 242        git update-ref refs/bisect/good-$good $good &&
 243        good=$(git rev-parse c1) &&
 244        git update-ref refs/bisect/good-$good $good
 245'
 246
 247test_expect_success 'rev-list --bisect can default to good/bad refs' '
 248        # the only thing between c3 and c1 is c2
 249        git rev-parse c2 >expect &&
 250        git rev-list --bisect >actual &&
 251        test_cmp expect actual
 252'
 253
 254test_expect_success 'rev-parse --bisect can default to good/bad refs' '
 255        git rev-parse c3 ^b1 ^c1 >expect &&
 256        git rev-parse --bisect >actual &&
 257
 258        # output order depends on the refnames, which in turn depends on
 259        # the exact sha1s. We just want to make sure we have the same set
 260        # of lines in any order.
 261        sort <expect >expect.sorted &&
 262        sort <actual >actual.sorted &&
 263        test_cmp expect.sorted actual.sorted
 264'
 265
 266test_done