#!/bin/sh global 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'' source ./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 (CommandList children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:test_description) op: Equal rhs: { (SQ <"git add -u\n"> <"\n"> <"This test creates a working tree state with three files:\n"> <"\n"> <" top (previously committed, modified)\n"> <" dir/sub (previously committed, modified)\n"> <" dir/other (untracked)\n"> <"\n"> <"and issues a git add -u with path limiting on \"dir\" to add\n"> <"only the updates to dir/sub.\n"> <"\n"> <"Also tested are \"git add -u\" without limiting, and \"git add -u\"\n"> <"without contents changes, and other conditions"> ) } spids: [4] ) ] spids: [4] ) (C {(.)} {(./test-lib.sh)}) (C {(test_expect_success)} {(setup)} { (SQ <"\n"> <"\techo initial >check &&\n"> <"\techo initial >top &&\n"> <"\techo initial >foo &&\n"> <"\tmkdir dir1 dir2 &&\n"> <"\techo initial >dir1/sub1 &&\n"> <"\techo initial >dir1/sub2 &&\n"> <"\techo initial >dir2/sub3 &&\n"> <"\tgit add check dir1 dir2 top foo &&\n"> <"\ttest_tick &&\n"> <"\tgit commit -m initial &&\n"> <"\n"> <"\techo changed >check &&\n"> <"\techo changed >top &&\n"> <"\techo changed >dir2/sub3 &&\n"> <"\trm -f dir1/sub1 &&\n"> <"\techo other >dir2/other\n"> ) } ) (C {(test_expect_success)} {(update)} {(SQ <"\n"> <"\tgit add -u dir1 dir2\n">)}) (C {(test_expect_success)} {(SQ <"update noticed a removal">)} {(SQ <"\n"> <"\ttest \"$(git ls-files dir1/sub1)\" = \"\"\n">)} ) (C {(test_expect_success)} {(SQ <"update touched correct path">)} {(SQ <"\n"> <"\ttest \"$(git diff-files --name-status dir2/sub3)\" = \"\"\n">)} ) (C {(test_expect_success)} {(SQ <"update did not touch other tracked files">)} { (SQ <"\n"> <"\ttest \"$(git diff-files --name-status check)\" = \"M\tcheck\" &&\n"> <"\ttest \"$(git diff-files --name-status top)\" = \"M\ttop\"\n"> ) } ) (C {(test_expect_success)} {(SQ <"update did not touch untracked files">)} {(SQ <"\n"> <"\ttest \"$(git ls-files dir2/other)\" = \"\"\n">)} ) (C {(test_expect_success)} {(SQ <"cache tree has not been corrupted">)} { (SQ <"\n"> <"\n"> <"\tgit ls-files -s |\n"> <"\tsed -e \"s/ 0\t/\t/\" >expect &&\n"> <"\tgit ls-tree -r $(git write-tree) |\n"> <"\tsed -e \"s/ blob / /\" >current &&\n"> <"\ttest_cmp expect current\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"update from a subdirectory">)} { (SQ <"\n"> <"\t(\n"> <"\t\tcd dir1 &&\n"> <"\t\techo more >sub2 &&\n"> <"\t\tgit add -u sub2\n"> <"\t)\n"> ) } ) (C {(test_expect_success)} {(SQ <"change gets noticed">)} {(SQ <"\n"> <"\n"> <"\ttest \"$(git diff-files --name-status dir1)\" = \"\"\n"> <"\n">)} ) (C {(test_expect_success)} {(SQ <"non-qualified update in subdir updates from the root">)} { (SQ <"\n"> <"\t(\n"> <"\t\tcd dir1 &&\n"> <"\t\techo even more >>sub2 &&\n"> <"\t\tgit --literal-pathspecs add -u &&\n"> <"\t\techo even more >>sub2 &&\n"> <"\t\tgit add -u\n"> <"\t) &&\n"> <"\t: >expect &&\n"> <"\tgit diff-files --name-only >actual &&\n"> <"\ttest_cmp expect actual\n"> ) } ) (C {(test_expect_success)} {(SQ <"replace a file with a symlink">)} {(SQ <"\n"> <"\n"> <"\trm foo &&\n"> <"\ttest_ln_s_add top foo\n"> <"\n">)} ) (C {(test_expect_success)} {(SQ <"add everything changed">)} {(SQ <"\n"> <"\n"> <"\tgit add -u &&\n"> <"\ttest -z \"$(git diff-files)\"\n"> <"\n">)} ) (C {(test_expect_success)} {(SQ <"touch and then add -u">)} { (SQ <"\n"> <"\n"> <"\ttouch check &&\n"> <"\tgit add -u &&\n"> <"\ttest -z \"$(git diff-files)\"\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"touch and then add explicitly">)} { (SQ <"\n"> <"\n"> <"\ttouch check &&\n"> <"\tgit add check &&\n"> <"\ttest -z \"$(git diff-files)\"\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"add -n -u should not add but just report">)} {(SQ <"\n"> <"\n"> <"\t(\n"> <"\t\techo \"add ">) (EscapedLiteralPart token:) (SQ ) (EscapedLiteralPart token:) (SQ <"\" &&\n"> <"\t\techo \"remove ">) (EscapedLiteralPart token:) (SQ ) (EscapedLiteralPart token:) (SQ <"\"\n"> <"\t) >expect &&\n"> <"\tbefore=$(git ls-files -s check top) &&\n"> <"\techo changed >>check &&\n"> <"\trm -f top &&\n"> <"\tgit add -n -u >actual &&\n"> <"\tafter=$(git ls-files -s check top) &&\n"> <"\n"> <"\ttest \"$before\" = \"$after\" &&\n"> <"\ttest_i18ncmp expect actual\n"> <"\n"> ) } ) (C {(test_expect_success)} {(SQ <"add -u resolves unmerged paths">)} { (SQ <"\n"> <"\tgit reset --hard &&\n"> <"\tone=$(echo 1 | git hash-object -w --stdin) &&\n"> <"\ttwo=$(echo 2 | git hash-object -w --stdin) &&\n"> <"\tthree=$(echo 3 | git hash-object -w --stdin) &&\n"> <"\t{\n"> <"\t\tfor path in path1 path2\n"> <"\t\tdo\n"> <"\t\t\techo \"100644 $one 1\t$path\"\n"> <"\t\t\techo \"100644 $two 2\t$path\"\n"> <"\t\t\techo \"100644 $three 3\t$path\"\n"> <"\t\tdone\n"> <"\t\techo \"100644 $one 1\tpath3\"\n"> <"\t\techo \"100644 $one 1\tpath4\"\n"> <"\t\techo \"100644 $one 3\tpath5\"\n"> <"\t\techo \"100644 $one 3\tpath6\"\n"> <"\t} |\n"> <"\tgit update-index --index-info &&\n"> <"\techo 3 >path1 &&\n"> <"\techo 2 >path3 &&\n"> <"\techo 2 >path5 &&\n"> <"\n"> <"\t# Fail to explicitly resolve removed paths with \"git add\"\n"> <"\ttest_must_fail git add --no-all path4 &&\n"> <"\ttest_must_fail git add --no-all path6 &&\n"> <"\n"> <"\t# \"add -u\" should notice removals no matter what stages\n"> <"\t# the index entries are in.\n"> <"\tgit add -u &&\n"> <"\tgit ls-files -s path1 path2 path3 path4 path5 path6 >actual &&\n"> <"\t{\n"> <"\t\techo \"100644 $three 0\tpath1\"\n"> <"\t\techo \"100644 $two 0\tpath3\"\n"> <"\t\techo \"100644 $two 0\tpath5\"\n"> <"\t} >expect &&\n"> <"\ttest_cmp expect actual\n"> ) } ) (C {(test_expect_success)} {(SQ <"\"add -u non-existent\" should fail">)} { (SQ <"\n"> <"\ttest_must_fail git add -u non-existent &&\n"> <"\t! (git ls-files | grep \"non-existent\")\n"> ) } ) (C {(test_done)}) ] )