t / t6026-merge-attr.shon commit t4045: abstract away SHA-1-specific constants (5c02428)
   1#!/bin/sh
   2#
   3# Copyright (c) 2007 Junio C Hamano
   4#
   5
   6test_description='per path merge controlled by merge attribute'
   7
   8. ./test-lib.sh
   9
  10test_expect_success setup '
  11
  12        for f in text binary union
  13        do
  14                echo Initial >$f && git add $f || return 1
  15        done &&
  16        test_tick &&
  17        git commit -m Initial &&
  18
  19        git branch side &&
  20        for f in text binary union
  21        do
  22                echo Master >>$f && git add $f || return 1
  23        done &&
  24        test_tick &&
  25        git commit -m Master &&
  26
  27        git checkout side &&
  28        for f in text binary union
  29        do
  30                echo Side >>$f && git add $f || return 1
  31        done &&
  32        test_tick &&
  33        git commit -m Side &&
  34
  35        git tag anchor
  36'
  37
  38test_expect_success merge '
  39
  40        {
  41                echo "binary -merge"
  42                echo "union merge=union"
  43        } >.gitattributes &&
  44
  45        if git merge master
  46        then
  47                echo Gaah, should have conflicted
  48                false
  49        else
  50                echo Ok, conflicted.
  51        fi
  52'
  53
  54test_expect_success 'check merge result in index' '
  55
  56        git ls-files -u | grep binary &&
  57        git ls-files -u | grep text &&
  58        ! (git ls-files -u | grep union)
  59
  60'
  61
  62test_expect_success 'check merge result in working tree' '
  63
  64        git cat-file -p HEAD:binary >binary-orig &&
  65        grep "<<<<<<<" text &&
  66        cmp binary-orig binary &&
  67        ! grep "<<<<<<<" union &&
  68        grep Master union &&
  69        grep Side union
  70
  71'
  72
  73test_expect_success 'retry the merge with longer context' '
  74        echo text conflict-marker-size=32 >>.gitattributes &&
  75        git checkout -m text &&
  76        sed -ne "/^\([<=>]\)\1\1\1*/{
  77                s/ .*$//
  78                p
  79        }" >actual text &&
  80        grep ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" actual &&
  81        grep "================================" actual &&
  82        grep "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" actual
  83'
  84
  85cat >./custom-merge <<\EOF
  86#!/bin/sh
  87
  88orig="$1" ours="$2" theirs="$3" exit="$4" path=$5
  89(
  90        echo "orig is $orig"
  91        echo "ours is $ours"
  92        echo "theirs is $theirs"
  93        echo "path is $path"
  94        echo "=== orig ==="
  95        cat "$orig"
  96        echo "=== ours ==="
  97        cat "$ours"
  98        echo "=== theirs ==="
  99        cat "$theirs"
 100) >"$ours+"
 101cat "$ours+" >"$ours"
 102rm -f "$ours+"
 103exit "$exit"
 104EOF
 105chmod +x ./custom-merge
 106
 107test_expect_success 'custom merge backend' '
 108
 109        echo "* merge=union" >.gitattributes &&
 110        echo "text merge=custom" >>.gitattributes &&
 111
 112        git reset --hard anchor &&
 113        git config --replace-all \
 114        merge.custom.driver "./custom-merge %O %A %B 0 %P" &&
 115        git config --replace-all \
 116        merge.custom.name "custom merge driver for testing" &&
 117
 118        git merge master &&
 119
 120        cmp binary union &&
 121        sed -e 1,3d text >check-1 &&
 122        o=$(git unpack-file master^:text) &&
 123        a=$(git unpack-file side^:text) &&
 124        b=$(git unpack-file master:text) &&
 125        sh -c "./custom-merge $o $a $b 0 'text'" &&
 126        sed -e 1,3d $a >check-2 &&
 127        cmp check-1 check-2 &&
 128        rm -f $o $a $b
 129'
 130
 131test_expect_success 'custom merge backend' '
 132
 133        git reset --hard anchor &&
 134        git config --replace-all \
 135        merge.custom.driver "./custom-merge %O %A %B 1 %P" &&
 136        git config --replace-all \
 137        merge.custom.name "custom merge driver for testing" &&
 138
 139        if git merge master
 140        then
 141                echo "Eh? should have conflicted"
 142                false
 143        else
 144                echo "Ok, conflicted"
 145        fi &&
 146
 147        cmp binary union &&
 148        sed -e 1,3d text >check-1 &&
 149        o=$(git unpack-file master^:text) &&
 150        a=$(git unpack-file anchor:text) &&
 151        b=$(git unpack-file master:text) &&
 152        sh -c "./custom-merge $o $a $b 0 'text'" &&
 153        sed -e 1,3d $a >check-2 &&
 154        cmp check-1 check-2 &&
 155        sed -e 1,3d -e 4q $a >check-3 &&
 156        echo "path is text" >expect &&
 157        cmp expect check-3 &&
 158        rm -f $o $a $b
 159'
 160
 161test_expect_success 'up-to-date merge without common ancestor' '
 162        test_create_repo repo1 &&
 163        test_create_repo repo2 &&
 164        test_tick &&
 165        (
 166                cd repo1 &&
 167                >a &&
 168                git add a &&
 169                git commit -m initial
 170        ) &&
 171        test_tick &&
 172        (
 173                cd repo2 &&
 174                git commit --allow-empty -m initial
 175        ) &&
 176        test_tick &&
 177        (
 178                cd repo1 &&
 179                git fetch ../repo2 master &&
 180                git merge --allow-unrelated-histories FETCH_HEAD
 181        )
 182'
 183
 184test_expect_success 'custom merge does not lock index' '
 185        git reset --hard anchor &&
 186        write_script sleep-an-hour.sh <<-\EOF &&
 187                sleep 3600 &
 188                echo $! >sleep.pid
 189        EOF
 190
 191        test_write_lines >.gitattributes \
 192                "* merge=ours" "text merge=sleep-an-hour" &&
 193        test_config merge.ours.driver true &&
 194        test_config merge.sleep-an-hour.driver ./sleep-an-hour.sh &&
 195
 196        # We are testing that the custom merge driver does not block
 197        # index.lock on Windows due to an inherited file handle.
 198        # To ensure that the backgrounded process ran sufficiently
 199        # long (and has been started in the first place), we do not
 200        # ignore the result of the kill command.
 201        # By packaging the command in test_when_finished, we get both
 202        # the correctness check and the clean-up.
 203        test_when_finished "kill \$(cat sleep.pid)" &&
 204        git merge master
 205'
 206
 207test_done