Рекурсивно додайте файли за зразком


172

Як мені рекурсивно додавати файли за шаблоном (або глобусом), розташованим у різних каталогах?

Наприклад, я хотів би додати A/B/C/foo.javaі D/E/F/bar.java(та кілька інших файлів java) за допомогою однієї команди:

git add '*.java'

На жаль, це не працює, як очікувалося.


2
Це працює для мене (Mac OS X, Git 1.7.1+). Яку версію ОС та Git ви використовуєте?
Кріс Джонсен

3
Якщо .javaу вашому поточному каталозі є декілька (вже відслідковуваних) файлів, ви, можливо, зіткнетеся з, е, складним підключенням підстановки між bash та "помічником" командного рядка msys . Я не впевнений у рішенні. Ви можете спробувати кілька шарів лапок: git add '"*.java"'(одинарні лапки приймаються bash для запобігання розширення глобальної форми, подвійні лапки приймаються шаром msys для запобігання розширення glob).
Кріс Джонсен

1
Дякую за замітку. На жаль, і це не працює. Кажуть, виправлено, але я вже маю останню версію.
Мішель Кремер


1
git add *.javaпрацює для мене (на патенті з клієнтом GitHub)
ThaDafinser

Відповіді:


89

Відповідь Серхіо Акоста - це, мабуть, найкраща ставка, якщо деякі файли, які потрібно додати, можливо, вже не відстежуються. Якщо ви хочете обмежитися файлами, про які вже знає git, ви можете комбінувати git-ls-filesз фільтром:

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

Git не забезпечує будь-яких фантазійних механізмів для цього, тому що це в основному проблема оболонки: як ви можете отримати список файлів, які можна надати в якості аргументів даній команді.


8
Дякую! Я трохи покращив ваше командування, і тепер він робить те, що я шукав:git ls-files -co --exclude-standard | grep '\.java$' | xargs git add
Мішель Крямер,

169

Ви можете використовувати git add [path]/\*.javaдля додавання файлів Java з підкаталогів,
наприклад, git add ./\*.javaдля поточного каталогу.

З git addдокументації :

Додає вміст з усіх *.txtфайлів у Documentationкаталозі та його підкаталогів:

$ git add Documentation/\*.txt

Зауважте, що зірочка *в цьому прикладі цитується із оболонки; це дозволяє команді включати файли з підкаталогів Documentation/каталогу.


2
@ MichelKrämer, мабуть, це не було, але це зараз.
Альберто

7
Це найкраще рішення, працює і у вікнах.
TheTFo

1
"зірочка * цитується з оболонки". Я думаю, ти маєш на увазі "втік". У будь-якому випадку, зворотна косої риски запобігає розширенню оболонки.
gwideman

1
@gwideman Я думаю, ти маєш рацію, але це не я. Це цитата з docs git-scm.com/docs/git-add#_examples
Сергій Глотов

62

З zshвами можна запустити:

git add "**/*.java"

і всі ваші *.javaфайли будуть додані рекурсивно.


Дякую за це, але я працюю з msysgit у Windows, і він має лише баш.
Мішель Кремер

1
Ну, я бачу, що є zshоболонка для windows ... ти зробиш собі послугу, щоб використовувати її замість bash, imho.
Олів'є Верд'є,

1
Порт Windows zsh заснований на дуже старій версії і весь час виходить з ладу (наприклад, коли я входжу ls).
Мішель Кремер

Нічого собі, ідеально. Я не знав про цю особливість!
Томаш Вотруба

1
Це нічого спільного з zsh. Я думаю, що ця відповідь пропускає те, що ви хочете пройти шлях із незахищеними символами, щоб не зійти, і дозволити git обробляти його. Таким чином, ви хочете не допустити розширення підстановок (-ів), які б оболонки ви не використовували. Для цього вам потрібно процитувати це деяким чином, що підходить для оболонки, яку ви використовуєте. Дивіться інші відповіді для детальної інформації.
gwideman

55

Трохи поза темою (не стосується спеціально git), але якщо ви в Linux / unix, вирішення може бути:

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

І якщо ви очікуєте шляхи з пробілами:

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

Але я знаю, що це не саме те, що ви просили.


6
Незначна проблема при такому підході - якщо ви "знайдете" файл, який відповідає вашому .gitignore, тоді git скаржиться, що ви намагаєтеся додати файл, який ви йому сказали, щоб ігнорувати.
yoyo

2
@yoyo - Я щойно додав -f наприкінці, і це виправлено
Маслоу

5
@Maslow, це насильно додасть файл, навіть якщо його передбачалося ігнорувати (на основі .gitignore). Я вважаю за краще отримати скаргу та не додавати файл (що є поведінкою за замовчуванням.)
yoyo,

Як це в будь-якому випадку краще, ніж дозволяти Git виконувати розширення підстановки?
gwideman

12

Відповідь Сергія (не оцінюй мене) працює:

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

8

Якщо ви вже відстежуєте свої файли та вносили зміни до них, і тепер ви хочете додати їх вибірково на основі шаблону, ви можете використовувати --modifiedпрапор

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

Наприклад, якщо ви хочете лише додати зміни CSS до цього зобов’язання, ви можете це зробити

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

Дивіться man git-ls-filesбільше прапорів


5

Просто використовуйте git add *\*.java. Це додасть усі файли .java в кореневій каталог та всі підкаталоги.


Чудова відповідь. Я зробив git add * / pom.xml, щоб додати всі імена файлів pom.xml.
Філіп Рего

4

Додавання рішення командного рядка Windows, яке ще не було згадано:

for /f "delims=" %G in ('dir /b/s *.java') do @git add %G

3

Я хотів додати лише файли, які мали певний рядок на основі git status:

git status | grep string | xargs git add

а потім змогла git commit -m 'commit msgзафіксувати всі змінені файли з "рядком" у заголовку файла


2

Як згадується в " git: Як мені рекурсивно додати всі файли в піддерево каталогів, що відповідають глобальному шаблону? ", Якщо ви належним чином уникнути або процитувати ваш глобус pathspec (наприклад,'*.java' ), то так, git add'*.java'

Git 2.13 (Q2 2017) покращує показник для інтерактивного додавання:

Див. Запис 7288e12 (14 березня 2017 р.) Від Джеффа Кінга ( peff) .
(Об'єднав Хуніо С Хамано - gitster- у комітеті 153e0d7 , 17 березня 2017 р.)

add --interactive: не розгортайте проспекти шляху за допомогою ls-files

Коли ми хочемо отримати список модифікованих файлів, ми спочатку розширюємо будь-які надані користувачем спекуляції за допомогою " ls-files", а потім подаємо отриманий список шляхів як аргументи до " diff-index" і " diff-files".
Якщо ваш pathspec розшириться на велику кількість шляхів, ви можете зіткнутися з однією з двох проблем:

  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сховищі, яке містить близько 20 К файлів у каталозі "драйвери" (жоден з них не змінюється в цьому випадку). " ulimit -s" Трюк необхідний, щоб показати проблему в Linux навіть для такого гігантського набору шляхів.
Інші операційні системи мають набагато менші обмеження (наприклад, в реальному світі було викладено лише 5K файлів на OS X).

  1. Навіть коли це працює, це дуже повільно. Код pathspec не оптимізований для величезної кількості шляхів. Ось той самий випадок без уваги:

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

Ми можемо покращити це, пропустивши ls-filesповністю " " "і просто подавши початкові особливості шляху до команд diff.

Історично мова " diff-index", яка підтримується " ", була слабшою, але це вже не так.


1

поставити рядок у ~ / .gitconfig

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

Якщо ви хочете додати всі модифіковані файли java, можна просто зробити: git addt java

Так само, якщо ви хочете додати весь змінений файл python, ви можете просто зробити: git addt py

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.