Git fork
at reftables-rust 197 lines 6.3 kB view raw
1#!/bin/sh 2 3# NOTICE: 4# This testsuite does a number of diffs and checks that the output match. 5# However, it is a "garbage in, garbage out" situation; the trees have 6# duplicate entries for individual paths, and it results in diffs that do 7# not make much sense. As such, it is not clear that the diffs are 8# "correct". The primary purpose of these tests was to verify that 9# diff-tree does not segfault, but there is perhaps some value in ensuring 10# that the diff output isn't wildly unreasonable. 11 12test_description='test tree diff when trees have duplicate entries' 13 14. ./test-lib.sh 15 16if ! test_have_prereq PERL_TEST_HELPERS 17then 18 skip_all='skipping diff duplicates tests; Perl not available' 19 test_done 20fi 21 22# make_tree_entry <mode> <mode> <sha1> 23# 24# We have to rely on perl here because not all printfs understand 25# hex escapes (only octal), and xxd is not portable. 26make_tree_entry () { 27 printf '%s %s\0' "$1" "$2" && 28 perl -e 'print chr(hex($_)) for ($ARGV[0] =~ /../g)' "$3" 29} 30 31# Like git-mktree, but without all of the pesky sanity checking. 32# Arguments come in groups of three, each group specifying a single 33# tree entry (see make_tree_entry above). 34make_tree () { 35 while test $# -gt 2; do 36 make_tree_entry "$1" "$2" "$3" 37 shift; shift; shift 38 done | 39 git hash-object --literally -w -t tree --stdin 40} 41 42# this is kind of a convoluted setup, but matches 43# a real-world case. Each tree contains four entries 44# for the given path, one with one sha1, and three with 45# the other. The first tree has them split across 46# two subtrees (which are themselves duplicate entries in 47# the root tree), and the second has them all in a single subtree. 48test_expect_success 'create trees with duplicate entries' ' 49 blob_one=$(echo one | git hash-object -w --stdin) && 50 blob_two=$(echo two | git hash-object -w --stdin) && 51 inner_one_a=$(make_tree \ 52 100644 inner $blob_one 53 ) && 54 inner_one_b=$(make_tree \ 55 100644 inner $blob_two \ 56 100644 inner $blob_two \ 57 100644 inner $blob_two 58 ) && 59 outer_one=$(make_tree \ 60 040000 outer $inner_one_a \ 61 040000 outer $inner_one_b 62 ) && 63 inner_two=$(make_tree \ 64 100644 inner $blob_one \ 65 100644 inner $blob_two \ 66 100644 inner $blob_two \ 67 100644 inner $blob_two 68 ) && 69 outer_two=$(make_tree \ 70 040000 outer $inner_two 71 ) && 72 git tag one $outer_one && 73 git tag two $outer_two 74' 75 76test_expect_success 'create tree without duplicate entries' ' 77 blob_one=$(echo one | git hash-object -w --stdin) && 78 outer_three=$(make_tree \ 79 100644 renamed $blob_one 80 ) && 81 git tag three $outer_three 82' 83 84test_expect_success 'diff-tree between duplicate trees' ' 85 # See NOTICE at top of file 86 { 87 printf ":000000 100644 $ZERO_OID $blob_two A\touter/inner\n" && 88 printf ":000000 100644 $ZERO_OID $blob_two A\touter/inner\n" && 89 printf ":000000 100644 $ZERO_OID $blob_two A\touter/inner\n" && 90 printf ":100644 000000 $blob_two $ZERO_OID D\touter/inner\n" && 91 printf ":100644 000000 $blob_two $ZERO_OID D\touter/inner\n" && 92 printf ":100644 000000 $blob_two $ZERO_OID D\touter/inner\n" 93 } >expect && 94 git diff-tree -r --no-abbrev one two >actual && 95 test_cmp expect actual 96' 97 98test_expect_success 'diff-tree with renames' ' 99 # See NOTICE at top of file. 100 git diff-tree -M -r --no-abbrev one two >actual && 101 test_must_be_empty actual 102' 103 104test_expect_success 'diff-tree FROM duplicate tree' ' 105 # See NOTICE at top of file. 106 { 107 printf ":100644 000000 $blob_one $ZERO_OID D\touter/inner\n" && 108 printf ":100644 000000 $blob_two $ZERO_OID D\touter/inner\n" && 109 printf ":100644 000000 $blob_two $ZERO_OID D\touter/inner\n" && 110 printf ":100644 000000 $blob_two $ZERO_OID D\touter/inner\n" && 111 printf ":000000 100644 $ZERO_OID $blob_one A\trenamed\n" 112 } >expect && 113 git diff-tree -r --no-abbrev one three >actual && 114 test_cmp expect actual 115' 116 117test_expect_success 'diff-tree FROM duplicate tree, with renames' ' 118 # See NOTICE at top of file. 119 { 120 printf ":100644 000000 $blob_two $ZERO_OID D\touter/inner\n" && 121 printf ":100644 000000 $blob_two $ZERO_OID D\touter/inner\n" && 122 printf ":100644 000000 $blob_two $ZERO_OID D\touter/inner\n" && 123 printf ":100644 100644 $blob_one $blob_one R100\touter/inner\trenamed\n" 124 } >expect && 125 git diff-tree -M -r --no-abbrev one three >actual && 126 test_cmp expect actual 127' 128 129test_expect_success 'create a few commits' ' 130 git commit-tree -m "Duplicate Entries" two^{tree} >commit_id && 131 git branch base $(cat commit_id) && 132 133 git commit-tree -p $(cat commit_id) -m "Just one" three^{tree} >up && 134 git branch update $(cat up) && 135 136 git commit-tree -p $(cat up) -m "Back to weird" two^{tree} >final && 137 git branch final $(cat final) && 138 139 rm commit_id up final 140' 141 142test_expect_success 'git read-tree does not segfault' ' 143 test_must_fail git read-tree --reset base 2>err && 144 test_grep "error: corrupted cache-tree has entries not present in index" err 145' 146 147test_expect_success 'reset --hard does not segfault' ' 148 git checkout base && 149 test_must_fail git reset --hard 2>err && 150 test_grep "error: corrupted cache-tree has entries not present in index" err 151' 152 153test_expect_success 'git diff HEAD does not segfault' ' 154 git checkout base && 155 GIT_TEST_CHECK_CACHE_TREE=false && 156 git reset --hard && 157 test_must_fail git diff HEAD 2>err && 158 test_grep "error: corrupted cache-tree has entries not present in index" err 159' 160 161test_expect_failure 'can switch to another branch when status is empty' ' 162 git clean -ffdqx && 163 git status --porcelain -uno >actual && 164 test_must_be_empty actual && 165 git checkout update 166' 167 168test_expect_success 'forcibly switch to another branch, verify status empty' ' 169 git checkout -f update && 170 git status --porcelain -uno >actual && 171 test_must_be_empty actual 172' 173 174test_expect_success 'fast-forward from non-duplicate entries to duplicate' ' 175 git merge final 176' 177 178test_expect_failure 'clean status, switch branches, status still clean' ' 179 git status --porcelain -uno >actual && 180 test_must_be_empty actual && 181 git checkout base && 182 git status --porcelain -uno >actual && 183 test_must_be_empty actual 184' 185 186test_expect_success 'switch to base branch and force status to be clean' ' 187 git checkout base && 188 GIT_TEST_CHECK_CACHE_TREE=false git reset --hard && 189 git status --porcelain -uno >actual && 190 test_must_be_empty actual 191' 192 193test_expect_failure 'fast-forward from duplicate entries to non-duplicate' ' 194 git merge update 195' 196 197test_done