1#!/bin/sh 2 3test_description='git merge 4 5Testing pull.* configuration parsing and other things.' 6 7. ./test-lib.sh 8 9test_expect_success 'setup' ' 10 echo c0 >c0.c && 11 git add c0.c && 12 git commit -m c0 && 13 git tag c0 && 14 echo c1 >c1.c && 15 git add c1.c && 16 git commit -m c1 && 17 git tag c1 && 18 git reset --hard c0 && 19 echo c2 >c2.c && 20 git add c2.c && 21 git commit -m c2 && 22 git tag c2 && 23 git reset --hard c0 && 24 echo c3 >c3.c && 25 git add c3.c && 26 git commit -m c3 && 27 git tag c3 28' 29 30test_expect_success 'pull.rebase not set, ff possible' ' 31 git reset --hard c0 && 32 git pull . c1 2>err && 33 test_i18ngrep ! "You have divergent branches" err 34' 35 36test_expect_success 'pull.rebase not set and pull.ff=true' ' 37 git reset --hard c0 && 38 test_config pull.ff true && 39 git pull . c1 2>err && 40 test_i18ngrep ! "You have divergent branches" err 41' 42 43test_expect_success 'pull.rebase not set and pull.ff=false' ' 44 git reset --hard c0 && 45 test_config pull.ff false && 46 git pull . c1 2>err && 47 test_i18ngrep ! "You have divergent branches" err 48' 49 50test_expect_success 'pull.rebase not set and pull.ff=only' ' 51 git reset --hard c0 && 52 test_config pull.ff only && 53 git pull . c1 2>err && 54 test_i18ngrep ! "You have divergent branches" err 55' 56 57test_expect_success 'pull.rebase not set and --rebase given' ' 58 git reset --hard c0 && 59 git pull --rebase . c1 2>err && 60 test_i18ngrep ! "You have divergent branches" err 61' 62 63test_expect_success 'pull.rebase not set and --no-rebase given' ' 64 git reset --hard c0 && 65 git pull --no-rebase . c1 2>err && 66 test_i18ngrep ! "You have divergent branches" err 67' 68 69test_expect_success 'pull.rebase not set and --ff given' ' 70 git reset --hard c0 && 71 git pull --ff . c1 2>err && 72 test_i18ngrep ! "You have divergent branches" err 73' 74 75test_expect_success 'pull.rebase not set and --no-ff given' ' 76 git reset --hard c0 && 77 git pull --no-ff . c1 2>err && 78 test_i18ngrep ! "You have divergent branches" err 79' 80 81test_expect_success 'pull.rebase not set and --ff-only given' ' 82 git reset --hard c0 && 83 git pull --ff-only . c1 2>err && 84 test_i18ngrep ! "You have divergent branches" err 85' 86 87test_expect_success 'pull.rebase not set (not-fast-forward)' ' 88 git reset --hard c2 && 89 test_must_fail git -c color.advice=always pull . c1 2>err && 90 test_decode_color <err >decoded && 91 test_i18ngrep "<YELLOW>hint: " decoded && 92 test_i18ngrep "You have divergent branches" decoded 93' 94 95test_expect_success 'pull.rebase not set and pull.ff=true (not-fast-forward)' ' 96 git reset --hard c2 && 97 test_config pull.ff true && 98 git pull . c1 2>err && 99 test_i18ngrep ! "You have divergent branches" err 100' 101 102test_expect_success 'pull.rebase not set and pull.ff=false (not-fast-forward)' ' 103 git reset --hard c2 && 104 test_config pull.ff false && 105 git pull . c1 2>err && 106 test_i18ngrep ! "You have divergent branches" err 107' 108 109test_expect_success 'pull.rebase not set and pull.ff=only (not-fast-forward)' ' 110 git reset --hard c2 && 111 test_config pull.ff only && 112 test_must_fail git pull . c1 2>err && 113 test_i18ngrep ! "You have divergent branches" err 114' 115 116test_expect_success 'pull.rebase not set and --rebase given (not-fast-forward)' ' 117 git reset --hard c2 && 118 git pull --rebase . c1 2>err && 119 test_i18ngrep ! "You have divergent branches" err 120' 121 122test_expect_success 'pull.rebase not set and --no-rebase given (not-fast-forward)' ' 123 git reset --hard c2 && 124 git pull --no-rebase . c1 2>err && 125 test_i18ngrep ! "You have divergent branches" err 126' 127 128test_expect_success 'pull.rebase not set and --ff given (not-fast-forward)' ' 129 git reset --hard c2 && 130 git pull --ff . c1 2>err && 131 test_i18ngrep ! "You have divergent branches" err 132' 133 134test_expect_success 'pull.rebase not set and --no-ff given (not-fast-forward)' ' 135 git reset --hard c2 && 136 git pull --no-ff . c1 2>err && 137 test_i18ngrep ! "You have divergent branches" err 138' 139 140test_expect_success 'pull.rebase not set and --ff-only given (not-fast-forward)' ' 141 git reset --hard c2 && 142 test_must_fail git pull --ff-only . c1 2>err && 143 test_i18ngrep ! "You have divergent branches" err 144' 145 146test_does_rebase () { 147 git reset --hard c2 && 148 git "$@" . c1 && 149 # Check that we actually did a rebase 150 git rev-list --count HEAD >actual && 151 git rev-list --merges --count HEAD >>actual && 152 test_write_lines 3 0 >expect && 153 test_cmp expect actual && 154 rm actual expect 155} 156 157# Prefers merge over fast-forward 158test_does_merge_when_ff_possible () { 159 git reset --hard c0 && 160 git "$@" . c1 && 161 # Check that we actually did a merge 162 git rev-list --count HEAD >actual && 163 git rev-list --merges --count HEAD >>actual && 164 test_write_lines 3 1 >expect && 165 test_cmp expect actual && 166 rm actual expect 167} 168 169# Prefers fast-forward over merge or rebase 170test_does_fast_forward () { 171 git reset --hard c0 && 172 git "$@" . c1 && 173 174 # Check that we did not get any merges 175 git rev-list --count HEAD >actual && 176 git rev-list --merges --count HEAD >>actual && 177 test_write_lines 2 0 >expect && 178 test_cmp expect actual && 179 180 # Check that we ended up at c1 181 git rev-parse HEAD >actual && 182 git rev-parse c1^{commit} >expect && 183 test_cmp actual expect && 184 185 # Remove temporary files 186 rm actual expect 187} 188 189# Doesn't fail when fast-forward not possible; does a merge 190test_falls_back_to_full_merge () { 191 git reset --hard c2 && 192 git "$@" . c1 && 193 # Check that we actually did a merge 194 git rev-list --count HEAD >actual && 195 git rev-list --merges --count HEAD >>actual && 196 test_write_lines 4 1 >expect && 197 test_cmp expect actual && 198 rm actual expect 199} 200 201# Attempts fast forward, which is impossible, and bails 202test_attempts_fast_forward () { 203 git reset --hard c2 && 204 test_must_fail git "$@" . c1 2>err && 205 test_i18ngrep "Not possible to fast-forward, aborting" err 206} 207 208# 209# Group 1: Interaction of --ff-only with --[no-]rebase 210# (And related interaction of pull.ff=only with pull.rebase) 211# 212test_expect_success '--ff-only overrides --rebase' ' 213 test_attempts_fast_forward pull --rebase --ff-only 214' 215 216test_expect_success '--ff-only overrides --rebase even if first' ' 217 test_attempts_fast_forward pull --ff-only --rebase 218' 219 220test_expect_success '--ff-only overrides --no-rebase' ' 221 test_attempts_fast_forward pull --ff-only --no-rebase 222' 223 224test_expect_success 'pull.ff=only overrides pull.rebase=true' ' 225 test_attempts_fast_forward -c pull.ff=only -c pull.rebase=true pull 226' 227 228test_expect_success 'pull.ff=only overrides pull.rebase=false' ' 229 test_attempts_fast_forward -c pull.ff=only -c pull.rebase=false pull 230' 231 232# Group 2: --rebase=[!false] overrides --no-ff and --ff 233# (And related interaction of pull.rebase=!false and pull.ff=!only) 234test_expect_success '--rebase overrides --no-ff' ' 235 test_does_rebase pull --rebase --no-ff 236' 237 238test_expect_success '--rebase overrides --ff' ' 239 test_does_rebase pull --rebase --ff 240' 241 242test_expect_success '--rebase fast-forwards when possible' ' 243 test_does_fast_forward pull --rebase --ff 244' 245 246test_expect_success 'pull.rebase=true overrides pull.ff=false' ' 247 test_does_rebase -c pull.rebase=true -c pull.ff=false pull 248' 249 250test_expect_success 'pull.rebase=true overrides pull.ff=true' ' 251 test_does_rebase -c pull.rebase=true -c pull.ff=true pull 252' 253 254# Group 3: command line flags take precedence over config 255test_expect_success '--ff-only takes precedence over pull.rebase=true' ' 256 test_attempts_fast_forward -c pull.rebase=true pull --ff-only 257' 258 259test_expect_success '--ff-only takes precedence over pull.rebase=false' ' 260 test_attempts_fast_forward -c pull.rebase=false pull --ff-only 261' 262 263test_expect_success '--no-rebase takes precedence over pull.ff=only' ' 264 test_falls_back_to_full_merge -c pull.ff=only pull --no-rebase 265' 266 267test_expect_success '--rebase takes precedence over pull.ff=only' ' 268 test_does_rebase -c pull.ff=only pull --rebase 269' 270 271test_expect_success '--rebase overrides pull.ff=true' ' 272 test_does_rebase -c pull.ff=true pull --rebase 273' 274 275test_expect_success '--rebase overrides pull.ff=false' ' 276 test_does_rebase -c pull.ff=false pull --rebase 277' 278 279test_expect_success '--rebase overrides pull.ff unset' ' 280 test_does_rebase pull --rebase 281' 282 283# Group 4: --no-rebase heeds pull.ff=!only or explict --ff or --no-ff 284 285test_expect_success '--no-rebase works with --no-ff' ' 286 test_does_merge_when_ff_possible pull --no-rebase --no-ff 287' 288 289test_expect_success '--no-rebase works with --ff' ' 290 test_does_fast_forward pull --no-rebase --ff 291' 292 293test_expect_success '--no-rebase does ff if pull.ff unset' ' 294 test_does_fast_forward pull --no-rebase 295' 296 297test_expect_success '--no-rebase heeds pull.ff=true' ' 298 test_does_fast_forward -c pull.ff=true pull --no-rebase 299' 300 301test_expect_success '--no-rebase heeds pull.ff=false' ' 302 test_does_merge_when_ff_possible -c pull.ff=false pull --no-rebase 303' 304 305# Group 5: pull.rebase=!false in combination with --no-ff or --ff 306test_expect_success 'pull.rebase=true and --no-ff' ' 307 test_does_rebase -c pull.rebase=true pull --no-ff 308' 309 310test_expect_success 'pull.rebase=true and --ff' ' 311 test_does_rebase -c pull.rebase=true pull --ff 312' 313 314test_expect_success 'pull.rebase=false and --no-ff' ' 315 test_does_merge_when_ff_possible -c pull.rebase=false pull --no-ff 316' 317 318test_expect_success 'pull.rebase=false and --ff, ff possible' ' 319 test_does_fast_forward -c pull.rebase=false pull --ff 320' 321 322test_expect_success 'pull.rebase=false and --ff, ff not possible' ' 323 test_falls_back_to_full_merge -c pull.rebase=false pull --ff 324' 325 326# End of groupings for conflicting merge vs. rebase flags/options 327 328test_expect_success 'Multiple heads warns about inability to fast forward' ' 329 git reset --hard c1 && 330 test_must_fail git pull . c2 c3 2>err && 331 test_i18ngrep "You have divergent branches" err 332' 333 334test_expect_success 'Multiple can never be fast forwarded' ' 335 git reset --hard c0 && 336 test_must_fail git -c pull.ff=only pull . c1 c2 c3 2>err && 337 test_i18ngrep ! "You have divergent branches" err && 338 # In addition to calling out "cannot fast-forward", we very much 339 # want the "multiple branches" piece to be called out to users. 340 test_i18ngrep "Cannot fast-forward to multiple branches" err 341' 342 343test_expect_success 'Cannot rebase with multiple heads' ' 344 git reset --hard c0 && 345 test_must_fail git -c pull.rebase=true pull . c1 c2 c3 2>err && 346 test_i18ngrep ! "You have divergent branches" err && 347 test_i18ngrep "Cannot rebase onto multiple branches." err 348' 349 350test_expect_success 'merge c1 with c2' ' 351 git reset --hard c1 && 352 test -f c0.c && 353 test -f c1.c && 354 test ! -f c2.c && 355 test ! -f c3.c && 356 git merge c2 && 357 test -f c1.c && 358 test -f c2.c 359' 360 361test_expect_success 'fast-forward pull succeeds with "true" in pull.ff' ' 362 git reset --hard c0 && 363 test_config pull.ff true && 364 git pull . c1 && 365 test "$(git rev-parse HEAD)" = "$(git rev-parse c1)" 366' 367 368test_expect_success 'pull.ff=true overrides merge.ff=false' ' 369 git reset --hard c0 && 370 test_config merge.ff false && 371 test_config pull.ff true && 372 git pull . c1 && 373 test "$(git rev-parse HEAD)" = "$(git rev-parse c1)" 374' 375 376test_expect_success 'fast-forward pull creates merge with "false" in pull.ff' ' 377 git reset --hard c0 && 378 test_config pull.ff false && 379 git pull . c1 && 380 test "$(git rev-parse HEAD^1)" = "$(git rev-parse c0)" && 381 test "$(git rev-parse HEAD^2)" = "$(git rev-parse c1)" 382' 383 384test_expect_success 'pull prevents non-fast-forward with "only" in pull.ff' ' 385 git reset --hard c1 && 386 test_config pull.ff only && 387 test_must_fail git pull . c3 388' 389 390test_expect_success 'already-up-to-date pull succeeds with unspecified pull.ff' ' 391 git reset --hard c1 && 392 git pull . c0 && 393 test "$(git rev-parse HEAD)" = "$(git rev-parse c1)" 394' 395 396test_expect_success 'already-up-to-date pull succeeds with "only" in pull.ff' ' 397 git reset --hard c1 && 398 test_config pull.ff only && 399 git pull . c0 && 400 test "$(git rev-parse HEAD)" = "$(git rev-parse c1)" 401' 402 403test_expect_success 'already-up-to-date pull/rebase succeeds with "only" in pull.ff' ' 404 git reset --hard c1 && 405 test_config pull.ff only && 406 git -c pull.rebase=true pull . c0 && 407 test "$(git rev-parse HEAD)" = "$(git rev-parse c1)" 408' 409 410test_expect_success 'merge c1 with c2 (ours in pull.twohead)' ' 411 git reset --hard c1 && 412 git config pull.twohead ours && 413 git merge c2 && 414 test -f c1.c && 415 ! test -f c2.c 416' 417 418test_expect_success 'merge c1 with c2 and c3 (recursive in pull.octopus)' ' 419 git reset --hard c1 && 420 git config pull.octopus "recursive" && 421 test_must_fail git merge c2 c3 && 422 test "$(git rev-parse c1)" = "$(git rev-parse HEAD)" 423' 424 425test_expect_success 'merge c1 with c2 and c3 (recursive and octopus in pull.octopus)' ' 426 git reset --hard c1 && 427 git config pull.octopus "recursive octopus" && 428 git merge c2 c3 && 429 test "$(git rev-parse c1)" != "$(git rev-parse HEAD)" && 430 test "$(git rev-parse c1)" = "$(git rev-parse HEAD^1)" && 431 test "$(git rev-parse c2)" = "$(git rev-parse HEAD^2)" && 432 test "$(git rev-parse c3)" = "$(git rev-parse HEAD^3)" && 433 git diff --exit-code && 434 test -f c0.c && 435 test -f c1.c && 436 test -f c2.c && 437 test -f c3.c 438' 439 440conflict_count() 441{ 442 { 443 git diff-files --name-only 444 git ls-files --unmerged 445 } | wc -l 446} 447 448# c4 - c5 449# \ c6 450# 451# There are two conflicts here: 452# 453# 1) Because foo.c is renamed to bar.c, recursive will handle this, 454# resolve won't. 455# 456# 2) One in conflict.c and that will always fail. 457 458test_expect_success 'setup conflicted merge' ' 459 git reset --hard c0 && 460 echo A >conflict.c && 461 git add conflict.c && 462 echo contents >foo.c && 463 git add foo.c && 464 git commit -m c4 && 465 git tag c4 && 466 echo B >conflict.c && 467 git add conflict.c && 468 git mv foo.c bar.c && 469 git commit -m c5 && 470 git tag c5 && 471 git reset --hard c4 && 472 echo C >conflict.c && 473 git add conflict.c && 474 echo secondline >> foo.c && 475 git add foo.c && 476 git commit -m c6 && 477 git tag c6 478' 479 480# First do the merge with resolve and recursive then verify that 481# recursive is chosen. 482 483test_expect_success 'merge picks up the best result' ' 484 git config --unset-all pull.twohead && 485 git reset --hard c5 && 486 test_must_fail git merge -s resolve c6 && 487 resolve_count=$(conflict_count) && 488 git reset --hard c5 && 489 test_must_fail git merge -s recursive c6 && 490 recursive_count=$(conflict_count) && 491 git reset --hard c5 && 492 test_must_fail git merge -s recursive -s resolve c6 && 493 auto_count=$(conflict_count) && 494 test $auto_count = $recursive_count && 495 test $auto_count != $resolve_count 496' 497 498test_expect_success 'merge picks up the best result (from config)' ' 499 git config pull.twohead "recursive resolve" && 500 git reset --hard c5 && 501 test_must_fail git merge -s resolve c6 && 502 resolve_count=$(conflict_count) && 503 git reset --hard c5 && 504 test_must_fail git merge -s recursive c6 && 505 recursive_count=$(conflict_count) && 506 git reset --hard c5 && 507 test_must_fail git merge c6 && 508 auto_count=$(conflict_count) && 509 test $auto_count = $recursive_count && 510 test $auto_count != $resolve_count 511' 512 513test_expect_success 'merge errors out on invalid strategy' ' 514 git config pull.twohead "foobar" && 515 git reset --hard c5 && 516 test_must_fail git merge c6 517' 518 519test_expect_success 'merge errors out on invalid strategy' ' 520 git config --unset-all pull.twohead && 521 git reset --hard c5 && 522 test_must_fail git merge -s "resolve recursive" c6 523' 524 525test_done 526