t / t3700-add.shon commit t4018: an infrastructure to test hunk headers (bfa7d01)
   1#!/bin/sh
   2#
   3# Copyright (c) 2006 Carl D. Worth
   4#
   5
   6test_description='Test of git add, including the -- option.'
   7
   8. ./test-lib.sh
   9
  10test_expect_success \
  11    'Test of git add' \
  12    'touch foo && git add foo'
  13
  14test_expect_success \
  15    'Post-check that foo is in the index' \
  16    'git ls-files foo | grep foo'
  17
  18test_expect_success \
  19    'Test that "git add -- -q" works' \
  20    'touch -- -q && git add -- -q'
  21
  22test_expect_success \
  23        'git add: Test that executable bit is not used if core.filemode=0' \
  24        'git config core.filemode 0 &&
  25         echo foo >xfoo1 &&
  26         chmod 755 xfoo1 &&
  27         git add xfoo1 &&
  28         case "`git ls-files --stage xfoo1`" in
  29         100644" "*xfoo1) echo pass;;
  30         *) echo fail; git ls-files --stage xfoo1; (exit 1);;
  31         esac'
  32
  33test_expect_success 'git add: filemode=0 should not get confused by symlink' '
  34        rm -f xfoo1 &&
  35        test_ln_s_add foo xfoo1 &&
  36        case "`git ls-files --stage xfoo1`" in
  37        120000" "*xfoo1) echo pass;;
  38        *) echo fail; git ls-files --stage xfoo1; (exit 1);;
  39        esac
  40'
  41
  42test_expect_success \
  43        'git update-index --add: Test that executable bit is not used...' \
  44        'git config core.filemode 0 &&
  45         echo foo >xfoo2 &&
  46         chmod 755 xfoo2 &&
  47         git update-index --add xfoo2 &&
  48         case "`git ls-files --stage xfoo2`" in
  49         100644" "*xfoo2) echo pass;;
  50         *) echo fail; git ls-files --stage xfoo2; (exit 1);;
  51         esac'
  52
  53test_expect_success 'git add: filemode=0 should not get confused by symlink' '
  54        rm -f xfoo2 &&
  55        test_ln_s_add foo xfoo2 &&
  56        case "`git ls-files --stage xfoo2`" in
  57        120000" "*xfoo2) echo pass;;
  58        *) echo fail; git ls-files --stage xfoo2; (exit 1);;
  59        esac
  60'
  61
  62test_expect_success \
  63        'git update-index --add: Test that executable bit is not used...' \
  64        'git config core.filemode 0 &&
  65         test_ln_s_add xfoo2 xfoo3 &&   # runs git update-index --add
  66         case "`git ls-files --stage xfoo3`" in
  67         120000" "*xfoo3) echo pass;;
  68         *) echo fail; git ls-files --stage xfoo3; (exit 1);;
  69         esac'
  70
  71test_expect_success '.gitignore test setup' '
  72        echo "*.ig" >.gitignore &&
  73        mkdir c.if d.ig &&
  74        >a.ig && >b.if &&
  75        >c.if/c.if && >c.if/c.ig &&
  76        >d.ig/d.if && >d.ig/d.ig
  77'
  78
  79test_expect_success '.gitignore is honored' '
  80        git add . &&
  81        ! (git ls-files | grep "\\.ig")
  82'
  83
  84test_expect_success 'error out when attempting to add ignored ones without -f' '
  85        test_must_fail git add a.?? &&
  86        ! (git ls-files | grep "\\.ig")
  87'
  88
  89test_expect_success 'error out when attempting to add ignored ones without -f' '
  90        test_must_fail git add d.?? &&
  91        ! (git ls-files | grep "\\.ig")
  92'
  93
  94test_expect_success 'add ignored ones with -f' '
  95        git add -f a.?? &&
  96        git ls-files --error-unmatch a.ig
  97'
  98
  99test_expect_success 'add ignored ones with -f' '
 100        git add -f d.??/* &&
 101        git ls-files --error-unmatch d.ig/d.if d.ig/d.ig
 102'
 103
 104test_expect_success 'add ignored ones with -f' '
 105        rm -f .git/index &&
 106        git add -f d.?? &&
 107        git ls-files --error-unmatch d.ig/d.if d.ig/d.ig
 108'
 109
 110test_expect_success '.gitignore with subdirectory' '
 111
 112        rm -f .git/index &&
 113        mkdir -p sub/dir &&
 114        echo "!dir/a.*" >sub/.gitignore &&
 115        >sub/a.ig &&
 116        >sub/dir/a.ig &&
 117        git add sub/dir &&
 118        git ls-files --error-unmatch sub/dir/a.ig &&
 119        rm -f .git/index &&
 120        (
 121                cd sub/dir &&
 122                git add .
 123        ) &&
 124        git ls-files --error-unmatch sub/dir/a.ig
 125'
 126
 127mkdir 1 1/2 1/3
 128touch 1/2/a 1/3/b 1/2/c
 129test_expect_success 'check correct prefix detection' '
 130        rm -f .git/index &&
 131        git add 1/2/a 1/3/b 1/2/c
 132'
 133
 134test_expect_success 'git add with filemode=0, symlinks=0, and unmerged entries' '
 135        for s in 1 2 3
 136        do
 137                echo $s > stage$s
 138                echo "100755 $(git hash-object -w stage$s) $s   file"
 139                echo "120000 $(printf $s | git hash-object -w -t blob --stdin) $s       symlink"
 140        done | git update-index --index-info &&
 141        git config core.filemode 0 &&
 142        git config core.symlinks 0 &&
 143        echo new > file &&
 144        echo new > symlink &&
 145        git add file symlink &&
 146        git ls-files --stage | grep "^100755 .* 0       file$" &&
 147        git ls-files --stage | grep "^120000 .* 0       symlink$"
 148'
 149
 150test_expect_success 'git add with filemode=0, symlinks=0 prefers stage 2 over stage 1' '
 151        git rm --cached -f file symlink &&
 152        (
 153                echo "100644 $(git hash-object -w stage1) 1     file"
 154                echo "100755 $(git hash-object -w stage2) 2     file"
 155                echo "100644 $(printf 1 | git hash-object -w -t blob --stdin) 1 symlink"
 156                echo "120000 $(printf 2 | git hash-object -w -t blob --stdin) 2 symlink"
 157        ) | git update-index --index-info &&
 158        git config core.filemode 0 &&
 159        git config core.symlinks 0 &&
 160        echo new > file &&
 161        echo new > symlink &&
 162        git add file symlink &&
 163        git ls-files --stage | grep "^100755 .* 0       file$" &&
 164        git ls-files --stage | grep "^120000 .* 0       symlink$"
 165'
 166
 167test_expect_success 'git add --refresh' '
 168        >foo && git add foo && git commit -a -m "commit all" &&
 169        test -z "`git diff-index HEAD -- foo`" &&
 170        git read-tree HEAD &&
 171        case "`git diff-index HEAD -- foo`" in
 172        :100644" "*"M   foo") echo pass;;
 173        *) echo fail; (exit 1);;
 174        esac &&
 175        git add --refresh -- foo &&
 176        test -z "`git diff-index HEAD -- foo`"
 177'
 178
 179test_expect_success 'git add --refresh with pathspec' '
 180        git reset --hard &&
 181        echo >foo && echo >bar && echo >baz &&
 182        git add foo bar baz && H=$(git rev-parse :foo) && git rm -f foo &&
 183        echo "100644 $H 3       foo" | git update-index --index-info &&
 184        test-chmtime -60 bar baz &&
 185        >expect &&
 186        git add --refresh bar >actual &&
 187        test_cmp expect actual &&
 188
 189        git diff-files --name-only >actual &&
 190        ! grep bar actual&&
 191        grep baz actual
 192'
 193
 194test_expect_success POSIXPERM,SANITY 'git add should fail atomically upon an unreadable file' '
 195        git reset --hard &&
 196        date >foo1 &&
 197        date >foo2 &&
 198        chmod 0 foo2 &&
 199        test_must_fail git add --verbose . &&
 200        ! ( git ls-files foo1 | grep foo1 )
 201'
 202
 203rm -f foo2
 204
 205test_expect_success POSIXPERM,SANITY 'git add --ignore-errors' '
 206        git reset --hard &&
 207        date >foo1 &&
 208        date >foo2 &&
 209        chmod 0 foo2 &&
 210        test_must_fail git add --verbose --ignore-errors . &&
 211        git ls-files foo1 | grep foo1
 212'
 213
 214rm -f foo2
 215
 216test_expect_success POSIXPERM,SANITY 'git add (add.ignore-errors)' '
 217        git config add.ignore-errors 1 &&
 218        git reset --hard &&
 219        date >foo1 &&
 220        date >foo2 &&
 221        chmod 0 foo2 &&
 222        test_must_fail git add --verbose . &&
 223        git ls-files foo1 | grep foo1
 224'
 225rm -f foo2
 226
 227test_expect_success POSIXPERM,SANITY 'git add (add.ignore-errors = false)' '
 228        git config add.ignore-errors 0 &&
 229        git reset --hard &&
 230        date >foo1 &&
 231        date >foo2 &&
 232        chmod 0 foo2 &&
 233        test_must_fail git add --verbose . &&
 234        ! ( git ls-files foo1 | grep foo1 )
 235'
 236rm -f foo2
 237
 238test_expect_success POSIXPERM,SANITY '--no-ignore-errors overrides config' '
 239       git config add.ignore-errors 1 &&
 240       git reset --hard &&
 241       date >foo1 &&
 242       date >foo2 &&
 243       chmod 0 foo2 &&
 244       test_must_fail git add --verbose --no-ignore-errors . &&
 245       ! ( git ls-files foo1 | grep foo1 ) &&
 246       git config add.ignore-errors 0
 247'
 248rm -f foo2
 249
 250test_expect_success BSLASHPSPEC "git add 'fo\\[ou\\]bar' ignores foobar" '
 251        git reset --hard &&
 252        touch fo\[ou\]bar foobar &&
 253        git add '\''fo\[ou\]bar'\'' &&
 254        git ls-files fo\[ou\]bar | fgrep fo\[ou\]bar &&
 255        ! ( git ls-files foobar | grep foobar )
 256'
 257
 258test_expect_success 'git add to resolve conflicts on otherwise ignored path' '
 259        git reset --hard &&
 260        H=$(git rev-parse :1/2/a) &&
 261        (
 262                echo "100644 $H 1       track-this"
 263                echo "100644 $H 3       track-this"
 264        ) | git update-index --index-info &&
 265        echo track-this >>.gitignore &&
 266        echo resolved >track-this &&
 267        git add track-this
 268'
 269
 270test_expect_success '"add non-existent" should fail' '
 271        test_must_fail git add non-existent &&
 272        ! (git ls-files | grep "non-existent")
 273'
 274
 275test_expect_success 'git add -A on empty repo does not error out' '
 276        rm -fr empty &&
 277        git init empty &&
 278        (
 279                cd empty &&
 280                git add -A . &&
 281                git add -A
 282        )
 283'
 284
 285test_expect_success '"git add ." in empty repo' '
 286        rm -fr empty &&
 287        git init empty &&
 288        (
 289                cd empty &&
 290                git add .
 291        )
 292'
 293
 294test_expect_success 'git add --dry-run of existing changed file' "
 295        echo new >>track-this &&
 296        git add --dry-run track-this >actual 2>&1 &&
 297        echo \"add 'track-this'\" | test_cmp - actual
 298"
 299
 300test_expect_success 'git add --dry-run of non-existing file' "
 301        echo ignored-file >>.gitignore &&
 302        test_must_fail git add --dry-run track-this ignored-file >actual 2>&1
 303"
 304
 305test_expect_success 'git add --dry-run of an existing file output' "
 306        echo \"fatal: pathspec 'ignored-file' did not match any files\" >expect &&
 307        test_i18ncmp expect actual
 308"
 309
 310cat >expect.err <<\EOF
 311The following paths are ignored by one of your .gitignore files:
 312ignored-file
 313Use -f if you really want to add them.
 314fatal: no files added
 315EOF
 316cat >expect.out <<\EOF
 317add 'track-this'
 318EOF
 319
 320test_expect_success 'git add --dry-run --ignore-missing of non-existing file' '
 321        test_must_fail git add --dry-run --ignore-missing track-this ignored-file >actual.out 2>actual.err
 322'
 323
 324test_expect_success 'git add --dry-run --ignore-missing of non-existing file output' '
 325        test_i18ncmp expect.out actual.out &&
 326        test_i18ncmp expect.err actual.err
 327'
 328
 329test_done