git/t/t6019-rev-list-ancestry-path.sh
Elijah Newren 257418c590 revision: allow --ancestry-path to take an argument
We have long allowed users to run e.g.
    git log --ancestry-path master..seen
which shows all commits which satisfy all three of these criteria:
  * are an ancestor of seen
  * are not an ancestor of master
  * have master as an ancestor

This commit allows another variant:
    git log --ancestry-path=$TOPIC master..seen
which shows all commits which satisfy all of these criteria:
  * are an ancestor of seen
  * are not an ancestor of master
  * have $TOPIC in their ancestry-path
that last bullet can be defined as commits meeting any of these
criteria:
    * are an ancestor of $TOPIC
    * have $TOPIC as an ancestor
    * are $TOPIC

This also allows multiple --ancestry-path arguments, which can be
used to find commits with any of the given topics in their ancestry
path.

Signed-off-by: Elijah Newren <newren@gmail.com>
Acked-by: Derrick Stolee <derrickstolee@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-08-19 10:45:08 -07:00

133 lines
3.3 KiB
Bash
Executable File

#!/bin/sh
test_description='--ancestry-path'
# D---E-------F
# / \ \
# B---C---G---H---I---J
# / \
# A-------K---------------L--M
#
# D..M == E F G H I J K L M
# --ancestry-path D..M == E F H I J L M
# --ancestry-path=F D..M == E F J L M
# --ancestry-path=G D..M == G H I J L M
# --ancestry-path=H D..M == E G H I J L M
# --ancestry-path=K D..M == K L M
# --ancestry-path=K --ancestry-path=F D..M == E F J K L M
#
# D..M -- M.t == M
# --ancestry-path D..M -- M.t == M
#
# F...I == F G H I
# --ancestry-path F...I == F H I
#
# G..M -- G.t == [nothing - was dropped in "-s ours" merge L]
# --ancestry-path G..M -- G.t == L
# --ancestry-path --simplify-merges G^..M -- G.t == G L
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
. ./test-lib.sh
test_merge () {
test_tick &&
git merge -s ours -m "$2" "$1" &&
git tag "$2"
}
test_expect_success setup '
test_commit A &&
test_commit B &&
test_commit C &&
test_commit D &&
test_commit E &&
test_commit F &&
git reset --hard C &&
test_commit G &&
test_merge E H &&
test_commit I &&
test_merge F J &&
git reset --hard A &&
test_commit K &&
test_merge J L &&
test_commit M
'
test_ancestry () {
args=$1
expected=$2
test_expect_success "log $args" "
test_write_lines $expected >expect &&
git log --format=%s $args >raw &&
if test -n \"$expected\"
then
sort raw >actual &&
test_cmp expect actual
else
test_must_be_empty raw
fi
"
}
test_ancestry "D..M" "E F G H I J K L M"
test_ancestry "--ancestry-path D..M" "E F H I J L M"
test_ancestry "--ancestry-path=F D..M" "E F J L M"
test_ancestry "--ancestry-path=G D..M" "G H I J L M"
test_ancestry "--ancestry-path=H D..M" "E G H I J L M"
test_ancestry "--ancestry-path=K D..M" "K L M"
test_ancestry "--ancestry-path=F --ancestry-path=K D..M" "E F J K L M"
test_ancestry "D..M -- M.t" "M"
test_ancestry "--ancestry-path D..M -- M.t" "M"
test_ancestry "F...I" "F G H I"
test_ancestry "--ancestry-path F...I" "F H I"
test_ancestry "G..M -- G.t" ""
test_ancestry "--ancestry-path G..M -- G.t" "L"
test_ancestry "--ancestry-path --simplify-merges G^..M -- G.t" "G L"
# b---bc
# / \ /
# a X
# \ / \
# c---cb
#
# All refnames prefixed with 'x' to avoid confusion with the tags
# generated by test_commit on case-insensitive systems.
test_expect_success 'setup criss-cross' '
mkdir criss-cross &&
(cd criss-cross &&
git init &&
test_commit A &&
git checkout -b xb main &&
test_commit B &&
git checkout -b xc main &&
test_commit C &&
git checkout -b xbc xb -- &&
git merge xc &&
git checkout -b xcb xc -- &&
git merge xb &&
git checkout main)
'
# no commits in bc descend from cb
test_expect_success 'criss-cross: rev-list --ancestry-path cb..bc' '
(cd criss-cross &&
git rev-list --ancestry-path xcb..xbc > actual &&
test_must_be_empty actual)
'
# no commits in repository descend from cb
test_expect_success 'criss-cross: rev-list --ancestry-path --all ^cb' '
(cd criss-cross &&
git rev-list --ancestry-path --all ^xcb > actual &&
test_must_be_empty actual)
'
test_done