4f2b674e5de6e4b9c8c4ab9fd9684d99aa1cae50
   1#!/bin/bash
   2. shellopts.sh
   3set -e
   4
   5create()
   6{
   7        echo "$1" >"$1"
   8        git add "$1"
   9}
  10
  11check()
  12{
  13        echo
  14        echo "check:" "$@"
  15        if "$@"; then
  16                echo ok
  17                return 0
  18        else
  19                echo FAILED
  20                exit 1
  21        fi
  22}
  23
  24check_equal()
  25{
  26        echo
  27        echo "check a:" "$1"
  28        echo "      b:" "$2"
  29        if [ "$1" = "$2" ]; then
  30                return 0
  31        else
  32                echo FAILED
  33                exit 1
  34        fi
  35}
  36
  37fixnl()
  38{       
  39        t=""
  40        while read x; do
  41                t="$t$x "
  42        done
  43        echo $t
  44}
  45
  46multiline()
  47{
  48        while read x; do
  49                set -- $x
  50                for d in "$@"; do
  51                        echo "$d"
  52                done
  53        done
  54}
  55
  56rm -rf mainline subproj
  57mkdir mainline subproj
  58
  59cd subproj
  60git init
  61
  62create sub1
  63git commit -m 'sub1'
  64git branch sub1
  65git branch -m master subproj
  66check true
  67
  68create sub2
  69git commit -m 'sub2'
  70git branch sub2
  71
  72create sub3
  73git commit -m 'sub3'
  74git branch sub3
  75
  76cd ../mainline
  77git init
  78create main4
  79git commit -m 'main4'
  80git branch -m master mainline
  81
  82git fetch ../subproj sub1
  83git branch sub1 FETCH_HEAD
  84git subtree add --prefix=subdir FETCH_HEAD
  85
  86# this shouldn't actually do anything, since FETCH_HEAD is already a parent
  87git merge -m 'merge -s -ours' -s ours FETCH_HEAD
  88
  89create subdir/main-sub5
  90git commit -m 'main-sub5'
  91
  92create main6
  93git commit -m 'main6 boring'
  94
  95create subdir/main-sub7
  96git commit -m 'main-sub7'
  97
  98git fetch ../subproj sub2
  99git branch sub2 FETCH_HEAD
 100git subtree merge --prefix=subdir FETCH_HEAD
 101git branch pre-split
 102
 103split1=$(git subtree split --annotate='*' --prefix subdir --onto FETCH_HEAD --rejoin)
 104echo "split1={$split1}"
 105git branch split1 "$split1"
 106
 107create subdir/main-sub8
 108git commit -m 'main-sub8'
 109
 110cd ../subproj
 111git fetch ../mainline split1
 112git branch split1 FETCH_HEAD
 113git merge FETCH_HEAD
 114
 115create sub9
 116git commit -m 'sub9'
 117
 118cd ../mainline
 119split2=$(git subtree split --annotate='*' --prefix subdir --rejoin)
 120git branch split2 "$split2"
 121
 122create subdir/main-sub10
 123git commit -m 'main-sub10'
 124
 125split3=$(git subtree split --annotate='*' --prefix subdir --rejoin)
 126git branch split3 "$split3"
 127
 128cd ../subproj
 129git fetch ../mainline split3
 130git branch split3 FETCH_HEAD
 131git merge FETCH_HEAD
 132git branch subproj-merge-split3
 133
 134chkm="main4 main6"
 135chkms="main-sub10 main-sub5 main-sub7 main-sub8"
 136chkms_sub=$(echo $chkms | multiline | sed 's,^,subdir/,' | fixnl)
 137chks="sub1 sub2 sub3 sub9"
 138chks_sub=$(echo $chks | multiline | sed 's,^,subdir/,' | fixnl)
 139
 140# make sure exactly the right set of files ends up in the subproj
 141subfiles=$(git ls-files | fixnl)
 142check_equal "$subfiles" "$chkms $chks"
 143
 144# make sure the subproj history *only* contains commits that affect the subdir.
 145allchanges=$(git log --name-only --pretty=format:'' | sort | fixnl)
 146check_equal "$allchanges" "$chkms $chks"
 147
 148cd ../mainline
 149git fetch ../subproj subproj-merge-split3
 150git branch subproj-merge-split3 FETCH_HEAD
 151git subtree pull --prefix=subdir ../subproj subproj-merge-split3
 152
 153# make sure exactly the right set of files ends up in the mainline
 154mainfiles=$(git ls-files | fixnl)
 155check_equal "$mainfiles" "$chkm $chkms_sub $chks_sub"
 156
 157# make sure each filename changed exactly once in the entire history.
 158# 'main-sub??' and '/subdir/main-sub??' both change, because those are the
 159# changes that were split into their own history.  And 'subdir/sub??' never
 160# change, since they were *only* changed in the subtree branch.
 161allchanges=$(git log --name-only --pretty=format:'' | sort | fixnl)
 162check_equal "$allchanges" "$chkm $chkms $chks $chkms_sub"
 163