git 按模式递归添加文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2855140/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Recursively add files by pattern
提问by Michel Kr?mer
How do I recursively add files by a pattern (or glob) located in different directories?
如何通过位于不同目录中的模式(或全局)递归添加文件?
For example, I'd like to add A/B/C/foo.java
and D/E/F/bar.java
(and several other java files) with one command:
例如,我想用一个命令添加A/B/C/foo.java
和D/E/F/bar.java
(以及其他几个 java 文件):
git add '*.java'
Unfortunately, that doesn't work as expected.
不幸的是,这并没有按预期工作。
采纳答案by Cascabel
Sergio Acosta's answer is probably your best bet if some of the files to be added may not already be tracked. If you want to limit yourself to files git already knows about, you could combine git-ls-files
with a filter:
如果要添加的某些文件可能尚未被跟踪,Sergio Acosta 的回答可能是您最好的选择。如果你想限制自己使用 git 已经知道的文件,你可以结合git-ls-files
一个过滤器:
git ls-files [path] | grep '\.java$' | xargs git add
Git doesn't provide any fancy mechanisms for doing this itself, as it's basically a shell problem: how do you get a list of files to provide as arguments to a given command.
Git 本身没有提供任何奇特的机制来执行此操作,因为它基本上是一个 shell 问题:如何获取文件列表以作为给定命令的参数提供。
回答by Sergey Glotov
You can use git add [path]/\*.java
to add java files from subdirectories,
e.g. git add ./\*.java
for current directory.
您可以使用git add [path]/\*.java
从子目录添加 java 文件,
例如git add ./\*.java
为当前目录。
From git add
documentation:
Adds content from all
*.txt
files underDocumentation
directory and its subdirectories:$ git add Documentation/\*.txt
Note that the asterisk
*
is quoted from the shell in this example; this lets the command include the files from subdirectories ofDocumentation/
directory.
添加目录及其子目录
*.txt
下所有文件的内容Documentation
:$ git add Documentation/\*.txt
请注意,
*
在此示例中,星号是从 shell 引用的;这让命令包含来自目录子目录的Documentation/
文件。
回答by Olivier Verdier
With zsh
you can run:
有了zsh
你可以运行:
git add "**/*.java"
and all your *.java
files will be added recursively.
并且您的所有*.java
文件都将递归添加。
回答by Sergio Acosta
A bit off topic (not specifically git related) but if you're on linux/unix a workaround could be:
有点离题(与 git 无关),但如果您使用的是 linux/unix,则解决方法可能是:
find . -name '*.java' | xargs git add
And if you expect paths with spaces:
如果您希望路径带有空格:
find . -name '*.java' -print0 | xargs -0 git add
But I know that is not exactly what you asked.
但我知道这不是你问的。
回答by Alberto
Sergey's answer(don't credit me) is working:
谢尔盖的回答(不要相信我)是有效的:
You can use git add [path]/\*.java
You can use git add [path]/\*.java
with a recent git:
使用最近的 git:
$git version
git version 1.7.3.4
Files for the test:
测试文件:
$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 status:
git状态:
$git status -s
?? dirA/
?? dirB/
?? file7.txt
Adding *.txt:
添加 *.txt:
$git add \*.txt
Updated status:
更新状态:
$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
回答by Ram
If you are already tracking your files and have made changes to them and now you want to add them selectively based on a pattern, you can use the --modified
flag
如果您已经在跟踪您的文件并对它们进行了更改,现在您想根据模式有选择地添加它们,则可以使用该--modified
标志
git ls-files --modified | grep '<pattern>' | xargs git add
For example, if you only want to add the CSS changes to this commit, you can do
例如,如果您只想将 CSS 更改添加到此提交,您可以这样做
git ls-files --modified | grep '\.css$' | xargs git add
See man git-ls-files
for more flags
查看man git-ls-files
更多标志
回答by Jan Lovstrand
Just use git add *\*.java
. This will add all .java files in root directory and all subdirectories.
只需使用git add *\*.java
. 这将添加根目录和所有子目录中的所有 .java 文件。
回答by selalerer
Adding a Windows command line solution that was not yet mentioned:
添加尚未提及的 Windows 命令行解决方案:
for /f "delims=" %G in ('dir /b/s *.java') do @git add %G
回答by bdanin
I wanted to only add files that had a certain string based on git status
:
我只想添加具有基于特定字符串的文件git status
:
git status | grep string | xargs git add
git status | grep string | xargs git add
and then was able to git commit -m 'commit msg
to commit all changed files with "string" in the title of the file
然后能够git commit -m 'commit msg
提交文件标题中带有“字符串”的所有更改文件
回答by VonC
As mentioned in "git: How do I recursively add all files in a directory subtree that match a glob pattern?", if you properly escape or quote your pathspec globbing (like '*.java'
), then yes, git add '*.java'
如“ git: How do I recursively add all files in a directory subtree that match a glob pattern?”中所述,如果您正确转义或引用您的路径规范通配符(如'*.java'
),那么是的,git add'*.java'
Git 2.13 (Q2 2017) improves that for interactive add:
Git 2.13(2017 年第二季度)改进了交互式添加:
See commit 7288e12(14 Mar 2017) by Jeff King (peff
).
(Merged by Junio C Hamano -- gitster
--in commit 153e0d7, 17 Mar 2017)
请参阅Jeff King ( ) 的commit 7288e12(2017 年 3 月 14 日)。(由Junio C Hamano合并-- --在commit 153e0d7,2017 年 3 月 17 日)peff
gitster
add --interactive
: do not expand pathspecs withls-files
When we want to get the list of modified files, we first expand any user-provided pathspecs with "
ls-files
", and then feed the resulting list of paths as arguments to "diff-index
" and "diff-files
".
If your pathspec expands into a large number of paths, you may run into one of two problems:
The OS may complain about the size of the argument list, and refuse to run. For example:
$ (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.
That's on the
linux.git
repository, which has about 20K files in the "drivers" directory (none of them modified in this case). The "ulimit -s
" trick is necessary to show the problem on Linux even for such a gigantic set of paths.
Other operating systems have much smaller limits (e.g., a real-world case was seen with only 5K files on OS X).
Even when it does work, it's really slow. The pathspec code is not optimized for huge numbers of paths. Here's the same case without the ulimit:
$ time git add -p drivers No changes. real 0m16.559s user 0m53.140s sys 0m0.220s
We can improve this by skipping "
ls-files
" completely, and just feeding the original pathspecs to the diff commands.
add --interactive
:不要扩展路径规格ls-files
当我们想要获取修改文件的列表时,我们首先用“
ls-files
”扩展任何用户提供的路径规范,然后将生成的路径列表作为参数提供给“diff-index
”和“diff-files
”。
如果您的路径规范扩展为大量路径,您可能会遇到以下两个问题之一:
操作系统可能会抱怨参数列表的大小,并拒绝运行。例如:
$ (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
存储库中,它在“驱动程序”目录中有大约 20K 个文件(在这种情况下它们都没有修改)。ulimit -s
即使对于如此庞大的路径集,“ ”技巧对于在 Linux 上显示问题也是必要的。
其他操作系统的限制要小得多(例如,在 OS X 上看到的真实案例只有 5K 文件)。
即使它确实有效,它也确实很慢。pathspec 代码没有针对大量路径进行优化。这是没有 ulimit 的相同情况:
$ time git add -p drivers No changes. real 0m16.559s user 0m53.140s sys 0m0.220s
我们可以通过
ls-files
完全跳过“ ”来改进这一点,只需将原始路径规范提供给 diff 命令。
Historically the pathspec language supported by "diff-index
" was weaker, but that is no longer the case.
从历史上看," diff-index
"支持的 pathspec 语言较弱,但现在已不再如此。