Git fork
at reftables-rust 336 lines 8.8 kB view raw
1#!/bin/sh 2 3test_description='git apply --3way' 4 5GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main 6export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME 7 8. ./test-lib.sh 9 10print_sanitized_conflicted_diff () { 11 git diff HEAD >diff.raw && 12 sed -e ' 13 /^index /d 14 s/^\(+[<>|][<>|][<>|][<>|]*\) .*/\1/ 15 ' diff.raw 16} 17 18test_expect_success setup ' 19 test_tick && 20 test_write_lines 1 2 3 4 5 6 7 >one && 21 cat one >two && 22 git add one two && 23 git commit -m initial && 24 25 git branch side && 26 27 test_tick && 28 test_write_lines 1 two 3 4 5 six 7 >one && 29 test_write_lines 1 two 3 4 5 6 7 >two && 30 git commit -a -m main && 31 32 git checkout side && 33 test_write_lines 1 2 3 4 five 6 7 >one && 34 test_write_lines 1 2 3 4 five 6 7 >two && 35 git commit -a -m side && 36 37 git checkout main 38' 39 40test_expect_success 'apply without --3way' ' 41 git diff side^ side >P.diff && 42 43 # should fail to apply 44 git reset --hard && 45 git checkout main^0 && 46 test_must_fail git apply --index P.diff && 47 # should leave things intact 48 git diff-files --exit-code && 49 git diff-index --exit-code --cached HEAD 50' 51 52test_apply_with_3way () { 53 # Merging side should be similar to applying this patch 54 git diff ...side >P.diff && 55 56 # The corresponding conflicted merge 57 git reset --hard && 58 git checkout main^0 && 59 test_must_fail git merge --no-commit side && 60 git ls-files -s >expect.ls && 61 print_sanitized_conflicted_diff >expect.diff && 62 63 # should fail to apply 64 git reset --hard && 65 git checkout main^0 && 66 test_must_fail git apply --index --3way P.diff && 67 git ls-files -s >actual.ls && 68 print_sanitized_conflicted_diff >actual.diff && 69 70 # The result should resemble the corresponding merge 71 test_cmp expect.ls actual.ls && 72 test_cmp expect.diff actual.diff 73} 74 75test_expect_success 'apply with --3way' ' 76 test_apply_with_3way 77' 78 79test_expect_success 'apply with --3way with merge.conflictStyle = diff3' ' 80 test_config merge.conflictStyle diff3 && 81 test_apply_with_3way 82' 83 84test_apply_with_3way_favoritism () { 85 apply_arg=$1 86 merge_arg=$2 87 88 # Merging side should be similar to applying this patch 89 git diff ...side >P.diff && 90 91 # The corresponding conflicted merge 92 git reset --hard && 93 git checkout main^0 && 94 git merge --no-commit $merge_arg side && 95 git ls-files -s >expect.ls && 96 print_sanitized_conflicted_diff >expect.diff && 97 98 # should apply successfully 99 git reset --hard && 100 git checkout main^0 && 101 git apply --index --3way $apply_arg P.diff && 102 git ls-files -s >actual.ls && 103 print_sanitized_conflicted_diff >actual.diff && 104 105 # The result should resemble the corresponding merge 106 test_cmp expect.ls actual.ls && 107 test_cmp expect.diff actual.diff 108} 109 110test_expect_success 'apply with --3way --ours' ' 111 test_apply_with_3way_favoritism --ours -Xours 112' 113 114test_expect_success 'apply with --3way --theirs' ' 115 test_apply_with_3way_favoritism --theirs -Xtheirs 116' 117 118test_expect_success 'apply with --3way --union' ' 119 echo "* merge=union" >.gitattributes && 120 test_apply_with_3way_favoritism --union && 121 rm .gitattributes 122' 123 124test_expect_success 'apply with --3way with rerere enabled' ' 125 test_config rerere.enabled true && 126 127 # Merging side should be similar to applying this patch 128 git diff ...side >P.diff && 129 130 # The corresponding conflicted merge 131 git reset --hard && 132 git checkout main^0 && 133 test_must_fail git merge --no-commit side && 134 135 # Manually resolve and record the resolution 136 test_write_lines 1 two 3 4 five six 7 >one && 137 git rerere && 138 cat one >expect && 139 140 # should fail to apply 141 git reset --hard && 142 git checkout main^0 && 143 test_must_fail git apply --index --3way P.diff && 144 145 # but rerere should have replayed the recorded resolution 146 test_cmp expect one 147' 148 149test_expect_success 'apply -3 with add/add conflict setup' ' 150 git reset --hard && 151 152 git checkout -b adder && 153 test_write_lines 1 2 3 4 5 6 7 >three && 154 test_write_lines 1 2 3 4 5 6 7 >four && 155 git add three four && 156 git commit -m "add three and four" && 157 158 git checkout -b another adder^ && 159 test_write_lines 1 2 3 4 5 6 7 >three && 160 test_write_lines 1 2 3 four 5 6 7 >four && 161 git add three four && 162 git commit -m "add three and four" && 163 164 # Merging another should be similar to applying this patch 165 git diff adder...another >P.diff && 166 167 git checkout adder^0 && 168 test_must_fail git merge --no-commit another && 169 git ls-files -s >expect.ls && 170 print_sanitized_conflicted_diff >expect.diff 171' 172 173test_expect_success 'apply -3 with add/add conflict' ' 174 # should fail to apply ... 175 git reset --hard && 176 git checkout adder^0 && 177 test_must_fail git apply --index --3way P.diff && 178 # ... and leave conflicts in the index and in the working tree 179 git ls-files -s >actual.ls && 180 print_sanitized_conflicted_diff >actual.diff && 181 182 # The result should resemble the corresponding merge 183 test_cmp expect.ls actual.ls && 184 test_cmp expect.diff actual.diff 185' 186 187test_expect_success 'apply -3 with add/add conflict (dirty working tree)' ' 188 # should fail to apply ... 189 git reset --hard && 190 git checkout adder^0 && 191 echo >>four && 192 cat four >four.save && 193 cat three >three.save && 194 git ls-files -s >expect.ls && 195 test_must_fail git apply --index --3way P.diff && 196 # ... and should not touch anything 197 git ls-files -s >actual.ls && 198 test_cmp expect.ls actual.ls && 199 test_cmp four.save four && 200 test_cmp three.save three 201' 202 203test_expect_success 'apply -3 with ambiguous repeating file' ' 204 git reset --hard && 205 test_write_lines 1 2 1 2 1 2 1 2 1 2 1 >one_two_repeat && 206 git add one_two_repeat && 207 git commit -m "init one" && 208 test_write_lines 1 2 1 2 1 2 1 2 one 2 1 >one_two_repeat && 209 git commit -a -m "change one" && 210 211 git diff HEAD~ >Repeat.diff && 212 git reset --hard HEAD~ && 213 214 test_write_lines 1 2 1 2 1 2 one 2 1 2 one >one_two_repeat && 215 git commit -a -m "change surrounding one" && 216 217 git apply --index --3way Repeat.diff && 218 test_write_lines 1 2 1 2 1 2 one 2 one 2 one >expect && 219 220 test_cmp expect one_two_repeat 221' 222 223test_expect_success 'apply with --3way --cached clean apply' ' 224 # Merging side should be similar to applying this patch 225 git diff ...side >P.diff && 226 227 # The corresponding cleanly applied merge 228 git reset --hard && 229 git checkout main~ && 230 git merge --no-commit side && 231 git ls-files -s >expect.ls && 232 233 # should succeed 234 git reset --hard && 235 git checkout main~ && 236 git apply --cached --3way P.diff && 237 git ls-files -s >actual.ls && 238 print_sanitized_conflicted_diff >actual.diff && 239 240 # The cache should resemble the corresponding merge 241 # (both files at stage #0) 242 test_cmp expect.ls actual.ls && 243 # However the working directory should not change 244 >expect.diff && 245 test_cmp expect.diff actual.diff 246' 247 248test_expect_success 'apply with --3way --cached and conflicts' ' 249 # Merging side should be similar to applying this patch 250 git diff ...side >P.diff && 251 252 # The corresponding conflicted merge 253 git reset --hard && 254 git checkout main^0 && 255 test_must_fail git merge --no-commit side && 256 git ls-files -s >expect.ls && 257 258 # should fail to apply 259 git reset --hard && 260 git checkout main^0 && 261 test_must_fail git apply --cached --3way P.diff && 262 git ls-files -s >actual.ls && 263 print_sanitized_conflicted_diff >actual.diff && 264 265 # The cache should resemble the corresponding merge 266 # (one file at stage #0, one file at stages #1 #2 #3) 267 test_cmp expect.ls actual.ls && 268 # However the working directory should not change 269 >expect.diff && 270 test_cmp expect.diff actual.diff 271' 272 273test_expect_success 'apply binary file patch' ' 274 git reset --hard main && 275 cp "$TEST_DIRECTORY/test-binary-1.png" bin.png && 276 git add bin.png && 277 git commit -m "add binary file" && 278 279 cp "$TEST_DIRECTORY/test-binary-2.png" bin.png && 280 281 git diff --binary >bin.diff && 282 git reset --hard && 283 284 # Apply must succeed. 285 git apply bin.diff 286' 287 288test_expect_success 'apply binary file patch with 3way' ' 289 git reset --hard main && 290 cp "$TEST_DIRECTORY/test-binary-1.png" bin.png && 291 git add bin.png && 292 git commit -m "add binary file" && 293 294 cp "$TEST_DIRECTORY/test-binary-2.png" bin.png && 295 296 git diff --binary >bin.diff && 297 git reset --hard && 298 299 # Apply must succeed. 300 git apply --3way --index bin.diff 301' 302 303test_expect_success 'apply full-index patch with 3way' ' 304 git reset --hard main && 305 cp "$TEST_DIRECTORY/test-binary-1.png" bin.png && 306 git add bin.png && 307 git commit -m "add binary file" && 308 309 cp "$TEST_DIRECTORY/test-binary-2.png" bin.png && 310 311 git diff --full-index >bin.diff && 312 git reset --hard && 313 314 # Apply must succeed. 315 git apply --3way --index bin.diff 316' 317 318test_expect_success 'apply delete then new patch with 3way' ' 319 git reset --hard main && 320 test_write_lines 2 > delnew && 321 git add delnew && 322 git diff --cached >> new.patch && 323 git reset --hard && 324 test_write_lines 1 > delnew && 325 git add delnew && 326 git commit -m "delnew" && 327 rm delnew && 328 git diff >> delete-then-new.patch && 329 cat new.patch >> delete-then-new.patch && 330 331 git checkout -- . && 332 # Apply must succeed. 333 git apply --3way delete-then-new.patch 334' 335 336test_done