t / t5531-deep-submodule-push.shon commit untracked-cache: be defensive about missing NULs in index (c6909f9)
   1#!/bin/sh
   2
   3test_description='test push with submodules'
   4
   5. ./test-lib.sh
   6
   7test_expect_success setup '
   8        mkdir pub.git &&
   9        GIT_DIR=pub.git git init --bare &&
  10        GIT_DIR=pub.git git config receive.fsckobjects true &&
  11        mkdir work &&
  12        (
  13                cd work &&
  14                git init &&
  15                git config push.default matching &&
  16                mkdir -p gar/bage &&
  17                (
  18                        cd gar/bage &&
  19                        git init &&
  20                        git config push.default matching &&
  21                        >junk &&
  22                        git add junk &&
  23                        git commit -m "Initial junk"
  24                ) &&
  25                git add gar/bage &&
  26                git commit -m "Initial superproject"
  27        )
  28'
  29
  30test_expect_success 'push works with recorded gitlink' '
  31        (
  32                cd work &&
  33                git push ../pub.git master
  34        )
  35'
  36
  37test_expect_success 'push if submodule has no remote' '
  38        (
  39                cd work/gar/bage &&
  40                >junk2 &&
  41                git add junk2 &&
  42                git commit -m "Second junk"
  43        ) &&
  44        (
  45                cd work &&
  46                git add gar/bage &&
  47                git commit -m "Second commit for gar/bage" &&
  48                git push --recurse-submodules=check ../pub.git master
  49        )
  50'
  51
  52test_expect_success 'push fails if submodule commit not on remote' '
  53        (
  54                cd work/gar &&
  55                git clone --bare bage ../../submodule.git &&
  56                cd bage &&
  57                git remote add origin ../../../submodule.git &&
  58                git fetch &&
  59                >junk3 &&
  60                git add junk3 &&
  61                git commit -m "Third junk"
  62        ) &&
  63        (
  64                cd work &&
  65                git add gar/bage &&
  66                git commit -m "Third commit for gar/bage" &&
  67                # the push should fail with --recurse-submodules=check
  68                # on the command line...
  69                test_must_fail git push --recurse-submodules=check ../pub.git master &&
  70
  71                # ...or if specified in the configuration..
  72                test_must_fail git -c push.recurseSubmodules=check push ../pub.git master
  73        )
  74'
  75
  76test_expect_success 'push succeeds after commit was pushed to remote' '
  77        (
  78                cd work/gar/bage &&
  79                git push origin master
  80        ) &&
  81        (
  82                cd work &&
  83                git push --recurse-submodules=check ../pub.git master
  84        )
  85'
  86
  87test_expect_success 'push succeeds if submodule commit not on remote but using on-demand on command line' '
  88        (
  89                cd work/gar/bage &&
  90                >recurse-on-demand-on-command-line &&
  91                git add recurse-on-demand-on-command-line &&
  92                git commit -m "Recurse on-demand on command line junk"
  93        ) &&
  94        (
  95                cd work &&
  96                git add gar/bage &&
  97                git commit -m "Recurse on-demand on command line for gar/bage" &&
  98                git push --recurse-submodules=on-demand ../pub.git master &&
  99                # Check that the supermodule commit got there
 100                git fetch ../pub.git &&
 101                git diff --quiet FETCH_HEAD master &&
 102                # Check that the submodule commit got there too
 103                cd gar/bage &&
 104                git diff --quiet origin/master master
 105        )
 106'
 107
 108test_expect_success 'push succeeds if submodule commit not on remote but using on-demand from config' '
 109        (
 110                cd work/gar/bage &&
 111                >recurse-on-demand-from-config &&
 112                git add recurse-on-demand-from-config &&
 113                git commit -m "Recurse on-demand from config junk"
 114        ) &&
 115        (
 116                cd work &&
 117                git add gar/bage &&
 118                git commit -m "Recurse on-demand from config for gar/bage" &&
 119                git -c push.recurseSubmodules=on-demand push ../pub.git master &&
 120                # Check that the supermodule commit got there
 121                git fetch ../pub.git &&
 122                git diff --quiet FETCH_HEAD master &&
 123                # Check that the submodule commit got there too
 124                cd gar/bage &&
 125                git diff --quiet origin/master master
 126        )
 127'
 128
 129test_expect_success 'push succeeds if submodule commit not on remote but using auto-on-demand via submodule.recurse config' '
 130        (
 131                cd work/gar/bage &&
 132                >recurse-on-demand-from-submodule-recurse-config &&
 133                git add recurse-on-demand-from-submodule-recurse-config &&
 134                git commit -m "Recurse submodule.recurse from config junk"
 135        ) &&
 136        (
 137                cd work &&
 138                git add gar/bage &&
 139                git commit -m "Recurse submodule.recurse from config for gar/bage" &&
 140                git -c submodule.recurse push ../pub.git master &&
 141                # Check that the supermodule commit got there
 142                git fetch ../pub.git &&
 143                git diff --quiet FETCH_HEAD master &&
 144                # Check that the submodule commit got there too
 145                cd gar/bage &&
 146                git diff --quiet origin/master master
 147        )
 148'
 149
 150test_expect_success 'push recurse-submodules on command line overrides config' '
 151        (
 152                cd work/gar/bage &&
 153                >recurse-check-on-command-line-overriding-config &&
 154                git add recurse-check-on-command-line-overriding-config &&
 155                git commit -m "Recurse on command-line overriding config junk"
 156        ) &&
 157        (
 158                cd work &&
 159                git add gar/bage &&
 160                git commit -m "Recurse on command-line overriding config for gar/bage" &&
 161
 162                # Ensure that we can override on-demand in the config
 163                # to just check submodules
 164                test_must_fail git -c push.recurseSubmodules=on-demand push --recurse-submodules=check ../pub.git master &&
 165                # Check that the supermodule commit did not get there
 166                git fetch ../pub.git &&
 167                git diff --quiet FETCH_HEAD master^ &&
 168                # Check that the submodule commit did not get there
 169                (cd gar/bage && git diff --quiet origin/master master^) &&
 170
 171                # Ensure that we can override check in the config to
 172                # disable submodule recursion entirely
 173                (cd gar/bage && git diff --quiet origin/master master^) &&
 174                git -c push.recurseSubmodules=on-demand push --recurse-submodules=no ../pub.git master &&
 175                git fetch ../pub.git &&
 176                git diff --quiet FETCH_HEAD master &&
 177                (cd gar/bage && git diff --quiet origin/master master^) &&
 178
 179                # Ensure that we can override check in the config to
 180                # disable submodule recursion entirely (alternative form)
 181                git -c push.recurseSubmodules=on-demand push --no-recurse-submodules ../pub.git master &&
 182                git fetch ../pub.git &&
 183                git diff --quiet FETCH_HEAD master &&
 184                (cd gar/bage && git diff --quiet origin/master master^) &&
 185
 186                # Ensure that we can override check in the config to
 187                # push the submodule too
 188                git -c push.recurseSubmodules=check push --recurse-submodules=on-demand ../pub.git master &&
 189                git fetch ../pub.git &&
 190                git diff --quiet FETCH_HEAD master &&
 191                (cd gar/bage && git diff --quiet origin/master master)
 192        )
 193'
 194
 195test_expect_success 'push recurse-submodules last one wins on command line' '
 196        (
 197                cd work/gar/bage &&
 198                >recurse-check-on-command-line-overriding-earlier-command-line &&
 199                git add recurse-check-on-command-line-overriding-earlier-command-line &&
 200                git commit -m "Recurse on command-line overridiing earlier command-line junk"
 201        ) &&
 202        (
 203                cd work &&
 204                git add gar/bage &&
 205                git commit -m "Recurse on command-line overriding earlier command-line for gar/bage" &&
 206
 207                # should result in "check"
 208                test_must_fail git push --recurse-submodules=on-demand --recurse-submodules=check ../pub.git master &&
 209                # Check that the supermodule commit did not get there
 210                git fetch ../pub.git &&
 211                git diff --quiet FETCH_HEAD master^ &&
 212                # Check that the submodule commit did not get there
 213                (cd gar/bage && git diff --quiet origin/master master^) &&
 214
 215                # should result in "no"
 216                git push --recurse-submodules=on-demand --recurse-submodules=no ../pub.git master &&
 217                # Check that the supermodule commit did get there
 218                git fetch ../pub.git &&
 219                git diff --quiet FETCH_HEAD master &&
 220                # Check that the submodule commit did not get there
 221                (cd gar/bage && git diff --quiet origin/master master^) &&
 222
 223                # should result in "no"
 224                git push --recurse-submodules=on-demand --no-recurse-submodules ../pub.git master &&
 225                # Check that the submodule commit did not get there
 226                (cd gar/bage && git diff --quiet origin/master master^) &&
 227
 228                # But the options in the other order should push the submodule
 229                git push --recurse-submodules=check --recurse-submodules=on-demand ../pub.git master &&
 230                # Check that the submodule commit did get there
 231                git fetch ../pub.git &&
 232                (cd gar/bage && git diff --quiet origin/master master)
 233        )
 234'
 235
 236test_expect_success 'push succeeds if submodule commit not on remote using on-demand from cmdline overriding config' '
 237        (
 238                cd work/gar/bage &&
 239                >recurse-on-demand-on-command-line-overriding-config &&
 240                git add recurse-on-demand-on-command-line-overriding-config &&
 241                git commit -m "Recurse on-demand on command-line overriding config junk"
 242        ) &&
 243        (
 244                cd work &&
 245                git add gar/bage &&
 246                git commit -m "Recurse on-demand on command-line overriding config for gar/bage" &&
 247                git -c push.recurseSubmodules=check push --recurse-submodules=on-demand ../pub.git master &&
 248                # Check that the supermodule commit got there
 249                git fetch ../pub.git &&
 250                git diff --quiet FETCH_HEAD master &&
 251                # Check that the submodule commit got there
 252                cd gar/bage &&
 253                git diff --quiet origin/master master
 254        )
 255'
 256
 257test_expect_success 'push succeeds if submodule commit disabling recursion from cmdline overriding config' '
 258        (
 259                cd work/gar/bage &&
 260                >recurse-disable-on-command-line-overriding-config &&
 261                git add recurse-disable-on-command-line-overriding-config &&
 262                git commit -m "Recurse disable on command-line overriding config junk"
 263        ) &&
 264        (
 265                cd work &&
 266                git add gar/bage &&
 267                git commit -m "Recurse disable on command-line overriding config for gar/bage" &&
 268                git -c push.recurseSubmodules=check push --recurse-submodules=no ../pub.git master &&
 269                # Check that the supermodule commit got there
 270                git fetch ../pub.git &&
 271                git diff --quiet FETCH_HEAD master &&
 272                # But that the submodule commit did not
 273                ( cd gar/bage && git diff --quiet origin/master master^ ) &&
 274                # Now push it to avoid confusing future tests
 275                git push --recurse-submodules=on-demand ../pub.git master
 276        )
 277'
 278
 279test_expect_success 'push succeeds if submodule commit disabling recursion from cmdline (alternative form) overriding config' '
 280        (
 281                cd work/gar/bage &&
 282                >recurse-disable-on-command-line-alt-overriding-config &&
 283                git add recurse-disable-on-command-line-alt-overriding-config &&
 284                git commit -m "Recurse disable on command-line alternative overriding config junk"
 285        ) &&
 286        (
 287                cd work &&
 288                git add gar/bage &&
 289                git commit -m "Recurse disable on command-line alternative overriding config for gar/bage" &&
 290                git -c push.recurseSubmodules=check push --no-recurse-submodules ../pub.git master &&
 291                # Check that the supermodule commit got there
 292                git fetch ../pub.git &&
 293                git diff --quiet FETCH_HEAD master &&
 294                # But that the submodule commit did not
 295                ( cd gar/bage && git diff --quiet origin/master master^ ) &&
 296                # Now push it to avoid confusing future tests
 297                git push --recurse-submodules=on-demand ../pub.git master
 298        )
 299'
 300
 301test_expect_success 'submodule entry pointing at a tag is error' '
 302        git -C work/gar/bage tag -a test1 -m "tag" &&
 303        tag=$(git -C work/gar/bage rev-parse test1^{tag}) &&
 304        git -C work update-index --cacheinfo 160000 "$tag" gar/bage &&
 305        git -C work commit -m "bad commit" &&
 306        test_when_finished "git -C work reset --hard HEAD^" &&
 307        test_must_fail git -C work push --recurse-submodules=on-demand ../pub.git master 2>err &&
 308        test_i18ngrep "is a tag, not a commit" err
 309'
 310
 311test_expect_success 'push fails if recurse submodules option passed as yes' '
 312        (
 313                cd work/gar/bage &&
 314                >recurse-push-fails-if-recurse-submodules-passed-as-yes &&
 315                git add recurse-push-fails-if-recurse-submodules-passed-as-yes &&
 316                git commit -m "Recurse push fails if recurse submodules option passed as yes"
 317        ) &&
 318        (
 319                cd work &&
 320                git add gar/bage &&
 321                git commit -m "Recurse push fails if recurse submodules option passed as yes for gar/bage" &&
 322                test_must_fail git push --recurse-submodules=yes ../pub.git master &&
 323                test_must_fail git -c push.recurseSubmodules=yes push ../pub.git master &&
 324                git push --recurse-submodules=on-demand ../pub.git master
 325        )
 326'
 327
 328test_expect_success 'push fails when commit on multiple branches if one branch has no remote' '
 329        (
 330                cd work/gar/bage &&
 331                >junk4 &&
 332                git add junk4 &&
 333                git commit -m "Fourth junk"
 334        ) &&
 335        (
 336                cd work &&
 337                git branch branch2 &&
 338                git add gar/bage &&
 339                git commit -m "Fourth commit for gar/bage" &&
 340                git checkout branch2 &&
 341                (
 342                        cd gar/bage &&
 343                        git checkout HEAD~1
 344                ) &&
 345                >junk1 &&
 346                git add junk1 &&
 347                git commit -m "First junk" &&
 348                test_must_fail git push --recurse-submodules=check ../pub.git
 349        )
 350'
 351
 352test_expect_success 'push succeeds if submodule has no remote and is on the first superproject commit' '
 353        git init --bare a &&
 354        git clone a a1 &&
 355        (
 356                cd a1 &&
 357                git init b &&
 358                (
 359                        cd b &&
 360                        >junk &&
 361                        git add junk &&
 362                        git commit -m "initial"
 363                ) &&
 364                git add b &&
 365                git commit -m "added submodule" &&
 366                git push --recurse-submodule=check origin master
 367        )
 368'
 369
 370test_expect_success 'push unpushed submodules when not needed' '
 371        (
 372                cd work &&
 373                (
 374                        cd gar/bage &&
 375                        git checkout master &&
 376                        >junk5 &&
 377                        git add junk5 &&
 378                        git commit -m "Fifth junk" &&
 379                        git push &&
 380                        git rev-parse origin/master >../../../expected
 381                ) &&
 382                git checkout master &&
 383                git add gar/bage &&
 384                git commit -m "Fifth commit for gar/bage" &&
 385                git push --recurse-submodules=on-demand ../pub.git master
 386        ) &&
 387        (
 388                cd submodule.git &&
 389                git rev-parse master >../actual
 390        ) &&
 391        test_cmp expected actual
 392'
 393
 394test_expect_success 'push unpushed submodules when not needed 2' '
 395        (
 396                cd submodule.git &&
 397                git rev-parse master >../expected
 398        ) &&
 399        (
 400                cd work &&
 401                (
 402                        cd gar/bage &&
 403                        >junk6 &&
 404                        git add junk6 &&
 405                        git commit -m "Sixth junk"
 406                ) &&
 407                >junk2 &&
 408                git add junk2 &&
 409                git commit -m "Second junk for work" &&
 410                git push --recurse-submodules=on-demand ../pub.git master
 411        ) &&
 412        (
 413                cd submodule.git &&
 414                git rev-parse master >../actual
 415        ) &&
 416        test_cmp expected actual
 417'
 418
 419test_expect_success 'push unpushed submodules recursively' '
 420        (
 421                cd work &&
 422                (
 423                        cd gar/bage &&
 424                        git checkout master &&
 425                        > junk7 &&
 426                        git add junk7 &&
 427                        git commit -m "Seventh junk" &&
 428                        git rev-parse master >../../../expected
 429                ) &&
 430                git checkout master &&
 431                git add gar/bage &&
 432                git commit -m "Seventh commit for gar/bage" &&
 433                git push --recurse-submodules=on-demand ../pub.git master
 434        ) &&
 435        (
 436                cd submodule.git &&
 437                git rev-parse master >../actual
 438        ) &&
 439        test_cmp expected actual
 440'
 441
 442test_expect_success 'push unpushable submodule recursively fails' '
 443        (
 444                cd work &&
 445                (
 446                        cd gar/bage &&
 447                        git rev-parse origin/master >../../../expected &&
 448                        git checkout master~0 &&
 449                        > junk8 &&
 450                        git add junk8 &&
 451                        git commit -m "Eighth junk"
 452                ) &&
 453                git add gar/bage &&
 454                git commit -m "Eighth commit for gar/bage" &&
 455                test_must_fail git push --recurse-submodules=on-demand ../pub.git master
 456        ) &&
 457        (
 458                cd submodule.git &&
 459                git rev-parse master >../actual
 460        ) &&
 461        test_when_finished git -C work reset --hard master^ &&
 462        test_cmp expected actual
 463'
 464
 465test_expect_success 'push --dry-run does not recursively update submodules' '
 466        (
 467                cd work/gar/bage &&
 468                git checkout master &&
 469                git rev-parse master >../../../expected_submodule &&
 470                > junk9 &&
 471                git add junk9 &&
 472                git commit -m "Ninth junk" &&
 473
 474                # Go up to 'work' directory
 475                cd ../.. &&
 476                git checkout master &&
 477                git rev-parse master >../expected_pub &&
 478                git add gar/bage &&
 479                git commit -m "Ninth commit for gar/bage" &&
 480                git push --dry-run --recurse-submodules=on-demand ../pub.git master
 481        ) &&
 482        git -C submodule.git rev-parse master >actual_submodule &&
 483        git -C pub.git rev-parse master >actual_pub &&
 484        test_cmp expected_pub actual_pub &&
 485        test_cmp expected_submodule actual_submodule
 486'
 487
 488test_expect_success 'push --dry-run does not recursively update submodules' '
 489        git -C work push --dry-run --recurse-submodules=only ../pub.git master &&
 490
 491        git -C submodule.git rev-parse master >actual_submodule &&
 492        git -C pub.git rev-parse master >actual_pub &&
 493        test_cmp expected_pub actual_pub &&
 494        test_cmp expected_submodule actual_submodule
 495'
 496
 497test_expect_success 'push only unpushed submodules recursively' '
 498        git -C work/gar/bage rev-parse master >expected_submodule &&
 499        git -C pub.git rev-parse master >expected_pub &&
 500
 501        git -C work push --recurse-submodules=only ../pub.git master &&
 502
 503        git -C submodule.git rev-parse master >actual_submodule &&
 504        git -C pub.git rev-parse master >actual_pub &&
 505        test_cmp expected_submodule actual_submodule &&
 506        test_cmp expected_pub actual_pub
 507'
 508
 509test_expect_success 'push propagating the remotes name to a submodule' '
 510        git -C work remote add origin ../pub.git &&
 511        git -C work remote add pub ../pub.git &&
 512
 513        > work/gar/bage/junk10 &&
 514        git -C work/gar/bage add junk10 &&
 515        git -C work/gar/bage commit -m "Tenth junk" &&
 516        git -C work add gar/bage &&
 517        git -C work commit -m "Tenth junk added to gar/bage" &&
 518
 519        # Fails when submodule does not have a matching remote
 520        test_must_fail git -C work push --recurse-submodules=on-demand pub master &&
 521        # Succeeds when submodules has matching remote and refspec
 522        git -C work push --recurse-submodules=on-demand origin master &&
 523
 524        git -C submodule.git rev-parse master >actual_submodule &&
 525        git -C pub.git rev-parse master >actual_pub &&
 526        git -C work/gar/bage rev-parse master >expected_submodule &&
 527        git -C work rev-parse master >expected_pub &&
 528        test_cmp expected_submodule actual_submodule &&
 529        test_cmp expected_pub actual_pub
 530'
 531
 532test_expect_success 'push propagating refspec to a submodule' '
 533        > work/gar/bage/junk11 &&
 534        git -C work/gar/bage add junk11 &&
 535        git -C work/gar/bage commit -m "Eleventh junk" &&
 536
 537        git -C work checkout branch2 &&
 538        git -C work add gar/bage &&
 539        git -C work commit -m "updating gar/bage in branch2" &&
 540
 541        # Fails when submodule does not have a matching branch
 542        test_must_fail git -C work push --recurse-submodules=on-demand origin branch2 &&
 543        # Fails when refspec includes an object id
 544        test_must_fail git -C work push --recurse-submodules=on-demand origin \
 545                "$(git -C work rev-parse branch2):refs/heads/branch2" &&
 546        # Fails when refspec includes HEAD and parent and submodule do not
 547        # have the same named branch checked out
 548        test_must_fail git -C work push --recurse-submodules=on-demand origin \
 549                HEAD:refs/heads/branch2 &&
 550
 551        git -C work/gar/bage branch branch2 master &&
 552        git -C work push --recurse-submodules=on-demand origin branch2 &&
 553
 554        git -C submodule.git rev-parse branch2 >actual_submodule &&
 555        git -C pub.git rev-parse branch2 >actual_pub &&
 556        git -C work/gar/bage rev-parse branch2 >expected_submodule &&
 557        git -C work rev-parse branch2 >expected_pub &&
 558        test_cmp expected_submodule actual_submodule &&
 559        test_cmp expected_pub actual_pub
 560'
 561
 562test_expect_success 'push propagating HEAD refspec to a submodule' '
 563        git -C work/gar/bage checkout branch2 &&
 564        > work/gar/bage/junk12 &&
 565        git -C work/gar/bage add junk12 &&
 566        git -C work/gar/bage commit -m "Twelfth junk" &&
 567
 568        git -C work checkout branch2 &&
 569        git -C work add gar/bage &&
 570        git -C work commit -m "updating gar/bage in branch2" &&
 571
 572        # Passes since the superproject and submodules HEAD are both on branch2
 573        git -C work push --recurse-submodules=on-demand origin \
 574                HEAD:refs/heads/branch2 &&
 575
 576        git -C submodule.git rev-parse branch2 >actual_submodule &&
 577        git -C pub.git rev-parse branch2 >actual_pub &&
 578        git -C work/gar/bage rev-parse branch2 >expected_submodule &&
 579        git -C work rev-parse branch2 >expected_pub &&
 580        test_cmp expected_submodule actual_submodule &&
 581        test_cmp expected_pub actual_pub
 582'
 583
 584test_done