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>
		
	
		
			
				
	
	
		
			133 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			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
 |