<commit_before><commit_msg>tests: document cherry-pick behavior in face of conflicts<commit_after>#!/bin/sh

test_description='test cherry-pick and revert with conflicts

  -
  + picked: rewrites foo to c
  + base: rewrites foo to b
  + initial: writes foo as a, unrelated as unrelated

'

. ./test-lib.sh

test_expect_success setup '

	echo unrelated >unrelated &&
	git add unrelated &&
	test_commit initial foo a &&
	test_commit base foo b &&
	test_commit picked foo c &&
	git config advice.detachedhead false

'

test_expect_success 'failed cherry-pick does not advance HEAD' '

	git checkout -f initial^0 &&
	git read-tree -u --reset HEAD &&
	git clean -d -f -f -q -x &&

	git update-index --refresh &&
	git diff-index --exit-code HEAD &&

	head=$(git rev-parse HEAD) &&
	test_must_fail git cherry-pick picked &&
	newhead=$(git rev-parse HEAD) &&

	test "$head" = "$newhead"
'

test_expect_success 'failed cherry-pick produces dirty index' '

	git checkout -f initial^0 &&
	git read-tree -u --reset HEAD &&
	git clean -d -f -f -q -x &&

	git update-index --refresh &&
	git diff-index --exit-code HEAD &&

	test_must_fail git cherry-pick picked &&

	test_must_fail git update-index --refresh -q &&
	test_must_fail git diff-index --exit-code HEAD
'

test_expect_success 'failed cherry-pick registers participants in index' '

	git read-tree -u --reset HEAD &&
	git clean -d -f -f -q -x &&
	{
		git checkout base -- foo &&
		git ls-files --stage foo &&
		git checkout initial -- foo &&
		git ls-files --stage foo &&
		git checkout picked -- foo &&
		git ls-files --stage foo
	} > stages &&
	sed "
		1 s/ 0	/ 1	/
		2 s/ 0	/ 2	/
		3 s/ 0	/ 3	/
	" < stages > expected &&
	git checkout -f initial^0 &&

	git update-index --refresh &&
	git diff-index --exit-code HEAD &&

	test_must_fail git cherry-pick picked &&
	git ls-files --stage --unmerged > actual &&

	test_cmp expected actual
'

test_expect_success 'failed cherry-pick describes conflict in work tree' '

	git checkout -f initial^0 &&
	git read-tree -u --reset HEAD &&
	git clean -d -f -f -q -x &&
	cat <<-EOF > expected &&
	<<<<<<< HEAD
	a
	=======
	c
	>>>>>>> objid picked
	EOF

	git update-index --refresh &&
	git diff-index --exit-code HEAD &&

	test_must_fail git cherry-pick picked &&

	sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
	test_cmp expected actual
'

test_expect_success 'diff3 -m style' '

	git config merge.conflictstyle diff3 &&
	git checkout -f initial^0 &&
	git read-tree -u --reset HEAD &&
	git clean -d -f -f -q -x &&
	cat <<-EOF > expected &&
	<<<<<<< HEAD
	a
	|||||||
	b
	=======
	c
	>>>>>>> objid picked
	EOF

	git update-index --refresh &&
	git diff-index --exit-code HEAD &&

	test_must_fail git cherry-pick picked &&

	sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
	test_cmp expected actual
'

test_expect_success 'revert also handles conflicts sanely' '

	git config --unset merge.conflictstyle &&
	git read-tree -u --reset HEAD &&
	git clean -d -f -f -q -x &&
	cat <<-EOF > expected &&
	<<<<<<< HEAD
	a
	=======
	b
	>>>>>>> objid picked
	EOF
	{
		git checkout picked -- foo &&
		git ls-files --stage foo &&
		git checkout initial -- foo &&
		git ls-files --stage foo &&
		git checkout base -- foo &&
		git ls-files --stage foo
	} > stages &&
	sed "
		1 s/ 0	/ 1	/
		2 s/ 0	/ 2	/
		3 s/ 0	/ 3	/
	" < stages > expected-stages &&
	git checkout -f initial^0 &&

	git update-index --refresh &&
	git diff-index --exit-code HEAD &&

	head=$(git rev-parse HEAD) &&
	test_must_fail git revert picked &&
	newhead=$(git rev-parse HEAD) &&
	git ls-files --stage --unmerged > actual-stages &&

	test "$head" = "$newhead" &&
	test_must_fail git update-index --refresh -q &&
	test_must_fail git diff-index --exit-code HEAD &&
	test_cmp expected-stages actual-stages &&
	sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
	test_cmp expected actual
'

test_expect_success 'revert conflict, diff3 -m style' '
	git config merge.conflictstyle diff3 &&
	git checkout -f initial^0 &&
	git read-tree -u --reset HEAD &&
	git clean -d -f -f -q -x &&
	cat <<-EOF > expected &&
	<<<<<<< HEAD
	a
	|||||||
	c
	=======
	b
	>>>>>>> objid picked
	EOF

	git update-index --refresh &&
	git diff-index --exit-code HEAD &&

	test_must_fail git revert picked &&

	sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
	test_cmp expected actual
'

test_done

{'fraction_non_alphanumeric': 0.1581763200744359, 'fraction_numerical': 0.008606652709932543, 'mean_word_length': 2.765323992994746, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 46, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3605638', 'n_tokens_mistral': 1650, 'n_tokens_neox': 1515, 'n_words': 503}