سؤال

كيف يمكنني إضافة ملفات بشكل متكرر حسب نمط (أو غلوب) الموجود في أدلة مختلفة؟

على سبيل المثال ، أود أن أضيف A/B/C/foo.java و D/E/F/bar.java (والعديد من ملفات Java أخرى) مع أمر واحد:

git add '*.java'

لسوء الحظ ، هذا لا يعمل كما هو متوقع.

هل كانت مفيدة؟

المحلول

من المحتمل أن تكون إجابة سيرجيو أكوستا أفضل رهان لك إذا لم يتم بالفعل تتبع بعض الملفات التي سيتم إضافتها. إذا كنت ترغب في تقييد نفسك على الملفات التي تعرفها 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:

$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 status:

git status | grep string | xargs git add

ثم تمكنت من git commit -m 'commit msg لارتكاب جميع الملفات التي تم تغييرها باستخدام "سلسلة" في عنوان الملف

فقط استخدم git add *\*.java. سيؤدي هذا إلى إضافة جميع ملفات .java في دليل الجذر وجميع الدلائل الفرعية.

كما ذكر في ""GIT: كيف يمكنني إضافة جميع الملفات بشكل متكرر في الشجرة الفرعية التي تتطابق مع نمط الكرة الأرضية؟"، إذا هربت بشكل صحيح أو اقتبدت من لعبة PathSpec Globbing (مثل '*.java') ، ثم نعم ، GIT إضافة '*.java'

GIT 2.13 (Q2 2017) يحسن ذلك للإضافة التفاعلية:

نرى ارتكاب 7288E12 (14 مارس 2017) بواسطة جيف كينغ (peff).
(دمجها جونيو سي هامانو - gitster -- في ارتكاب 153E0D7, ، 17 مارس 2017)

add --interactive: لا توسع pathspecs مع 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 لأعداد كبيرة من المسارات. إليك نفس الحالة بدون Ulimit:

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

يمكننا تحسين هذا عن طريق تخطي "ls-files"تمامًا ، وتغذية PathSpecs الأصلية لأوامر DIFF.

تاريخيا لغة pathspec المدعومة من قبل "diff-index"كان أضعف ، لكن هذا لم يعد هو الحال.

إضافة حل سطر أوامر Windows لم يتم ذكره بعد:

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

ضع الخط في ~/.gitConfig

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

إذا كنت ترغب في إضافة جميع ملف Java المعدل ، فيمكن القيام بذلك:git addt java

Samely ، إذا كنت ترغب في إضافة جميع ملف Python المعدل ، فيمكن أن يفعل:git addt py

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top