(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 16777215] ) (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 16777215] ) ] 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:16777215 arg_word:{(expect.err)} spids:[780]) (HereDoc op_id: Redir_DLess fd: 16777215 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: T spids: [783] ) ] ) (SimpleCommand words: [{(cat)}] redirects: [ (Redir op_id:Redir_Great fd:16777215 arg_word:{(expect.out)} spids:[789]) (HereDoc op_id: Redir_DLess fd: 16777215 body: {("add 'track-this'\n")} do_expansion: False here_end: EOF was_filled: T 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)}) ] )