15

I performed a fresh clone and copied/pasted a working directory into the cloned directory. Now have a list of changed files:

$ git status --short | grep -v "??" | cut -d " " -f 3 
GNUmakefile
Readme.txt
base32.h
base64.h
...

When I try to get Git to add them, it results in an error (I don't care about adding 1 at a time):

$ git status --short | grep -v "??" | cut -d " " -f 3 | git add
Nothing specified, nothing added.
Maybe you wanted to say 'git add .'?

Adding the -:

$ git status --short | grep -v "??" | cut -d " " -f 3 | git add -
fatal: pathspec '-' did not match any files

And --:

$ git status --short | grep -v "??" | cut -d " " -f 3 | git add --
Nothing specified, nothing added.
Maybe you wanted to say 'git add .'?

Trying to use interactive from the man page appears to have made a greater mess of things:

$ git status --short | grep -v "??" | cut -d " " -f 3 | git add -i
           staged     unstaged path
  1:    unchanged        +1/-1 GNUmakefile
  2:    unchanged      +11/-11 Readme.txt
  ...

*** Commands ***
  1: status   2: update   3: revert   4: add untracked
  5: patch    6: diff     7: quit     8: help
Huh (GNUmakefile)?
What now> *** Commands ***
  1: status   2: update   3: revert   4: add untracked
  5: patch    6: diff     7: quit     8: help
Huh (Readme.txt)?

(I've already deleted the directory Git made a mess of, so I'm not trying to solve that issue).

How do I tell Git to add the files piped into it?

7 Answers7

19

git add is expecting the files to be listed as arguments, not piped into stdin. Try either

git status --short | grep -v "??" | cut -d " " -f 3 | xargs git add

or

for file in $(git status --short | grep -v "??" | cut -d " " -f 3); do
    git add $file;
done
David King
  • 3,147
  • 9
  • 23
4

I used

git add `cat filelist`

I only had 100 files. 1000s might be problematic.

But maybe not. Use "-n" for a dry run.

Romeo Ninov
  • 17,484
2

If the files were already in the index (i.e. they show up as "modified", as opposed to untracked, when you run 'git status'), Then you can run

git commit -am "Useful commit message here"

This adds all tracked but modified files automatically.

Hack Saw
  • 1,024
0

If you're using ag or ack, this is what works:

ag -l PATTERN | xargs git add

joachim
  • 7,687
0

Similar to David King's:

git status --short | perl -lane '$F[0] == "M" and print $F[1]' | xargs -n 20 git add

That example finds files only in the Modified state, and adds them. To guard against very long parameter lists, xargs uses the -n 20 parameter to limit each call to git to 20 files.

Change the match condition in the perl script as needed. Another example:

| perl -lane '$F[0] == "M" and $F[1] =~ m/py$/ and print $F[1]' |

That example finds modified Python files (ends with py).

0

Say if I wanted to add all .cpp files. You can do it simply by doing

git add $(ls *.cpp)

Just make sure you don't have any space in filenames like

Hello World.cpp //this will not work you have to do git add Hello\ World.cpp
Helloworld.cpp //these filenames will work
  • Welcome to the site and thank you for your contribution. Apart from the fact that you should never parse the output of ls (you pointed out why yourself), why do you pipe the output of ls through grep? You could just say ls *.cpp... – AdminBee Aug 18 '20 at 12:06
  • Didn't know about the parsing output of ls thread. No special reason behind using grep, one can do it using it too but sure ls *.cpp looks like a better option. Thanks :) – Tushar Gupta Aug 18 '20 at 14:41
0

another flavour...
This one works for me using only shell commands and is a oneliner. Add more filter to the grep stage of pipe to filter out files

git add -- $(git status --short |grep '??' |cut -d' ' -f2| xargs -i sh
-c "printf '%s\n' {}")
Clement
  • 57