按模式递归添加文件

发布于 2024-09-02 06:15:13 字数 232 浏览 6 评论 0 原文

如何通过位于不同目录中的模式(或全局)递归添加文件?

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

git add '*.java'

不幸的是,这并没有按预期工作。

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:

git add '*.java'

Unfortunately, that doesn't work as expected.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

归属感 2024-09-09 06:15:14

我只想添加具有基于 git status 的特定字符串的文件

: grep 字符串 | xargs git 添加

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

I wanted to only add files that had a certain string based on git status:

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

千と千尋 2024-09-09 06:15:14

正如“git:如何递归添加目录子树中与 glob 模式匹配的所有文件?”中提到的,如果你正确地转义或引用你的路径规范通配符(如'*.java'),那么是的,git add '*.java'

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

请参阅 提交 7288e12(2017 年 3 月 14 日),作者:杰夫·金 (peff)
(由 Junio C Hamano -- gitster -- 合并于 提交 153e0d7,2017 年 3 月 17 日)

add --interactive:不要使用 ls-files 扩展路径规范

当我们想要获取已修改文件的列表时,我们首先使用“ls-files”扩展用户提供的路径规范,然后将生成的路径列表作为参数提供给“diff-index”和“diff-files”。
如果您的路径规范扩展到大量路径,您可能会遇到以下两个问题之一:

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

    $ (ulimit -s 128 && git add -p drivers)
    无法执行“git”:.../git-add--interactive 第 177 行的参数列表太长。
    死于 .../git-add--interactive 第 177 行。
    

它位于 linux.git 存储库中,该存储库的“drivers”目录中有大约 20K 个文件(在本例中没有一个文件被修改)。即使对于如此庞大的路径集,“ulimit -s”技巧对于在 Linux 上显示问题也是必要的。
其他操作系统的限制要小得多(例如,在 OS X 上看到的实际情况只有 5K 文件)。

  • 即使它确实有效,它也非常慢。路径规范
    代码未针对大量路径进行优化。这是
    没有 ulimit 的相同情况:

    $ time git add -p drivers
      没有变化。
    
    真实0米16.559秒
    用户 0m53.140s
    系统0分0.220秒
    
  • 我们可以通过完全跳过“ls-files”来改进这一点,并将原始路径规范提供给 diff 命令。

    从历史上看,“diff-index”支持的路径规范语言较弱,但现在情况已不再如此。

    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 2.13 (Q2 2017) improves that for interactive add:

    See commit 7288e12 (14 Mar 2017) by Jeff King (peff).
    (Merged by Junio C Hamano -- gitster -- in commit 153e0d7, 17 Mar 2017)

    add --interactive: do not expand pathspecs with ls-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:

    1. 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).

    1. 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.

    Historically the pathspec language supported by "diff-index" was weaker, but that is no longer the case.

    空气里的味道 2024-09-09 06:15:14

    将行放入 ~/.gitconfig

    [alias]
    addt = !sh -c 'git ls 文件 | grep \"\\.$1*\" | xargs git add' -

    如果你想添加所有修改过的java文件可以这样做:
    git addt java

    同样,如果你想添加所有修改过的Python文件可以这样做:
    git addt py

    put line in ~/.gitconfig

    [alias]
    addt = !sh -c 'git ls-files | grep \"\\.$1*\" | xargs git add' -

    If you want to add all modified java file can just do:
    git addt java

    Samely, if you want to add all modified python file can just do:
    git addt py

    榕城若虚 2024-09-09 06:15:14
    我在 GNUmakefile 中使用的变体
    .PHONY: docs
    docs:
        @echo docs
        bash -c "if pgrep MacDown; then pkill MacDown; fi"
        bash -c 'cat $(PWD)/HEADER.md                >  $(PWD)/README.md'
        bash -c 'cat $(PWD)/COMMANDS.md              >> $(PWD)/README.md'
        bash -c 'cat $(PWD)/FOOTER.md                >> $(PWD)/README.md'
        bash -c 'pandoc -s README.md -o index.html'
        bash -c "if hash open 2>/dev/null; then open README.md; fi || echo failed to open README.md"
        #git add --ignore-errors *.md
        git ls-files -co --exclude-standard | grep '\.md/$\' | xargs git 
    
    A variation that I used in a GNUmakefile
    .PHONY: docs
    docs:
        @echo docs
        bash -c "if pgrep MacDown; then pkill MacDown; fi"
        bash -c 'cat $(PWD)/HEADER.md                >  $(PWD)/README.md'
        bash -c 'cat $(PWD)/COMMANDS.md              >> $(PWD)/README.md'
        bash -c 'cat $(PWD)/FOOTER.md                >> $(PWD)/README.md'
        bash -c 'pandoc -s README.md -o index.html'
        bash -c "if hash open 2>/dev/null; then open README.md; fi || echo failed to open README.md"
        #git add --ignore-errors *.md
        git ls-files -co --exclude-standard | grep '\.md/$\' | xargs git 
    
    一花一树开 2024-09-09 06:15:13

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

    来自 git add 文档

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

    $ git add Documentation/\*.txt
    

    请注意,在此示例中,星号 * 是从 shell 中引用的;这使得命令包含 Documentation/ 目录子目录中的文件。

    You can use git add [path]/\*.java to add java files from subdirectories,
    e.g. git add ./\*.java for current directory.

    From git add documentation:

    Adds content from all *.txt files under Documentation 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 of Documentation/ directory.

    娇妻 2024-09-09 06:15:13

    如果某些要添加的文件可能尚未被跟踪,Sergio Acosta 的答案可能是您最好的选择。如果你想将自己限制在 git 已经知道的文件中,你可以将 git-ls-files 与过滤器结合起来:

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

    Git 本身没有提供任何花哨的机制来执行此操作,因为它基本上是一个 shell问题:如何获取文件列表作为给定命令的参数提供。

    | xargs git add

    Git 本身没有提供任何花哨的机制来执行此操作,因为它基本上是一个 shell问题:如何获取文件列表作为给定命令的参数提供。

    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:

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

    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.

    | 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.

    你如我软肋 2024-09-09 06:15:13

    使用 zsh 您可以运行:

    git add "**/*.java"
    

    并且所有 *.java 文件将被递归添加。

    With zsh you can run:

    git add "**/*.java"
    

    and all your *.java files will be added recursively.

    亽野灬性zι浪 2024-09-09 06:15:13

    有点偏离主题(不是特别与 git 相关),但如果您使用的是 linux/unix,解决方法可能是:

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

    如果您期望路径带有空格:

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

    但我知道这并不完全是您所要求的。

    A bit off topic (not specifically git related) but if you're on linux/unix a workaround could be:

    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.

    っ〆星空下的拥抱 2024-09-09 06:15:13

    谢尔盖的回答(不要相信我)正在起作用:

    可以使用 git add [path]/\*.java
    

    使用最近的 git:

    $git version
    git version 1.7.3.4
    

    用于测试的文件:

    $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
    

    Sergey's answer (don't credit me) is working:

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

    with a recent 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 status -s
    ?? dirA/
    ?? dirB/
    ?? file7.txt
    

    Adding *.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
    
    画中仙 2024-09-09 06:15:13

    由于此处未提及,请考虑“魔法签名:/ 以递归方式添加项目根目录下匹配的任何内容:

    git add :/*.{java,pom}
    

    Tx 至: https://stackoverflow.com/ a/64210713/2586761

    As it's not mentioned here, consider also the "magic signature" :/ to recursively add anything matching below the project root:

    git add :/*.{java,pom}
    

    Tx to: https://stackoverflow.com/a/64210713/2586761

    三生一梦 2024-09-09 06:15:13

    只需使用 git add *\*.java 即可。这将添加根目录和所有子目录中的所有 .java 文件。

    Just use git add *\*.java. This will add all .java files in root directory and all subdirectories.

    娇妻 2024-09-09 06:15:13

    如果您已经在跟踪文件并对它们进行了更改,现在您想根据模式有选择地添加它们,则可以使用 --modified 标志

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

    例如,如果您只想添加此提交的 CSS 更改,您可以

    git ls-files --modified | grep '\.css
    

    查看 man git-ls-files 了解更多标志

    | xargs git add

    查看 man git-ls-files 了解更多标志

    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

    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

    git ls-files --modified | grep '\.css
    

    See man git-ls-files for more flags

    | xargs git add

    See man git-ls-files for more flags

    慢慢从新开始 2024-09-09 06:15:13

    添加尚未提及的 Windows 命令行解决方案:

    for /f "delims=" %G in ('dir /b/s *.java') do @git add %G
    

    Adding a Windows command line solution that was not yet mentioned:

    for /f "delims=" %G in ('dir /b/s *.java') do @git add %G
    
    ~没有更多了~
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文