代码之家  ›  专栏  ›  技术社区  ›  Michel Krämer

按模式递归添加文件

  •  137
  • Michel Krämer  · 技术社区  · 15 年前

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

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

    git add '*.java'
    

    不幸的是,这并不像预期的那样有效。

    10 回复  |  直到 6 年前
        1
  •  72
  •   Cascabel    15 年前

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

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

    Git本身并没有提供任何奇特的机制来实现这一点,因为它基本上是一个shell问题:如何获得一个文件列表作为给定命令的参数来提供。

        2
  •  126
  •   Sergey Glotov Nitesh Khosla    7 年前

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

    git add documentation :

    添加全部内容 *.txt 文件下 Documentation 目录及其子目录:

    $ git add Documentation/\*.txt
    

    注意星号 * 在本例中从shell中引用;这使命令包含来自以下子目录的文件: Documentation/ 目录。

        3
  •  48
  •   Sergio Acosta    15 年前

    有点离题(与Git无关),但如果您使用的是Linux/Unix,解决方法可能是:

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

    如果你期望有空间的路径:

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

    但我知道这不是你要的。

        4
  •  43
  •   Sanghyun Lee    10 年前

    zsh 你可以运行:

    git add "**/*.java"
    

    以及你的一切 *.java 文件将以递归方式添加。

        5
  •  10
  •   Community CDub    8 年前

    Sergey's answer (别相信我)正在工作:

    You can use 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
    
        6
  •  7
  •   Ram    12 年前

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

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

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

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

    man git-ls-files 更多的旗帜

        7
  •  2
  •   Community CDub    8 年前

    如“中所述 git: How do I recursively add all files in a directory subtree that match a glob pattern? “,如果您正确地转义或引用您的pathspec globbing(例如 '*.java' ,然后是,git-add “.java”

    Git 2.13(2017年第2季度)改进了交互式添加:

    commit 7288e12 (2017年3月14日) Jeff King ( peff ) .
    (合并) Junio C Hamano -- gitster -- 在里面 commit 153e0d7 17英里2017

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

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

    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 存储库,在“驱动程序”目录中有大约20K个文件(在本例中没有修改)。“ ulimit -s “即使对于如此庞大的路径集,在Linux上也需要技巧来显示这个问题。
    其他操作系统的限制要小得多(例如,在OS X上只看到一个实际情况,只有5千个文件)。

    1. 即使它真的起作用,它也很慢。路径规范 代码没有针对大量路径进行优化。这里是 同样的情况没有ulimit:

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

    我们可以通过跳过 LS文件 “完全,只需将原始路径规范提供给diff命令即可。

    “历史上支持的pathspec语言” 差异指数 “本来比较弱,但现在已经不是这样了。

        8
  •  2
  •   bdanin    7 年前

    我只想添加基于 git status :

    git status | grep string | xargs git add

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

        9
  •  1
  •   selalerer    6 年前

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

    for /f %G in ('dir /b/s *.java') do @git add %G
    
        10
  •  0
  •   Jan Lovstrand    7 年前

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