通过模式recursion添加文件

如何通过位于不同目录中的模式(或glob)recursion添加文件?

例如,我想用一个命令添加A/B/C/foo.javaD/E/F/bar.java (和其他几个java文件):

 git add '*.java' 

不幸的是,这并不像预期的那样工作。

塞尔吉奥阿科斯塔的答案可能是你最好的select,如果一些文件被添加可能还没有被跟踪。 如果你想限制自己已经知道的文件,你可以将git-ls-files与一个filter结合起来:

 git ls-files [path] | grep '\.java$' | xargs git add 

Git没有提供任何这样做的奇特机制,因为它基本上是一个shell问题:你如何得到一个文件列表作为给定命令的参数。

你可以使用git add [path]/\*.java 。java从子目录添加java文件,
例如git add ./\*.java为当前目录git add ./\*.java

git add文档:

在文档目录及其子目录下添加所有* .txt文件的内容:

 $ git add Documentation/\*.txt 

请注意,在本例中星号*是从shell引用的。 这允许命令包含来自Documentation /目录子目录的文件。

有点closures的话题(不是特别的git相关),但如果你在linux / unix上的解决方法可能是:

 find . -name '*.java' | xargs git add 

如果你期望有空间的path:

 find . -name '*.java' -print0 | xargs -0 git add 

但我知道这不完全是你问的。

zsh你可以运行:

 git add "**/*.java" 

和所有的*.java文件将recursion添加。

如果您已经在跟踪您的文件并对其进行了更改,现在您希望根据模式select性地添加它们,则可以使用--modified标志

 git ls-files --modified | grep '<pattern>' | xargs git add 

例如,如果您只想将CSS更改添加到此提交中,则可以执行此操作

 git ls-files --modified | grep '\.css$' | xargs git add 

请参阅man git-ls-files获取更多标志

谢尔盖的回答 (不要信任我)正在工作:

 You can use git add [path]/\*.java 

最近git:

 $git version git version 1.7.3.4 

testing文件:

 $find -name .git -prune -o -type f -print | sort ./dirA/dirA-1/dirA-1-1/file1.txt ./dirA/dirA-1/dirA-1-2/file2.html ./dirA/dirA-1/dirA-1-2/file3.txt ./dirA/dirA-1/file4.txt ./dirB/dirB-1/dirB-1-1/file5.html ./dirB/dirB-1/dirB-1-1/file6.txt ./file7.txt 

Git状态:

 $git status -s ?? dirA/ ?? dirB/ ?? file7.txt 

添加* .txt:

 $git add \*.txt 

更新状态:

 $git status -s A dirA/dirA-1/dirA-1-1/file1.txt A dirA/dirA-1/dirA-1-2/file3.txt A dirA/dirA-1/file4.txt A dirB/dirB-1/dirB-1-1/file6.txt A file7.txt ?? dirA/dirA-1/dirA-1-2/file2.html ?? dirB/dirB-1/dirB-1-1/file5.html 

我只想添加具有基于git status的特定string的文件:

git status | grep string | xargs git add

然后能够git commit -m 'commit msg来提交所有文件标题中的“string”更改的文件

正如在“ 混帐:如何recursion地添加匹配一个glob模式的目录子树中的所有文件吗? ”中提到的 ,如果你正确地转义或者引用你的pathspecbing(比如'*.java' ),那么是的,git add '*.java'

Git 2.13(Q2 2017)改进了交互式添加:

见Jeff King( peff )的 提交7288e12 (2017年3月14日) 。
(由Junio C gitster合并- gitster -在2017年3月17日的第gitster 提交 )

add --interactive -interactive:不要用ls-files扩展path规格

当我们想要得到修改文件的列表时,我们首先用“ ls-files ”扩展任何用户提供的pathspecs,然后把得到的path列表作为参数传给“ diff-index ”和“ diff-files ”。
如果您的pathspec扩展到大量的path,您可能会遇到两个问题之一:

  1. 操作系统可能会抱怨参数列表的大小,并拒绝运行。 例如:

     $ (ulimit -s 128 && git add -p drivers) Can't exec "git": Argument list too long at .../git-add--interactive line 177. Died at .../git-add--interactive line 177. 

这在linux.git版本库上,在“drivers”目录中有大约20K个文件(在这种情况下没有修改)。 即使对于如此庞大的一组path,“ ulimit -s ”技巧对于在Linux上显示问题也是必要的。
其他操作系统的限制要小得多(例如,在OS X上只有5K的文件才是真实的情况)。

  1. 即使它工作,它也很慢。 pathspec代码未针对大量path进行优化。 没有ulimit的情况如下:

     $ time git add -p drivers No changes. real 0m16.559s user 0m53.140s sys 0m0.220s 

我们可以通过完全跳过“ ls-files ”来完善这个function,只需要将原始path规格反馈给diff命令即可。

在历史上,由“ diff-index ”支持的pathspec语言较弱,但不再是这种情况。

Interesting Posts