(CommandList children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:test_description) op: Equal rhs: {(SQ <"Test of git add, including the -- option.">)} spids: [13] ) ] spids: [13] ) (C {(.)} {(./test-lib.sh)}) (FuncDef name: test_mode_in_index body: (BraceGroup children: [ (Case to_match: { (DQ (CommandSubPart command_list: (CommandList children: [(C {(git)} {(ls-files)} {(-s)} {(DQ ($ VSub_Number "$2"))})] ) left_token: <Left_CommandSub "$("> spids: [38 48] ) ) } arms: [ (case_arm pat_list: [ {(DQ ($ VSub_Number "$1") (" ")) (Lit_Other "*") (DQ ("\t") ($ VSub_Number "$2"))} ] action: [(C {(echo)} {(pass)})] spids: [55 63 71 -1] ) (case_arm pat_list: [{(Lit_Other "*")}] action: [ (C {(echo)} {(fail)}) (C {(git)} {(ls-files)} {(-s)} {(DQ ($ VSub_Number "$2"))}) (ControlFlow token:<ControlFlow_Return return> arg_word:{(1)}) ] spids: [74 75 99 -1] ) ] spids: [35 51 102] ) ] spids: [32] ) spids: [27 31] ) (C {(test_expect_success)} {(SQ <"Test of git add">)} {(SQ <"touch foo && git add foo">)}) (C {(test_expect_success)} {(SQ <"Post-check that foo is in the index">)} {(SQ <"git ls-files foo | grep foo">)} ) (C {(test_expect_success)} {(SQ <"Test that \"git add -- -q\" works">)} {(SQ <"touch -- -q && git add -- -q">)} ) (C {(test_expect_success)} {(SQ <"git add: Test that executable bit is not used if core.filemode=0">)} { (SQ <"git config core.filemode 0 &&\n"> <"\t echo foo >xfoo1 &&\n"> <"\t chmod 755 xfoo1 &&\n"> <"\t git add xfoo1 &&\n"> <"\t test_mode_in_index 100644 xfoo1"> ) } ) (C {(test_expect_success)} {(SQ <"git add: filemode=0 should not get confused by symlink">)} { (SQ <"\n"> <"\trm -f xfoo1 &&\n"> <"\ttest_ln_s_add foo xfoo1 &&\n"> <"\ttest_mode_in_index 120000 xfoo1\n"> ) } ) (C {(test_expect_success)} {(SQ <"git update-index --add: Test that executable bit is not used...">)} { (SQ <"git config core.filemode 0 &&\n"> <"\t echo foo >xfoo2 &&\n"> <"\t chmod 755 xfoo2 &&\n"> <"\t git update-index --add xfoo2 &&\n"> <"\t test_mode_in_index 100644 xfoo2"> ) } ) (C {(test_expect_success)} {(SQ <"git add: filemode=0 should not get confused by symlink">)} { (SQ <"\n"> <"\trm -f xfoo2 &&\n"> <"\ttest_ln_s_add foo xfoo2 &&\n"> <"\ttest_mode_in_index 120000 xfoo2\n"> ) } ) (C {(test_expect_success)} {(SQ <"git update-index --add: Test that executable bit is not used...">)} { (SQ <"git config core.filemode 0 &&\n"> <"\t test_ln_s_add xfoo2 xfoo3 &&\t# runs git update-index --add\n"> <"\t test_mode_in_index 120000 xfoo3"> ) } ) (C {(test_expect_success)} {(SQ <".gitignore test setup">)} { (SQ <"\n"> <"\techo \"*.ig\" >.gitignore &&\n"> <"\tmkdir c.if d.ig &&\n"> <"\t>a.ig && >b.if &&\n"> <"\t>c.if/c.if && >c.if/c.ig &&\n"> <"\t>d.ig/d.if && >d.ig/d.ig\n"> ) } ) (C {(test_expect_success)} {(SQ <".gitignore is honored">)} {(SQ <"\n"> <"\tgit add . &&\n"> <"\t! (git ls-files | grep \"\\\\.ig\")\n">)} ) (C {(test_expect_success)} {(SQ <"error out when attempting to add ignored ones without -f">)} { (SQ <"\n"> <"\ttest_must_fail git add a.?? &&\n"> <"\t! (git ls-files | grep \"\\\\.ig\")\n">) } ) (C {(test_expect_success)} {(SQ <"error out when attempting to add ignored ones without -f">)} { (SQ <"\n"> <"\ttest_must_fail git add d.?? &&\n"> <"\t! (git ls-files | grep \"\\\\.ig\")\n">) } ) (C {(test_expect_success)} {(SQ <"error out when attempting to add ignored ones but add others">)} { (SQ <"\n"> <"\ttouch a.if &&\n"> <"\ttest_must_fail git add a.?? &&\n"> <"\t! (git ls-files | grep \"\\\\.ig\") &&\n"> <"\t(git ls-files | grep a.if)\n"> ) } ) (C {(test_expect_success)} {(SQ <"add ignored ones with -f">)} {(SQ <"\n"> <"\tgit add -f a.?? &&\n"> <"\tgit ls-files --error-unmatch a.ig\n">)} ) (C {(test_expect_success)} {(SQ <"add ignored ones with -f">)} { (SQ <"\n"> <"\tgit add -f d.??/* &&\n"> <"\tgit ls-files --error-unmatch d.ig/d.if d.ig/d.ig\n"> ) } ) (C {(test_expect_success)} {(SQ <"add ignored ones with -f">)} { (SQ <"\n"> <"\trm -f .git/index &&\n"> <"\tgit add -f d.?? &&\n"> <"\tgit ls-files --error-unmatch d.ig/d.if d.ig/d.ig\n"> ) } ) (C {(test_expect_success)} {(SQ <".gitignore with subdirectory">)} { (SQ <"\n"> <"\n"> <"\trm -f .git/index &&\n"> <"\tmkdir -p sub/dir &&\n"> <"\techo \"!dir/a.*\" >sub/.gitignore &&\n"> <"\t>sub/a.ig &&\n"> <"\t>sub/dir/a.ig &&\n"> <"\tgit add sub/dir &&\n"> <"\tgit ls-files --error-unmatch sub/dir/a.ig &&\n"> <"\trm -f .git/index &&\n"> <"\t(\n"> <"\t\tcd sub/dir &&\n"> <"\t\tgit add .\n"> <"\t) &&\n"> <"\tgit ls-files --error-unmatch sub/dir/a.ig\n"> ) } ) (C {(mkdir)} {(1)} {(1/2)} {(1/3)}) (C {(touch)} {(1/2/a)} {(1/3/b)} {(1/2/c)}) (C {(test_expect_success)} {(SQ <"check correct prefix detection">)} {(SQ <"\n"> <"\trm -f .git/index &&\n"> <"\tgit add 1/2/a 1/3/b 1/2/c\n">)} ) (C {(test_expect_success)} {(SQ <"git add with filemode=0, symlinks=0, and unmerged entries">)} { (SQ <"\n"> <"\tfor s in 1 2 3\n"> <"\tdo\n"> <"\t\techo $s > stage$s\n"> <"\t\techo \"100755 $(git hash-object -w stage$s) $s\tfile\"\n"> <"\t\techo \"120000 $(printf $s | git hash-object -w -t blob --stdin) $s\tsymlink\"\n"> <"\tdone | git update-index --index-info &&\n"> <"\tgit config core.filemode 0 &&\n"> <"\tgit config core.symlinks 0 &&\n"> <"\techo new > file &&\n"> <"\techo new > symlink &&\n"> <"\tgit add file symlink &&\n"> <"\tgit ls-files --stage | grep \"^100755 .* 0\tfile$\" &&\n"> <"\tgit ls-files --stage | grep \"^120000 .* 0\tsymlink$\"\n"> ) } ) (C {(test_expect_success)} {(SQ <"git add with filemode=0, symlinks=0 prefers stage 2 over stage 1">)} { (SQ <"\n"> <"\tgit rm --cached -f file symlink &&\n"> <"\t(\n"> <"\t\techo \"100644 $(git hash-object -w stage1) 1\tfile\"\n"> <"\t\techo \"100755 $(git hash-object -w stage2) 2\tfile\"\n"> <"\t\techo \"100644 $(printf 1 | git hash-object -w -t blob --stdin) 1\tsymlink\"\n"> <"\t\techo \"120000 $(printf 2 | git hash-object -w -t blob --stdin) 2\tsymlink\"\n"> <"\t) | git update-index --index-info &&\n"> <"\tgit config core.filemode 0 &&\n"> <"\tgit config core.symlinks 0 &&\n"> <"\techo new > file &&\n"> <"\techo new > symlink &&\n"> <"\tgit add file symlink &&\n"> <"\tgit ls-files --stage | grep \"^100755 .* 0\tfile$\" &&\n"> <"\tgit ls-files --stage | grep \"^120000 .* 0\tsymlink$\"\n"> ) } ) (C {(test_expect_success)} {(SQ <"git add --refresh">)} { (SQ <"\n"> <"\t>foo && git add foo && git commit -a -m \"commit all\" &&\n"> <"\ttest -z \"$(git diff-index HEAD -- foo)\" &&\n"> <"\tgit read-tree HEAD &&\n"> <"\tcase \"$(git diff-index HEAD -- foo)\" in\n"> <"\t:100644\" \"*\"M\tfoo\") echo pass;;\n"> <"\t*) echo fail; (exit 1);;\n"> <"\tesac &&\n"> <"\tgit add --refresh -- foo &&\n"> <"\ttest -z \"$(git diff-index HEAD -- foo)\"\n"> ) } ) (C {(test_expect_success)} {(SQ <"git add --refresh with pathspec">)} { (SQ <"\n"> <"\tgit reset --hard &&\n"> <"\techo >foo && echo >bar && echo >baz &&\n"> <"\tgit add foo bar baz && H=$(git rev-parse :foo) && git rm -f foo &&\n"> <"\techo \"100644 $H 3\tfoo\" | git update-index --index-info &&\n"> <"\ttest-chmtime -60 bar baz &&\n"> <"\t>expect &&\n"> <"\tgit add --refresh bar >actual &&\n"> <"\ttest_cmp expect actual &&\n"> <"\n"> <"\tgit diff-files --name-only >actual &&\n"> <"\t! grep bar actual&&\n"> <"\tgrep baz actual\n"> ) } ) (C {(test_expect_success)} {(POSIXPERM) (Lit_Comma ",") (SANITY)} {(SQ <"git add should fail atomically upon an unreadable file">)} { (SQ <"\n"> <"\tgit reset --hard &&\n"> <"\tdate >foo1 &&\n"> <"\tdate >foo2 &&\n"> <"\tchmod 0 foo2 &&\n"> <"\ttest_must_fail git add --verbose . &&\n"> <"\t! ( git ls-files foo1 | grep foo1 )\n"> ) } ) (C {(rm)} {(-f)} {(foo2)}) (C {(test_expect_success)} {(POSIXPERM) (Lit_Comma ",") (SANITY)} {(SQ <"git add --ignore-errors">)} { (SQ <"\n"> <"\tgit reset --hard &&\n"> <"\tdate >foo1 &&\n"> <"\tdate >foo2 &&\n"> <"\tchmod 0 foo2 &&\n"> <"\ttest_must_fail git add --verbose --ignore-errors . &&\n"> <"\tgit ls-files foo1 | grep foo1\n"> ) } ) (C {(rm)} {(-f)} {(foo2)}) (C {(test_expect_success)} {(POSIXPERM) (Lit_Comma ",") (SANITY)} {(SQ <"git add (add.ignore-errors)">)} { (SQ <"\n"> <"\tgit config add.ignore-errors 1 &&\n"> <"\tgit reset --hard &&\n"> <"\tdate >foo1 &&\n"> <"\tdate >foo2 &&\n"> <"\tchmod 0 foo2 &&\n"> <"\ttest_must_fail git add --verbose . &&\n"> <"\tgit ls-files foo1 | grep foo1\n"> ) } ) (C {(rm)} {(-f)} {(foo2)}) (C {(test_expect_success)} {(POSIXPERM) (Lit_Comma ",") (SANITY)} {(SQ <"git add (add.ignore-errors = false)">)} { (SQ <"\n"> <"\tgit config add.ignore-errors 0 &&\n"> <"\tgit reset --hard &&\n"> <"\tdate >foo1 &&\n"> <"\tdate >foo2 &&\n"> <"\tchmod 0 foo2 &&\n"> <"\ttest_must_fail git add --verbose . &&\n"> <"\t! ( git ls-files foo1 | grep foo1 )\n"> ) } ) (C {(rm)} {(-f)} {(foo2)}) (C {(test_expect_success)} {(POSIXPERM) (Lit_Comma ",") (SANITY)} {(SQ <"--no-ignore-errors overrides config">)} { (SQ <"\n"> <" git config add.ignore-errors 1 &&\n"> <" git reset --hard &&\n"> <" date >foo1 &&\n"> <" date >foo2 &&\n"> <" chmod 0 foo2 &&\n"> <" test_must_fail git add --verbose --no-ignore-errors . &&\n"> <" ! ( git ls-files foo1 | grep foo1 ) &&\n"> <" git config add.ignore-errors 0\n"> ) } ) (C {(rm)} {(-f)} {(foo2)}) (C {(test_expect_success)} {(BSLASHPSPEC)} { (DQ ("git add 'fo") (EscapedLiteralPart token:<Lit_EscapedChar "\\\\">) ("[ou") (EscapedLiteralPart token:<Lit_EscapedChar "\\\\">) ("]bar' ignores foobar") ) } {(SQ <"\n"> <"\tgit reset --hard &&\n"> <"\ttouch fo\\[ou\\]bar foobar &&\n"> <"\tgit add ">) (EscapedLiteralPart token:<Lit_EscapedChar "\\'">) (SQ <"fo\\[ou\\]bar">) (EscapedLiteralPart token:<Lit_EscapedChar "\\'">) (SQ <" &&\n"> <"\tgit ls-files fo\\[ou\\]bar | fgrep fo\\[ou\\]bar &&\n"> <"\t! ( git ls-files foobar | grep foobar )\n"> ) } ) (C {(test_expect_success)} {(SQ <"git add to resolve conflicts on otherwise ignored path">)} { (SQ <"\n"> <"\tgit reset --hard &&\n"> <"\tH=$(git rev-parse :1/2/a) &&\n"> <"\t(\n"> <"\t\techo \"100644 $H 1\ttrack-this\"\n"> <"\t\techo \"100644 $H 3\ttrack-this\"\n"> <"\t) | git update-index --index-info &&\n"> <"\techo track-this >>.gitignore &&\n"> <"\techo resolved >track-this &&\n"> <"\tgit add track-this\n"> ) } ) (C {(test_expect_success)} {(SQ <"\"add non-existent\" should fail">)} { (SQ <"\n"> <"\ttest_must_fail git add non-existent &&\n"> <"\t! (git ls-files | grep \"non-existent\")\n"> ) } ) (C {(test_expect_success)} {(SQ <"git add -A on empty repo does not error out">)} { (SQ <"\n"> <"\trm -fr empty &&\n"> <"\tgit init empty &&\n"> <"\t(\n"> <"\t\tcd empty &&\n"> <"\t\tgit add -A . &&\n"> <"\t\tgit add -A\n"> <"\t)\n"> ) } ) (C {(test_expect_success)} {(SQ <"\"git add .\" in empty repo">)} { (SQ <"\n"> <"\trm -fr empty &&\n"> <"\tgit init empty &&\n"> <"\t(\n"> <"\t\tcd empty &&\n"> <"\t\tgit add .\n"> <"\t)\n"> ) } ) (C {(test_expect_success)} {(SQ <"git add --dry-run of existing changed file">)} { (DQ ("\n") ("\techo new >>track-this &&\n") ("\tgit add --dry-run track-this >actual 2>&1 &&\n") ("\techo ") (EscapedLiteralPart token:<Lit_EscapedChar "\\\"">) ("add 'track-this'") (EscapedLiteralPart token:<Lit_EscapedChar "\\\"">) (" | test_cmp - actual\n") ) } ) (C {(test_expect_success)} {(SQ <"git add --dry-run of non-existing file">)} { (DQ ("\n") ("\techo ignored-file >>.gitignore &&\n") ("\ttest_must_fail git add --dry-run track-this ignored-file >actual 2>&1\n") ) } ) (C {(test_expect_success)} {(SQ <"git add --dry-run of an existing file output">)} { (DQ ("\n") ("\techo ") (EscapedLiteralPart token:<Lit_EscapedChar "\\\"">) ("fatal: pathspec 'ignored-file' did not match any files") (EscapedLiteralPart token:<Lit_EscapedChar "\\\"">) (" >expect &&\n") ("\ttest_i18ncmp expect actual\n") ) } ) (SimpleCommand words: [{(cat)}] redirects: [ (Redir op_id:Redir_Great fd:-1 arg_word:{(expect.err)} spids:[780]) (HereDoc op_id: Redir_DLess fd: -1 body: {("The following paths are ignored by one of your .gitignore files:\n") ("ignored-file\n") ("Use -f if you really want to add them.\n") } do_expansion: False here_end: EOF was_filled: True spids: [783] ) ] ) (SimpleCommand words: [{(cat)}] redirects: [ (Redir op_id:Redir_Great fd:-1 arg_word:{(expect.out)} spids:[789]) (HereDoc op_id: Redir_DLess fd: -1 body: {("add 'track-this'\n")} do_expansion: False here_end: EOF was_filled: True spids: [792] ) ] ) (C {(test_expect_success)} {(SQ <"git add --dry-run --ignore-missing of non-existing file">)} { (SQ <"\n"> < "\ttest_must_fail git add --dry-run --ignore-missing track-this ignored-file >actual.out 2>actual.err\n" > ) } ) (C {(test_expect_success)} {(SQ <"git add --dry-run --ignore-missing of non-existing file output">)} { (SQ <"\n"> <"\ttest_i18ncmp expect.out actual.out &&\n"> <"\ttest_i18ncmp expect.err actual.err\n"> ) } ) (C {(test_expect_success)} {(SQ <"git add empty string should invoke warning">)} { (SQ <"\n"> <"\tgit add \"\" 2>output &&\n"> <"\ttest_i18ngrep \"warning: empty strings\" output\n"> ) } ) (C {(test_expect_success)} {(SQ <"git add --chmod=[+-]x stages correctly">)} { (SQ <"\n"> <"\trm -f foo1 &&\n"> <"\techo foo >foo1 &&\n"> <"\tgit add --chmod=+x foo1 &&\n"> <"\ttest_mode_in_index 100755 foo1 &&\n"> <"\tgit add --chmod=-x foo1 &&\n"> <"\ttest_mode_in_index 100644 foo1\n"> ) } ) (C {(test_expect_success)} {(POSIXPERM) (Lit_Comma ",") (SYMLINKS)} {(SQ <"git add --chmod=+x with symlinks">)} { (SQ <"\n"> <"\tgit config core.filemode 1 &&\n"> <"\tgit config core.symlinks 1 &&\n"> <"\trm -f foo2 &&\n"> <"\techo foo >foo2 &&\n"> <"\tgit add --chmod=+x foo2 &&\n"> <"\ttest_mode_in_index 100755 foo2\n"> ) } ) (C {(test_expect_success)} {(SQ <"git add --chmod=[+-]x changes index with already added file">)} { (SQ <"\n"> <"\trm -f foo3 xfoo3 &&\n"> <"\techo foo >foo3 &&\n"> <"\tgit add foo3 &&\n"> <"\tgit add --chmod=+x foo3 &&\n"> <"\ttest_mode_in_index 100755 foo3 &&\n"> <"\techo foo >xfoo3 &&\n"> <"\tchmod 755 xfoo3 &&\n"> <"\tgit add xfoo3 &&\n"> <"\tgit add --chmod=-x xfoo3 &&\n"> <"\ttest_mode_in_index 100644 xfoo3\n"> ) } ) (C {(test_expect_success)} {(POSIXPERM)} {(SQ <"git add --chmod=[+-]x does not change the working tree">)} { (SQ <"\n"> <"\techo foo >foo4 &&\n"> <"\tgit add foo4 &&\n"> <"\tgit add --chmod=+x foo4 &&\n"> <"\t! test -x foo4\n"> ) } ) (C {(test_expect_success)} {(SQ <"no file status change if no pathspec is given">)} { (SQ <"\n"> <"\t>foo5 &&\n"> <"\t>foo6 &&\n"> <"\tgit add foo5 foo6 &&\n"> <"\tgit add --chmod=+x &&\n"> <"\ttest_mode_in_index 100644 foo5 &&\n"> <"\ttest_mode_in_index 100644 foo6\n"> ) } ) (C {(test_expect_success)} {(SQ <"no file status change if no pathspec is given in subdir">)} { (SQ <"\n"> <"\tmkdir -p sub &&\n"> <"\t(\n"> <"\t\tcd sub &&\n"> <"\t\t>sub-foo1 &&\n"> <"\t\t>sub-foo2 &&\n"> <"\t\tgit add . &&\n"> <"\t\tgit add --chmod=+x &&\n"> <"\t\ttest_mode_in_index 100644 sub-foo1 &&\n"> <"\t\ttest_mode_in_index 100644 sub-foo2\n"> <"\t)\n"> ) } ) (C {(test_expect_success)} {(SQ <"all statuses changed in folder if . is given">)} { (SQ <"\n"> <"\tgit add --chmod=+x . &&\n"> <"\ttest $(git ls-files --stage | grep ^100644 | wc -l) -eq 0 &&\n"> <"\tgit add --chmod=-x . &&\n"> <"\ttest $(git ls-files --stage | grep ^100755 | wc -l) -eq 0\n"> ) } ) (C {(test_done)}) ] )