b2bca771cc6cda9fa6fca00214302f5167451f8e
   1#!/bin/sh
   2#
   3#        ,---E--.   *H----------.             * marks !TREESAME parent paths
   4#       /        \ /             \*
   5# *A--*B---D--*F-*G---------K-*L-*M
   6#   \     /*       \       /
   7#    `-C-'          `-*I-*J
   8#
   9# A creates "file", B and F change it.
  10# Odd merge G takes the old version from B.
  11# I changes it, but J reverts it, so K is TREESAME to both parents.
  12# H and L both change "file", and M merges those changes.
  13
  14test_description='TREESAME and limiting'
  15
  16. ./test-lib.sh
  17
  18note () {
  19        git tag "$1"
  20}
  21
  22unnote () {
  23        git name-rev --tags --stdin | sed -e "s|$_x40 (tags/\([^)]*\)) |\1 |g"
  24}
  25
  26test_expect_success setup '
  27        test_commit "Initial file" file "Hi there" A &&
  28        git branch other-branch &&
  29
  30        test_commit "file=Hello" file "Hello" B &&
  31        git branch third-branch &&
  32
  33        git checkout other-branch &&
  34        test_commit "Added other" other "Hello" C &&
  35
  36        git checkout master &&
  37        test_merge D other-branch &&
  38
  39        git checkout third-branch &&
  40        test_commit "Third file" third "Nothing" E &&
  41
  42        git checkout master &&
  43        test_commit "file=Blah" file "Blah" F &&
  44
  45        test_tick && git merge --no-commit third-branch &&
  46        git checkout third-branch file &&
  47        git commit &&
  48        note G &&
  49        git branch fiddler-branch &&
  50
  51        git checkout -b part2-branch &&
  52        test_commit "file=Part 2" file "Part 2" H &&
  53
  54        git checkout fiddler-branch &&
  55        test_commit "Bad commit" file "Silly" I &&
  56
  57        test_tick && git revert I && note J &&
  58
  59        git checkout master &&
  60        test_tick && git merge --no-ff fiddler-branch &&
  61        note K
  62
  63        test_commit "file=Part 1" file "Part 1" L &&
  64
  65        test_tick && test_must_fail git merge part2-branch &&
  66        test_commit M file "Parts 1+2"
  67'
  68
  69FMT='tformat:%P         %H | %s'
  70
  71# could we soup this up to optionally check parents? So "(BA)C" would check
  72# that C is shown and has parents B A.
  73check_outcome () {
  74        outcome=$1
  75        shift
  76        for c in $1
  77        do
  78                echo "$c"
  79        done >expect &&
  80        shift &&
  81        param="$*" &&
  82        test_expect_$outcome "log $param" '
  83                git log --format="$FMT" $param |
  84                unnote >actual &&
  85                sed -e "s/^.*   \([^ ]*\) .*/\1/" >check <actual &&
  86                test_cmp expect check || {
  87                        cat actual
  88                        false
  89                }
  90        '
  91}
  92
  93check_result () {
  94        check_outcome success "$@"
  95}
  96
  97# Odd merge G drops a change in F. Important that G is listed in all
  98# except the most basic list. Achieving this means normal merge D will also be
  99# shown in normal full-history, as we can't distinguish unless we do a
 100# simplification pass. After simplification, D is dropped but G remains.
 101check_result 'M L K J I H G F E D C B A'
 102check_result 'M H L K J I G E F D C B A' --topo-order
 103check_result 'M L H B A' -- file
 104check_result 'M L H B A' --parents -- file
 105check_outcome failure 'M L J I H G F D B A' --full-history -- file # drops G
 106check_result 'M L K J I H G F D B A' --full-history --parents -- file
 107check_outcome failure 'M H L J I G F B A' --simplify-merges -- file # drops G
 108check_result 'M L K G F D B A' --first-parent
 109check_result 'M L G F B A' --first-parent -- file
 110
 111# Check that odd merge G remains shown when F is the bottom.
 112check_result 'M L K J I H G E' F..M
 113check_result 'M H L K J I G E' F..M --topo-order
 114check_result 'M L H' F..M -- file
 115check_result 'M L H' F..M --parents -- file # L+H's parents rewritten to B, so more useful than it may seem
 116check_outcome failure 'M L J I H G' F..M --full-history -- file # drops G
 117check_result 'M L K J I H G' F..M --full-history --parents -- file
 118check_outcome failure 'M H L J I G' F..M --simplify-merges -- file # drops G
 119check_result 'M L K J I H G' F..M --ancestry-path
 120check_outcome failure 'M L J I H G' F..M --ancestry-path -- file # drops G
 121check_result 'M L K J I H G' F..M --ancestry-path --parents -- file
 122check_result 'M H L J I G' F..M --ancestry-path --simplify-merges -- file
 123check_result 'M L K G' F..M --first-parent
 124check_result 'M L G' F..M --first-parent -- file
 125
 126# Note that G is pruned when E is the bottom, even if it's the same commit list
 127# If we want history since E, then we're quite happy to ignore G that took E.
 128check_result 'M L K J I H G' E..M --ancestry-path
 129check_result 'M L J I H' E..M --ancestry-path -- file
 130check_outcome failure 'M L K J I H' E..M --ancestry-path --parents -- file # includes G
 131check_outcome failure 'M H L J I' E..M --ancestry-path --simplify-merges -- file # includes G
 132
 133# Should still be able to ignore I-J branch in simple log, despite limiting
 134# to G.
 135check_result 'M L K J I H' G..M
 136check_result 'M H L K J I' G..M --topo-order
 137check_outcome failure 'M L H' G..M -- file # includes J I
 138check_outcome failure 'M L H' G..M --parents -- file # includes J I
 139check_result 'M L J I H' G..M --full-history -- file
 140check_result 'M L K J I H' G..M --full-history --parents -- file
 141check_result 'M H L J I' G..M --simplify-merges -- file
 142check_result 'M L K J I H' G..M --ancestry-path
 143check_result 'M L J I H' G..M --ancestry-path -- file
 144check_result 'M L K J I H' G..M --ancestry-path --parents -- file
 145check_result 'M H L J I' G..M --ancestry-path --simplify-merges -- file
 146
 147# B..F should be able to simplify the merge D from irrelevant side branch C.
 148# Default log should also be free to follow B-D, and ignore C.
 149# But --full-history shouldn't drop D on its own - without simplification,
 150# we can't decide if the merge from INTERESTING commit C was sensible.
 151check_result 'F D C' B..F
 152check_result 'F' B..F -- file
 153check_outcome failure 'F' B..F --parents -- file # includes D
 154check_outcome failure 'F D' B..F --full-history -- file # drops D prematurely
 155check_result 'F D' B..F --full-history --parents -- file
 156check_result 'F' B..F --simplify-merges -- file
 157check_result 'F D' B..F --ancestry-path
 158check_result 'F' B..F --ancestry-path -- file
 159check_outcome failure 'F' B..F --ancestry-path --parents -- file # includes D
 160check_outcome failure 'F' B..F --ancestry-path --simplify-merges -- file # includes D
 161check_result 'F D' B..F --first-parent
 162check_result 'F' B..F --first-parent -- file
 163
 164# E...F should be equivalent to E F ^B, and be able to drop D as above.
 165check_result 'F' E F ^B -- file
 166check_result 'F' E...F -- file
 167
 168# Any sort of full history of C..F should show D, as it's the connection to C,
 169# and it differs from it.
 170check_result 'F D B' C..F
 171check_result 'F B' C..F -- file
 172check_result 'F B' C..F --parents -- file
 173check_outcome failure 'F D B' C..F --full-history -- file # drops D
 174check_result 'F D B' C..F --full-history --parents -- file
 175check_result 'F D B' C..F --simplify-merges -- file
 176check_result 'F D' C..F --ancestry-path
 177check_outcome failure 'F D' C..F --ancestry-path -- file # drops D
 178check_result 'F D' C..F --ancestry-path --parents -- file
 179check_result 'F D' C..F --ancestry-path --simplify-merges -- file
 180check_result 'F D B' C..F --first-parent
 181check_result 'F B' C..F --first-parent -- file
 182
 183
 184test_done