| #!/bin/sh | 
 |  | 
 | test_description='git add -u | 
 |  | 
 | This test creates a working tree state with three files: | 
 |  | 
 |   top (previously committed, modified) | 
 |   dir/sub (previously committed, modified) | 
 |   dir/other (untracked) | 
 |  | 
 | and issues a git add -u with path limiting on "dir" to add | 
 | only the updates to dir/sub. | 
 |  | 
 | Also tested are "git add -u" without limiting, and "git add -u" | 
 | without contents changes, and other conditions' | 
 |  | 
 | . ./test-lib.sh | 
 |  | 
 | test_expect_success setup ' | 
 | 	echo initial >check && | 
 | 	echo initial >top && | 
 | 	echo initial >foo && | 
 | 	mkdir dir1 dir2 && | 
 | 	echo initial >dir1/sub1 && | 
 | 	echo initial >dir1/sub2 && | 
 | 	echo initial >dir2/sub3 && | 
 | 	git add check dir1 dir2 top foo && | 
 | 	test_tick && | 
 | 	git commit -m initial && | 
 |  | 
 | 	echo changed >check && | 
 | 	echo changed >top && | 
 | 	echo changed >dir2/sub3 && | 
 | 	rm -f dir1/sub1 && | 
 | 	echo other >dir2/other | 
 | ' | 
 |  | 
 | test_expect_success update ' | 
 | 	git add -u dir1 dir2 | 
 | ' | 
 |  | 
 | test_expect_success 'update noticed a removal' ' | 
 | 	test "$(git ls-files dir1/sub1)" = "" | 
 | ' | 
 |  | 
 | test_expect_success 'update touched correct path' ' | 
 | 	test "$(git diff-files --name-status dir2/sub3)" = "" | 
 | ' | 
 |  | 
 | test_expect_success 'update did not touch other tracked files' ' | 
 | 	test "$(git diff-files --name-status check)" = "M	check" && | 
 | 	test "$(git diff-files --name-status top)" = "M	top" | 
 | ' | 
 |  | 
 | test_expect_success 'update did not touch untracked files' ' | 
 | 	test "$(git ls-files dir2/other)" = "" | 
 | ' | 
 |  | 
 | test_expect_success 'cache tree has not been corrupted' ' | 
 |  | 
 | 	git ls-files -s | | 
 | 	sed -e "s/ 0	/	/" >expect && | 
 | 	git ls-tree -r $(git write-tree) | | 
 | 	sed -e "s/ blob / /" >current && | 
 | 	test_cmp expect current | 
 |  | 
 | ' | 
 |  | 
 | test_expect_success 'update from a subdirectory' ' | 
 | 	( | 
 | 		cd dir1 && | 
 | 		echo more >sub2 && | 
 | 		git add -u sub2 | 
 | 	) | 
 | ' | 
 |  | 
 | test_expect_success 'change gets noticed' ' | 
 |  | 
 | 	test "$(git diff-files --name-status dir1)" = "" | 
 |  | 
 | ' | 
 |  | 
 | test_expect_success 'non-qualified update in subdir updates from the root' ' | 
 | 	( | 
 | 		cd dir1 && | 
 | 		echo even more >>sub2 && | 
 | 		git --literal-pathspecs add -u && | 
 | 		echo even more >>sub2 && | 
 | 		git add -u | 
 | 	) && | 
 | 	: >expect && | 
 | 	git diff-files --name-only >actual && | 
 | 	test_cmp expect actual | 
 | ' | 
 |  | 
 | test_expect_success 'replace a file with a symlink' ' | 
 |  | 
 | 	rm foo && | 
 | 	test_ln_s_add top foo | 
 |  | 
 | ' | 
 |  | 
 | test_expect_success 'add everything changed' ' | 
 |  | 
 | 	git add -u && | 
 | 	test -z "$(git diff-files)" | 
 |  | 
 | ' | 
 |  | 
 | test_expect_success 'touch and then add -u' ' | 
 |  | 
 | 	touch check && | 
 | 	git add -u && | 
 | 	test -z "$(git diff-files)" | 
 |  | 
 | ' | 
 |  | 
 | test_expect_success 'touch and then add explicitly' ' | 
 |  | 
 | 	touch check && | 
 | 	git add check && | 
 | 	test -z "$(git diff-files)" | 
 |  | 
 | ' | 
 |  | 
 | test_expect_success 'add -n -u should not add but just report' ' | 
 |  | 
 | 	( | 
 | 		echo "add '\''check'\''" && | 
 | 		echo "remove '\''top'\''" | 
 | 	) >expect && | 
 | 	before=$(git ls-files -s check top) && | 
 | 	echo changed >>check && | 
 | 	rm -f top && | 
 | 	git add -n -u >actual && | 
 | 	after=$(git ls-files -s check top) && | 
 |  | 
 | 	test "$before" = "$after" && | 
 | 	test_i18ncmp expect actual | 
 |  | 
 | ' | 
 |  | 
 | test_expect_success 'add -u resolves unmerged paths' ' | 
 | 	git reset --hard && | 
 | 	one=$(echo 1 | git hash-object -w --stdin) && | 
 | 	two=$(echo 2 | git hash-object -w --stdin) && | 
 | 	three=$(echo 3 | git hash-object -w --stdin) && | 
 | 	{ | 
 | 		for path in path1 path2 | 
 | 		do | 
 | 			echo "100644 $one 1	$path" | 
 | 			echo "100644 $two 2	$path" | 
 | 			echo "100644 $three 3	$path" | 
 | 		done | 
 | 		echo "100644 $one 1	path3" | 
 | 		echo "100644 $one 1	path4" | 
 | 		echo "100644 $one 3	path5" | 
 | 		echo "100644 $one 3	path6" | 
 | 	} | | 
 | 	git update-index --index-info && | 
 | 	echo 3 >path1 && | 
 | 	echo 2 >path3 && | 
 | 	echo 2 >path5 && | 
 |  | 
 | 	# Fail to explicitly resolve removed paths with "git add" | 
 | 	test_must_fail git add --no-all path4 && | 
 | 	test_must_fail git add --no-all path6 && | 
 |  | 
 | 	# "add -u" should notice removals no matter what stages | 
 | 	# the index entries are in. | 
 | 	git add -u && | 
 | 	git ls-files -s path1 path2 path3 path4 path5 path6 >actual && | 
 | 	{ | 
 | 		echo "100644 $three 0	path1" | 
 | 		echo "100644 $two 0	path3" | 
 | 		echo "100644 $two 0	path5" | 
 | 	} >expect && | 
 | 	test_cmp expect actual | 
 | ' | 
 |  | 
 | test_expect_success '"add -u non-existent" should fail' ' | 
 | 	test_must_fail git add -u non-existent && | 
 | 	! (git ls-files | grep "non-existent") | 
 | ' | 
 |  | 
 | test_done |