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.
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.
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.
Ajoute le contenu de tous les fichiers
*.txt
du répertoireDocumentation
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épertoireDocumentation/
.
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é.
Avec zsh
, vous pouvez exécuter:
git add "**/*.Java"
et tous vos fichiers *.Java
seront ajoutés de manière récursive.
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
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
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 avecls-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:
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).
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.
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
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
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
Il suffit d'utiliser git add *\*.Java
. Cela ajoutera tous les fichiers .Java dans le répertoire racine et tous les sous-répertoires.