Git fork
at reftables-rust 305 lines 8.3 kB view raw
1#!/bin/sh 2 3test_description='undoing resolution' 4 5GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main 6export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME 7 8. ./test-lib.sh 9 10check_resolve_undo () { 11 msg=$1 12 shift 13 while case $# in 14 0) break ;; 15 1|2|3) die "Bug in check-resolve-undo test" ;; 16 esac 17 do 18 path=$1 19 shift 20 for stage in 1 2 3 21 do 22 sha1=$1 23 shift 24 case "$sha1" in 25 '') continue ;; 26 esac 27 sha1=$(git rev-parse --verify "$sha1") 28 printf "100644 %s %s\t%s\n" $sha1 $stage $path 29 done 30 done >"$msg.expect" && 31 git ls-files --resolve-undo >"$msg.actual" && 32 test_cmp "$msg.expect" "$msg.actual" 33} 34 35prime_resolve_undo () { 36 git reset --hard && 37 git checkout second^0 && 38 test_tick && 39 test_must_fail git merge third^0 && 40 check_resolve_undo empty && 41 42 # how should the conflict be resolved? 43 case "$1" in 44 remove) 45 rm -f file/le && git rm fi/le 46 ;; 47 *) # modify 48 echo different >fi/le && git add fi/le 49 ;; 50 esac 51 check_resolve_undo recorded fi/le initial:fi/le second:fi/le third:fi/le 52} 53 54test_expect_success setup ' 55 mkdir fi && 56 printf "a\0a" >binary && 57 git add binary && 58 test_commit initial fi/le first && 59 git branch side && 60 git branch another && 61 printf "a\0b" >binary && 62 git add binary && 63 test_commit second fi/le second && 64 git checkout side && 65 test_commit third fi/le third && 66 git branch add-add && 67 git checkout another && 68 test_commit fourth fi/le fourth && 69 git checkout add-add && 70 test_commit fifth add-differently && 71 git checkout main 72' 73 74test_expect_success 'add records switch clears' ' 75 prime_resolve_undo && 76 test_tick && 77 git commit -m merged && 78 echo committing keeps && 79 check_resolve_undo kept fi/le initial:fi/le second:fi/le third:fi/le && 80 git checkout second^0 && 81 echo switching clears && 82 check_resolve_undo cleared 83' 84 85test_expect_success 'rm records reset clears' ' 86 prime_resolve_undo && 87 test_tick && 88 git commit -m merged && 89 echo committing keeps && 90 check_resolve_undo kept fi/le initial:fi/le second:fi/le third:fi/le && 91 92 echo merge clears upfront && 93 test_must_fail git merge fourth^0 && 94 check_resolve_undo nuked && 95 96 git rm -f fi/le && 97 echo resolving records && 98 check_resolve_undo recorded fi/le initial:fi/le HEAD:fi/le fourth:fi/le && 99 100 git reset --hard && 101 echo resetting discards && 102 check_resolve_undo discarded 103' 104 105test_expect_success 'plumbing clears' ' 106 prime_resolve_undo && 107 test_tick && 108 git commit -m merged && 109 echo committing keeps && 110 check_resolve_undo kept fi/le initial:fi/le second:fi/le third:fi/le && 111 112 echo plumbing clear && 113 git update-index --clear-resolve-undo && 114 check_resolve_undo cleared 115' 116 117test_expect_success 'add records checkout -m undoes' ' 118 prime_resolve_undo && 119 git diff HEAD && 120 git checkout --conflict=merge fi/le && 121 echo checkout used the record and removed it && 122 check_resolve_undo removed && 123 echo the index and the work tree is unmerged again && 124 git diff >actual && 125 grep "^++<<<<<<<" actual 126' 127 128test_expect_success 'unmerge with plumbing' ' 129 prime_resolve_undo && 130 git update-index --unresolve fi/le && 131 git ls-files --resolve-undo fi/le >actual && 132 test_must_be_empty actual && 133 git ls-files -u >actual && 134 test_line_count = 3 actual 135' 136 137test_expect_success 'unmerge can be done even after committing' ' 138 prime_resolve_undo && 139 git commit -m "record to nuke MERGE_HEAD" && 140 git update-index --unresolve fi/le && 141 git ls-files --resolve-undo fi/le >actual && 142 test_must_be_empty actual && 143 git ls-files -u >actual && 144 test_line_count = 3 actual 145' 146 147test_expect_success 'unmerge removal' ' 148 prime_resolve_undo remove && 149 git update-index --unresolve fi/le && 150 git ls-files --resolve-undo fi/le >actual && 151 test_must_be_empty actual && 152 git ls-files -u >actual && 153 test_line_count = 3 actual 154' 155 156test_expect_success 'unmerge removal after committing' ' 157 prime_resolve_undo remove && 158 git commit -m "record to nuke MERGE_HEAD" && 159 git update-index --unresolve fi/le && 160 git ls-files --resolve-undo fi/le >actual && 161 test_must_be_empty actual && 162 git ls-files -u >actual && 163 test_line_count = 3 actual 164' 165 166test_expect_success 'rerere and rerere forget' ' 167 mkdir .git/rr-cache && 168 prime_resolve_undo && 169 echo record the resolution && 170 git rerere && 171 rerere_id=$(cd .git/rr-cache && echo */postimage) && 172 rerere_id=${rerere_id%/postimage} && 173 test -f .git/rr-cache/$rerere_id/postimage && 174 git checkout -m fi/le && 175 echo resurrect the conflict && 176 grep "^=======" fi/le && 177 echo reresolve the conflict && 178 git rerere && 179 test "z$(cat fi/le)" = zdifferent && 180 echo register the resolution again && 181 git add fi/le && 182 check_resolve_undo kept fi/le initial:fi/le second:fi/le third:fi/le && 183 test -z "$(git ls-files -u)" && 184 git rerere forget fi/le && 185 ! test -f .git/rr-cache/$rerere_id/postimage && 186 tr "\0" "\n" <.git/MERGE_RR >actual && 187 echo "$rerere_id fi/le" >expect && 188 test_cmp expect actual 189' 190 191test_expect_success 'rerere and rerere forget (subdirectory)' ' 192 rm -fr .git/rr-cache && 193 mkdir .git/rr-cache && 194 prime_resolve_undo && 195 echo record the resolution && 196 (cd fi && git rerere) && 197 rerere_id=$(cd .git/rr-cache && echo */postimage) && 198 rerere_id=${rerere_id%/postimage} && 199 test -f .git/rr-cache/$rerere_id/postimage && 200 (cd fi && git checkout -m le) && 201 echo resurrect the conflict && 202 grep "^=======" fi/le && 203 echo reresolve the conflict && 204 (cd fi && git rerere) && 205 test "z$(cat fi/le)" = zdifferent && 206 echo register the resolution again && 207 (cd fi && git add le) && 208 check_resolve_undo kept fi/le initial:fi/le second:fi/le third:fi/le && 209 test -z "$(git ls-files -u)" && 210 (cd fi && git rerere forget le) && 211 ! test -f .git/rr-cache/$rerere_id/postimage && 212 tr "\0" "\n" <.git/MERGE_RR >actual && 213 echo "$rerere_id fi/le" >expect && 214 test_cmp expect actual 215' 216 217test_expect_success 'rerere forget (binary)' ' 218 git checkout -f side && 219 test_commit --printf binary binary "a\0c" && 220 test_must_fail git merge second && 221 git rerere forget binary 222' 223 224test_expect_success 'rerere forget (add-add conflict)' ' 225 git checkout -f main && 226 echo main >add-differently && 227 git add add-differently && 228 git commit -m "add differently" && 229 test_must_fail git merge fifth && 230 git rerere forget add-differently 2>actual && 231 test_grep "no remembered" actual 232' 233 234test_expect_success 'resolve-undo keeps blobs from gc' ' 235 git checkout -f main && 236 237 # First make sure we do not have any cruft left in the object store 238 git repack -a -d && 239 git prune --expire=now && 240 git prune-packed && 241 git gc --prune=now && 242 git fsck --unreachable >cruft && 243 test_must_be_empty cruft && 244 245 # Now add three otherwise unreferenced blob objects to the index 246 git reset --hard && 247 B1=$(echo "resolve undo test data 1" | git hash-object -w --stdin) && 248 B2=$(echo "resolve undo test data 2" | git hash-object -w --stdin) && 249 B3=$(echo "resolve undo test data 3" | git hash-object -w --stdin) && 250 git update-index --add --index-info <<-EOF && 251 100644 $B1 1 frotz 252 100644 $B2 2 frotz 253 100644 $B3 3 frotz 254 EOF 255 256 # These three blob objects are reachable (only) from the index 257 git fsck --unreachable >cruft && 258 test_must_be_empty cruft && 259 # and they should be protected from GC 260 git gc --prune=now && 261 git cat-file -e $B1 && 262 git cat-file -e $B2 && 263 git cat-file -e $B3 && 264 265 # Now resolve the conflicted path 266 B0=$(echo "resolve undo test data 0" | git hash-object -w --stdin) && 267 git update-index --add --cacheinfo 100644,$B0,frotz && 268 269 # These three blob objects are now reachable only from the resolve-undo 270 git fsck --unreachable >cruft && 271 test_must_be_empty cruft && 272 273 # and they should survive GC 274 git gc --prune=now && 275 git cat-file -e $B0 && 276 git cat-file -e $B1 && 277 git cat-file -e $B2 && 278 git cat-file -e $B3 && 279 280 # Now we switch away, which nukes resolve-undo, and 281 # blobs B0..B3 would become dangling. fsck should 282 # notice that they are now unreachable. 283 git checkout -f side && 284 git fsck --unreachable >cruft && 285 sort cruft >actual && 286 sort <<-EOF >expect && 287 unreachable blob $B0 288 unreachable blob $B1 289 unreachable blob $B2 290 unreachable blob $B3 291 EOF 292 test_cmp expect actual && 293 294 # And they should go away when gc runs. 295 git gc --prune=now && 296 git fsck --unreachable >cruft && 297 test_must_be_empty cruft && 298 299 test_must_fail git cat-file -e $B0 && 300 test_must_fail git cat-file -e $B1 && 301 test_must_fail git cat-file -e $B2 && 302 test_must_fail git cat-file -e $B3 303' 304 305test_done