Рекурсивно добавлять файлы по шаблону



как рекурсивно добавлять файлы по шаблону (или глобусу), расположенному в разных каталогах?



например, я хотел бы добавить A/B/C/foo.java и D/E/F/bar.java (и несколько других файлов java) с одной командой:



git add '*.java'


к сожалению, это не работает, как ожидалось.

543   9  

9 ответов:

ответ Серхио Акосты, вероятно, ваш лучший выбор, если некоторые из файлов, которые будут добавлены, возможно, уже не отслеживаются. Если вы хотите ограничить себя файлами, о которых git уже знает, вы можете объединить git-ls-files с фильтром:

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

Git не предоставляет никаких причудливых механизмов для выполнения этого самого, поскольку это в основном проблема оболочки: как вы получаете список файлов для предоставления в качестве аргументов для данной команды.

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

С git add документация:

добавляет контент из всех *.txt файлы Documentation каталог и его подкаталоги:

$ git add Documentation/\*.txt

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

немного не по теме (не особенно связанные с git), но если вы находитесь на linux / unix обходной путь может быть:

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

и если вы ожидаете, что пути с пробелами:

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

но я знаю, что это не совсем то, что вы просили.

С zsh вы можете работать:

git add "**/*.java"

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

Сергей (не верьте мне) работает:

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

если вы уже отслеживаете свои файлы и внесли в них изменения, и теперь вы хотите добавить их выборочно на основе шаблона, вы можете использовать --modified флаг

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

например, если вы хотите только добавить изменения CSS в этот коммит, вы можете сделать

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

посмотреть man git-ls-files для большего количества флагов

как говорилось в "git: как рекурсивно добавить все файлы в поддерево каталога, соответствующие шаблону glob?", если вы правильно экранировать или брать в кавычки свой pathspec подстановка (например,'*.java'), то да, git add '*.java'

Git 2.13 (Q2 2017) улучшает это для интерактивного добавления:

посмотреть совершить 7288e12 (14 марта 2017) by Джефф Кинг (peff).
(слитый Junio C Hamano--gitster -- на commit 153e0d7, 17 марта 2017)

add --interactive: не разворачивайте pathspecs с помощью ls-files

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

  1. даже когда он работает, это очень медленно. The pathspec код не оптимизирован для огромного количества путей. Это место в этом случае без ограничение:

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

мы можем улучшить эту пропуска "ls-files " полностью, и просто подавая исходные pathspecs к командам diff.

исторически язык pathspec поддерживается "diff-index" был слабее, но это уже не так.

Я хотел только добавить файлы, которые имеют определенную строку git status:

git status | grep string | xargs git add

а потом смог git commit -m 'commit msg чтобы зафиксировать все измененные файлы с помощью "string" в заголовке файла

просто использовать git add *\*.java. Это добавит все .файлы java в корневом каталоге и во всех подкаталогах.

Comments

    Ничего не найдено.