web-dev-qa-db-ja.com

パターンごとにファイルを再帰的に追加する

異なるディレクトリにあるパターン(またはグロブ)でファイルを再帰的に追加するにはどうすればよいですか?

たとえば、1つのコマンドでA/B/C/foo.JavaD/E/F/bar.Java(および他のいくつかのJavaファイル)を追加したいと思います。

git add '*.Java'

残念ながら、それは期待どおりに機能しません。

152
Michel Krämer

追加するファイルの一部がまだ追跡されていない可能性がある場合は、おそらくSergio Acostaの答えが最善の策です。 gitが既に知っているファイルに制限したい場合は、git-ls-filesフィルター付き:

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

これは基本的にシェルの問題であるため、Gitはこれ自体を行うための凝ったメカニズムを提供しません。特定のコマンドの引数として提供するファイルのリストをどのように取得しますか。

81
Cascabel

git add [path]/\*.Javaを使用して、サブディレクトリからJavaファイルを追加し、
例えば。 git add ./\*.Java現在のディレクトリ。

git add documentation から:

Documentationディレクトリとそのサブディレクトリの下にあるすべての*.txtファイルからコンテンツを追加します。

$ git add Documentation/\*.txt

この例では、アスタリスク*がシェルから引用されていることに注意してください。これにより、コマンドにDocumentation/ディレクトリのサブディレクトリのファイルを含めることができます。

138
Sergey Glotov

少し外れたトピック(特にgit関連ではありません)が、linux/unixを使用している場合の回避策は次のとおりです。

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

そして、スペースを含むパスを期待する場合:

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

しかし、それはあなたが尋ねたとおりのものではないことを知っています。

53
Sergio Acosta

zshを使用すると、次を実行できます。

git add "**/*.Java"

そしてあなたのすべての*.Javaファイルは再帰的に追加されます。

49
Olivier Verdier

セルゲイの答え (私を信用しないでください)は機能しています:

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
12
Alberto

既にファイルを追跡しており、それらに変更を加えた後、パターンに基づいて選択的にファイルを追加したい場合は、--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
Ram

単にgit add *\*.Java。これにより、ルートディレクトリとすべてのサブディレクトリにすべての.Javaファイルが追加されます。

3
Jan Lovstrand

git statusに基づく特定の文字列を持つファイルのみを追加したかった:

git status | grep string | xargs git add

その後、git commit -m 'commit msgを使用して、ファイルのタイトルに「string」を含むすべての変更されたファイルをコミットできました

3
bdanin

git:globパターンに一致するすべてのファイルをディレクトリサブツリーに再帰的に追加するにはどうすればよいですか? 」、pathspecグロビング('*.Java'など)を適切にエスケープまたは引用する場合、はい、git add '*.Java'

Git 2.13(2017年第2四半期)では、対話型追加の改善が行われています。

commit 7288e12 (2017年3月14日)by Jeff King(peff を参照してください。
J浜野順夫-gitster- in commit 153e0d7 、2017年3月17日)

add --interactivels-filesでpathspecsを展開しないでください

変更されたファイルのリストを取得する場合は、最初に「ls-files」でユーザー指定のパス仕様を展開し、次に、結果のパスのリストを「diff-index」および「diff-files "。
pathspecが多数のパスに展開される場合、次の2つの問題のいずれかに遭遇する可能性があります。

  1. OSは、引数リストのサイズについて文句を言い、実行を拒否する場合があります。例えば:

    $ (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のファイルがあります(この場合はいずれも変更されません)。 「ulimit -s」トリックは、このような巨大なパスのセットであってもLinuxで問題を示すために必要です。
他のオペレーティングシステムには、はるかに小さな制限があります(たとえば、OS Xで5Kファイルのみで実際のケースが見られました)。

  1. 動作する場合でも、本当に遅いです。 pathspecコードは、膨大な数のパスに対して最適化されていません。 ulimitを使用しない場合も同じです。

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

これを改善するには、「ls-files」を完全にスキップし、元のパス仕様を単にdiffコマンドに渡します。

歴史的に「diff-index」でサポートされているpathspec言語は弱かったが、もはやそうではない。

2
VonC

まだ言及されていないWindowsコマンドラインソリューションの追加:

for /f %G in ('dir /b/s *.Java') do @git add %G
2
selalerer

〜/ .gitconfigに行を入れます

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

すべての修正されたJavaファイルでできることを追加する場合:git addt Java

同様に、すべての修正されたpythonファイルでできることは:git addt py

0
Hong Emrys