web-dev-qa-db-fra.com

Ajouter récursivement des fichiers par motif

Comment ajouter de manière récursive des fichiers par un motif (ou un glob) situé dans des répertoires différents?

Par exemple, j'aimerais ajouter A/B/C/foo.Java et D/E/F/bar.Java (ainsi que plusieurs autres fichiers Java) avec une seule commande:

git add '*.Java'

Malheureusement, cela ne fonctionne pas comme prévu.

134
Michel Krämer

La réponse de Sergio Acosta est probablement votre meilleur choix si certains des fichiers à ajouter ne font pas déjà l'objet d'un suivi. Si vous voulez vous limiter aux fichiers que git connaît déjà, vous pouvez combiner git-ls-files avec un filtre:

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

Git ne fournit aucun mécanisme sophistiqué pour le faire lui-même, car il s’agit essentiellement d’un problème de Shell: comment obtenir une liste de fichiers à fournir comme arguments d’une commande donnée.

72
Cascabel

Vous pouvez utiliser git add [path]/\*.Java pour ajouter des fichiers Java à partir de sous-répertoires.
par exemple. git add ./\*.Java pour le répertoire en cours.

De git add documentation :

Ajoute le contenu de tous les fichiers *.txt du répertoire Documentation et de ses sous-répertoires:

$ git add Documentation/\*.txt

Notez que l'astérisque * est cité à partir du shell dans cet exemple; cela permet à la commande d'inclure les fichiers des sous-répertoires du répertoire Documentation/.

123
Sergey Glotov

Un peu hors sujet (pas spécifiquement lié à git) mais si vous êtes sur linux/unix, une solution pourrait être:

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

Et si vous attendez des chemins avec des espaces:

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

Mais je sais que ce n'est pas exactement ce que vous avez demandé.

48
Sergio Acosta

Avec zsh, vous pouvez exécuter:

git add "**/*.Java"

et tous vos fichiers *.Java seront ajoutés de manière récursive.

42
Olivier Verdier

La réponse de Sergey (ne me créditez pas) fonctionne:

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

avec un git récent:

$git version
git version 1.7.3.4

Fichiers pour le 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

Statut Git:

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

Ajout de * .txt:

$git add \*.txt

Statut mis à jour:

$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
10
Alberto

Si vous suivez déjà vos fichiers et les avez modifiés et que vous souhaitez maintenant les ajouter sélectivement en fonction d'un modèle, vous pouvez utiliser l'indicateur --modified.

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

Par exemple, si vous souhaitez uniquement ajouter les modifications CSS à cette validation, vous pouvez le faire.

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

Voir man git-ls-files pour plus de drapeaux

7
Ram

Comme mentionné dans " git: Comment puis-je ajouter récursivement tous les fichiers d'un sous-arbre de répertoire correspondant à un motif global? ", Si vous échappez ou citez correctement votre pathspec globbing (comme '*.Java'), alors oui, git add '*.Java'

Git 2.13 (T2 2017) améliore cela pour l'ajout interactif:

Voir commit 7288e12 (14 mars 2017) de Jeff King (peff) .
(Fusionnée par Junio ​​C Hamano - gitster - à commit 153e0d7 , 17 mars 2017)

add --interactive: ne développez pas pathspecs avec ls-files

Lorsque nous voulons obtenir la liste des fichiers modifiés, nous développons tout d'abord les pathspecs fournis par l'utilisateur avec "ls-files", puis nous alimentons la liste de chemins résultante sous forme d'arguments en "diff-index" et "diff-files".
Si votre pathspec se développe dans un grand nombre de chemins, vous pouvez rencontrer l'un des deux problèmes suivants:

  1. Le système d'exploitation peut se plaindre de la taille de l'argument liste, et refuser de courir. Par exemple:

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

Cela se trouve dans le référentiel linux.git, qui contient environ 20 000 fichiers dans le répertoire "drivers" (aucun d’eux n’a été modifié dans ce cas). L'astuce "ulimit -s" est nécessaire pour montrer le problème sous Linux, même pour un ensemble de chemins aussi gigantesque.
Les autres systèmes d'exploitation ont des limites beaucoup plus petites (par exemple, un cas réel a été vu avec seulement 5K fichiers sur OS X).

  1. Même quand ça marche, c'est vraiment lent. Pathspec le code n'est pas optimisé pour un grand nombre de chemins. Voici le même cas sans l'ulimit:

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

Nous pouvons améliorer cela en omettant complètement "ls-files" et en alimentant simplement les pathspecs d'origine dans les commandes diff.

Historiquement, le langage pathspec pris en charge par "diff-index" était plus faible, mais ce n'est plus le cas.

2
VonC

Je voulais uniquement ajouter des fichiers contenant une certaine chaîne basée sur git status:

git status | grep string | xargs git add

et puis était capable de git commit -m 'commit msg pour valider tous les fichiers modifiés avec "chaîne" dans le titre du fichier

2
bdanin

Ajout d'une solution de ligne de commande Windows non encore mentionnée:

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

mettre la ligne dans ~/.gitconfig

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

Si vous voulez ajouter tous les fichiers Java modifiés, vous pouvez simplement faire: git addt Java

Samely, si vous voulez ajouter tous les fichiers python modifiés, vous pouvez simplement faire: git addt py

0
Hong Emrys

Il suffit d'utiliser git add *\*.Java. Cela ajoutera tous les fichiers .Java dans le répertoire racine et tous les sous-répertoires.

0
Jan Lovstrand