Aggiungi ricorsivamente i file per modello

Come aggiungo in modo ricorsivo i file mediante un pattern (o glob) posizionato in diverse directory?

Ad esempio, mi piacerebbe aggiungere A/B/C/foo.java e D/E/F/bar.java (e molti altri file java) con un comando:

 git add '*.java' 

Sfortunatamente, questo non funziona come previsto.

La risposta di Sergio Acosta è probabilmente la scelta migliore se alcuni dei file da aggiungere potrebbero non essere già tracciati. Se vuoi limitarti ai file git che già conosci, puoi combinare git-ls-files con un filtro:

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

Git non fornisce alcun meccanismo di fantasia per farlo da solo, in quanto è fondamentalmente un problema di shell: come si ottiene un elenco di file da fornire come argomenti per un determinato comando.

Puoi usare git add [path]/\*.java per aggiungere file java da sottodirectory,
ad esempio git add ./\*.java per la directory corrente.

Da git add documentazione :

Aggiunge il contenuto di tutti i file *.txt nella directory Documentation e le sue sottodirectory:

 $ git add Documentation/\*.txt 

Si noti che l’asterisco * è quotato dalla shell in questo esempio; questo consente al comando di includere i file dalle sottodirectory della directory Documentation/ .

Un po ‘fuori tema (non specificamente git related) ma se sei su linux / unix una soluzione potrebbe essere:

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

E se ti aspetti percorsi con spazi:

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

Ma so che non è esattamente quello che hai chiesto.

Con zsh puoi eseguire:

 git add "**/*.java" 

e tutti i tuoi file *.java verranno aggiunti in modo ricorsivo.

La risposta di Sergey (non mi credito) sta funzionando:

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

con un recente git:

 $git version git version 1.7.3.4 

File per il 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 

Stato Git:

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

Aggiunta di * .txt:

 $git add \*.txt 

Stato aggiornato:

 $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 

Se stai già rintracciando i tuoi file e hai apportato delle modifiche e ora desideri aggiungerli in modo selettivo in base a un modello, puoi utilizzare il flag --modified

 git ls-files --modified | grep '' | xargs git add 

Ad esempio, se vuoi solo aggiungere le modifiche CSS a questo commit, puoi farlo

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

Vedi man git-ls-files per ulteriori flag

Come accennato in ” git: Come faccio ad aggiungere ricorsivamente tutti i file in una sottostruttura di directory che corrisponde a un modello glob? “, Se esci o citassi correttamente il tuo pathspec globbing (come '*.java' ), allora sì, git add '*.java'

Git 2.13 (2 ° trim. 2017) migliora quello per l’aggiunta intertriggers:

Vedi commit 7288e12 (14 mar 2017) di Jeff King ( peff ) .
(Unito da Junio ​​C Hamano – gitster – in commit 153e0d7 , 17 mar 2017)

add --interactive : non espandere pathspecs con ls-files

Quando vogliamo ottenere l’elenco dei file modificati, per prima cosa espandiamo qualsiasi pathspec fornito dall’utente con ” ls-files “, quindi alimentiamo l’elenco risultante di percorsi come argomenti su ” diff-index ” e ” diff-files “.
Se il tuo pathspec si espande in un numero elevato di percorsi, potresti riscontrare uno di questi due problemi:

  1. Il sistema operativo può lamentarsi della dimensione dell’elenco di argomenti e rifiutarsi di eseguire. Per esempio:

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

Quello è nel repository linux.git , che ha circa 20K file nella directory “drivers” (nessuno di questi è stato modificato in questo caso). Il trucco ” ulimit -s ” è necessario per mostrare il problema su Linux anche per un insieme così gigantesco di percorsi.
Altri sistemi operativi hanno limiti molto più piccoli (ad esempio, un caso reale è stato visto con solo 5 file su OS X).

  1. Anche quando funziona, è molto lento. Il codice pathspec non è ottimizzato per un numero enorme di percorsi. Ecco lo stesso caso senza l’ulimit:

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

Possiamo migliorare questo saltando completamente ” ls-files ” e semplicemente alimentando i pathspec originali ai comandi diff.

Storicamente il linguaggio pathspec supportato da ” diff-index ” era più debole, ma non è più così.

Volevo aggiungere solo file con una determinata stringa basata sullo git status :

git status | grep string | xargs git add

e quindi è stato in grado di git commit -m 'commit msg per salvare tutti i file modificati con “string” nel titolo del file

Basta usare git add *\*.java . Ciò aggiungerà tutti i file .java nella directory principale e in tutte le sottodirectory.