كيف تصنع النسيج الفرعي الضحل؟
-
23-09-2019 - |
سؤال
هل من الممكن أن يكون لديك علامات فرعية ضحلة؟ لديّ مشروع فائق مع العديد من العلامات الفرعية ، ولكل منها تاريخ طويل ، لذلك يصبح الأمر كبيرًا بشكل لا لزوم له في سحب كل هذا التاريخ.
كل ما وجدته هو هذا الموضوع لم تتم الإجابة عليه.
هل يجب علي فقط اختراق git-submodule لتنفيذ هذا؟
المحلول
جديد في القادم Git1.8.4 (يوليو 2013):
"
git submodule update
"يمكن اختياريا استنساخ مستودعات الجهاز الفرعي الضحلة.
(و GIT 2.10 Q3 2016 يسمح بتسجيل ذلك git config -f .gitmodules submodule.<name>.shallow true
.
انظر نهاية هذه الإجابة)
يرى Commit 275CD184D52B5B81CB89E4EC33E540FB2AE61C1F:
أضف ال
--depth
خيار إلى أوامر إضافة وتحديث "الجهاز الفرعي git" ، والذي يتم نقله بعد ذلك إلى أمر clone. يكون هذا مفيدًا عندما تكون المواد الفرعية (S) ضخمة ولا تهتم حقًا بأي شيء سوى الالتزام الأخير.تتم إضافة الاختبارات وتم إجراء بعض تعديلات البندات لتتوافق مع بقية اختبار "تحديث الجهاز الفرعي يمكنه التعامل مع الروابط الرمزية في PWD".
توقيعه: فريدريك غوستافسون
<iveqy@iveqy.com>
Acked-by: Jens Lehmann<Jens.Lehmann@web.de>
هذا يعني أن هذا يعمل:
git submodule add --depth 1 -- repository path
git submodule update --depth -- [<path>...]
مع:
--depth::
هذا الخيار صالح ل
add
وupdate
الأوامر.
قم بإنشاء استنساخ "ضحل" مع تاريخ مقطوع إلى العدد المحدد من المراجعات.
أتويمان يضيف في التعليقات:
بقدر ما أستطيع أن أقول هذا الخيار غير قابل للاستخدام للفيروسات الفرعية التي لا تتتبع
master
عن كثب. إذا قمت بتعيين العمق 1 ، ثمsubmodule update
لا يمكن أن تنجح إلا إذا تلتزم الجهاز الفرعي الذي تريده هو أحدث سيد. وإلا ستحصل على "fatal: reference is not a tree
".
هذا صحيح.
هذا هو ، حتى GIT 2.8 (مارس 2016). مع 2.8 ، و submodule update --depth
لديه فرصة أخرى للنجاح ، حتى لو كان SHA1 يمكن الوصول إليه مباشرة من أحد رؤوس الريبو عن بُعد.
يرى ارتكاب FB43E31 (24 فبراير 2016) بواسطة ستيفان بيلر (stefanbeller
).
ساعد: جونيو سي هامانو (gitster
).
(دمجها جونيو سي هامانو - gitster
-- في الالتزام 9671A76, ، 26 فبراير 2016)
الجهاز الفرعي: حاول أن تجلب جلب SHA1 المطلوب عن طريق جلب SHA1 المباشر
عند مراجعة التغيير الذي يقوم أيضًا بتحديث وحدة فرعية في Gerrit ، تتمثل ممارسة المراجعة الشائعة في تنزيل التصحيح محليًا واختياره محليًا لاختباره.
ولكن عند اختباره محليًا ، ''git submodule update
"قد تفشل في جلب الجهاز الفرعي الصحيح SHA1 لأن الالتزام المقابل في الجهاز الفرعي لم يكن بعد جزءًا من تاريخ المشروع ، ولكن أيضًا مجرد تغيير مقترح.لو
$sha1
لم يكن جزءًا من الجلب الافتراضي ، نحاول جلب$sha1
مباشرة. ومع ذلك ، لا تدعم بعض الخوادم الجلب المباشر بواسطة SHA1 ، الذي يؤديgit-fetch
للفشل بسرعة.
يمكننا أن نخفق أنفسنا هنا لأن SHA1 المفقود سيؤدي إلى فشل في وقت لاحق في مرحلة الخروج على أي حال ، لذا فإن الفشل هنا جيد قدر استطاعتنا.
MVG يشير الى في التعليقات ل ارتكاب FB43E31 (Git 2.9 ، فبراير 2016)
يبدو لي ذلك ارتكاب FB43E31 يطلب الالتزام المفقود من قبل معرف SHA1 ، وبالتالي فإن
uploadpack.allowReachableSHA1InWant
وuploadpack.allowTipSHA1InWant
من المحتمل أن تؤثر الإعدادات على الخادم على ما إذا كان هذا يعمل.
كتبت أ انشر إلى قائمة git اليوم, ، مع الإشارة إلى كيف يمكن أن يكون استخدام الوحدات الفرعية الضحلة للعمل بشكل أفضل في بعض السيناريوهات ، أي إذا كان الالتزام أيضًا علامة.
لننتظر ونرى.أعتقد أن هذا سبب يجعل FB43E31 جلبًا لـ SHA1 محددًا في العودة إلى الوراء بعد جلب الفرع الافتراضي.
ومع ذلك ، في حالة "-Depth 1" ، أعتقد أنه من المنطقي الإجهاض مبكرًا: إذا لم يطابق أي من الحكام المذكورة المطلوبة ، ولا يدعم الخادم SHA1 ، فلا فائدة من ذلك جلب أي شيء ، لأننا لن نتمكن من تلبية متطلبات الجهاز الفرعي في كلتا الحالتين.
تحديث أغسطس 2016 (بعد 3 سنوات)
مع GIT 2.10 (Q3 2016) ، ستتمكن من القيام به
git config -f .gitmodules submodule.<name>.shallow true
يرى "الجهاز الفرعي git دون وزن إضافي" للمزيد من.
GIT 2.13 (Q2 2017) قم بإضافة في ارتكاب 8d3047c (19 أبريل 2017) بواسطة سيباستيان شوبرث (sschuberth
).
(دمجها سيباستيان شوبرث - sschuberth
-- في ارتكاب 8d3047c, ، 20 أبريل 2017)
سيتم تنفيذ استنساخ من هذه المواد الفرعية كاستنساخ ضحل (مع عمق التاريخ 1)
لكن، سيرو سانتيلي يضيف في التعليقات (والتفاصيل في إجابته)
shallow = true
تشغيل.gitmodules
يؤثر فقط على المرجع الذي تتبعه رأس جهاز التحكم عن بُعد عند استخدامه--recurse-submodules
, ، حتى لو كان التزام الهدف يشير إليه فرع ، وحتى لو وضعتbranch = mybranch
على ال.gitmodules
أيضًا.
GIT 2.20 (Q4 2018) يتحسن من دعم الجهاز الفرعي ، والذي تم تحديثه للقراءة من النقطة في HEAD:.gitmodules
عندما .gitmodules
الملف مفقود من شجرة العمل.
يرى ارتكاب 2B1257E, ارتكاب 76E9BDC (25 أكتوبر 2018) ، و ارتكاب B5C259F, الالتزام 23dd8f5, ارتكاب B2FAAD4, ارتكاب 2502FFC, الالتزام 996DF4D, ارتكاب D1B13DF, ارتكاب 45F5EF3, ارتكاب BCBC780 (05 أكتوبر 2018) بواسطة أنطونيو أوسيت (ao2
).
(دمجها جونيو سي هامانو - gitster
-- في ارتكاب ABB4824, ، 13 نوفمبر 2018)
submodule
: دعم القراءة.gitmodules
عندما لا تكون في شجرة العملعندما
.gitmodules
الملف غير متوفر في شجرة العمل ، حاول استخدام المحتوى من الفهرس ومن الفرع الحالي.
يغطي هذا الحالة عندما يكون الملف جزءًا من المستودع ولكن لسبب ما لم يتم التحقق منه ، على سبيل المثال بسبب الخروج المتفرّق.هذا يجعل من الممكن استخدام على الأقل '
git submodule
أوامر التي اقرأ الgitmodules
ملف التكوين دون ملء شجرة العمل بالكامل.الكتابة ل
.gitmodules
سيظل يتطلب التحقق من الملف ، لذا تحقق من ذلك قبل الاتصالconfig_set_in_gitmodules_file_gently
.أضف شيكًا مشابهًا أيضًا
git-submodule.sh::cmd_add()
لتوقع الفشل النهائي لـ "git submodule add
"أمر متى.gitmodules
غير قابل للكتابة بأمان. هذا يمنع الأمر من ترك المستودع في حالة زائفة (على سبيل المثال ، تم استنساخ مستودع الجهاز الفرعي ولكن.gitmodules
لم يتم تحديثه بسببconfig_set_in_gitmodules_file_gently
باءت بالفشل).علاوة على ذلك ، منذ ذلك الحين
config_from_gitmodules()
الآن يصل إلى متجر الكائنات العالمية ، من الضروري حماية جميع مسارات التعليمات البرمجية التي تستدعي الوظيفة مقابل الوصول المتزامن إلى متجر الكائنات العالمي.
حاليا هذا يحدث فقط فيbuiltin/grep.c::grep_submodules()
, ، لذلك ندعوgrep_read_lock()
قبل استدعاء الكود الذي ينطويconfig_from_gitmodules()
.ملاحظة: هناك حالة واحدة نادرة لا تعمل فيها هذه الميزة الجديدة بشكل صحيح بعد: عروض فرعية متداخلة بدونها
.gitmodules
في شجرة العمل.
نصائح أخرى
شخص سخيف 2.9.0 الدعم النسيجية الفرعية استنساخ ضحل مباشرة ، لذلك يمكنك الآن الاتصال:
git clone url://to/source/repository --recursive --shallow-submodules
الآتي إجابة ريان تمكنت من التوصل إلى هذا البرنامج النصي البسيط الذي يكرر من خلال جميع النماذج الفرعية والاستنساخ الضحل:
#!/bin/bash
git submodule init
for i in $(git submodule | sed -e 's/.* //'); do
spath=$(git config -f .gitmodules --get submodule.$i.path)
surl=$(git config -f .gitmodules --get submodule.$i.url)
git clone --depth 1 $surl $spath
done
git submodule update
من خلال القراءة من خلال "مصدر" git-submodule ، يبدو الأمر git submodule add
يمكن التعامل مع العارض الفرعي الذي يوجد بالفعل مستودعاتها. في هذه الحالة...
$ git clone $remote1 $repo
$ cd $repo
$ git clone --depth 5 $remotesub1 $sub1
$ git submodule add $remotesub1 $sub1
#repeat as necessary...
ستحتاج إلى التأكد من أن الالتزام المطلوب في ريبو الجهاز الفرعي ، لذا تأكد من تعيين معمق مناسب.
تحرير: قد تكون قادرًا على الابتعاد عن استنساخ عارض فرعي يدوي متعددة متبوعًا بتحديث واحد:
$ git clone $remote1 $repo
$ cd $repo
$ git clone --depth 5 $remotesub1 $sub1
#repeat as necessary...
$ git submodule update
ملخص السلوك عربات التي تجرها الدواب / غير متوقع / مزعج اعتبارًا من GIT 2.14.1
shallow = true
في.gitmodules
يؤثر فقطgit clone --recurse-submodules
إذاHEAD
من بين الوحدة الفرعية البعيدة تشير إلى الالتزام المطلوب ، حتى لو كان التزام الهدف يشير إليه فرع ، وحتى لو وضعتbranch = mybranch
على ال.gitmodules
أيضًا.نص اختبار محلي. نفس السلوك على Github 2017-11 ، حيث
HEAD
يتم التحكم فيه بواسطة إعداد ريبو الفرع الافتراضي:git clone --recurse-submodules https://github.com/cirosantilli/test-shallow-submodule-top-branch-shallow cd test-shallow-submodule-top-branch-shallow/mod git log # Multiple commits, not shallow.
git clone --recurse-submodules --shallow-submodules
يفشل إذا لم يتم الإشارة إلى الالتزام بواسطة فرع أو علامة برسالة:error: Server does not allow request for unadvertised object
.نص اختبار محلي. نفس السلوك على جيثب:
git clone --recurse-submodules --shallow-submodules https://github.com/cirosantilli/test-shallow-submodule-top-sha # error
سألت أيضًا في القائمة البريدية: https://marc.info/؟l=git&m=151863590026582&w=2 وكان الرد:
من الناحية النظرية ، يجب أن يكون هذا سهلاً. قون
في الممارسة العملية ليس كثيرا ، لسوء الحظ. وذلك لأن الاستنساخ سيحصل فقط على أحدث نصيحة للفرع (عادةً ماجستير). لا توجد آلية في استنساخ لتحديد SHA1 الدقيق المطلوب.
يدعم بروتوكول السلك أن يطلب SCH1s الدقيق ، بحيث يجب تغطيته. (التحذير: إنه يعمل فقط إذا كان مشغل الخادم يمكّنًا من التحميل.
يسمح Git-Petch بإحضار SHA1 التعسفي ، بحيث يمكنك تشغيل جلب بعد استنساخ العودية باستخدام "تحديث الجهاز الفرعي git" حيث سيستخدم الجلبات بعد الاستنساخ الأولي.
اختبار تودو: allowReachableSHA1InWant
.
هل المواقع الكنسية للفيروسات الفرعية الخاصة بك عن بعد؟ إذا كان الأمر كذلك ، هل أنت بخير مع استنساخهم مرة واحدة؟ بمعنى آخر ، هل تريد الحيوانات المستنسخة الضحلة لمجرد أنك تعاني من عرض النطاق الترددي الضائع من الحيوانات المستنسخة الفرعية المتكررة (إعادة)؟
إذا كنت تريد أن تنقذ الحيوانات المستنسخة الضحلة ، فإن إجابة ريان جراهام تبدو وكأنها طريقة جيدة للذهاب. استنساخ المستودعات يدويًا حتى تكون ضحلة. إذا كنت تعتقد أنه سيكون مفيدًا ، فتكيف git submodule
لدعمها. إرسال بريد إلكتروني إلى القائمة السؤال عن ذلك (نصيحة لتنفيذها ، والاقتراحات على الواجهة ، وما إلى ذلك). في رأيي ، فإن الناس هناك داعمين تمامًا للمساهمين المحتملين الذين يريدون بجدية تعزيز GIT بطرق بناءة.
إذا كنت موافقًا على القيام باستنساخ كامل لكل وحدة فرعية (بالإضافة إلى جلبه لاحقًا للحفاظ على تحديثها) ، يمكنك محاولة استخدام --reference
خيار git submodule update
(في Git 1.6.4 وما بعد ذلك) للإشارة إلى متاجر الكائنات المحلية (على سبيل المثال ، --mirror
استنساخ من مستودعات الجزيئات الفرعية الكنسي ، ثم استخدم --reference
في العدوى الفرعية الخاصة بك للإشارة إلى هذه الحيوانات المستنسخة المحلية). فقط تأكد من القراءة عن git clone --reference
/git clone --shared
قبل استعمال --reference
. إن المشكلة الوحيدة المحتملة في المرايا المرجعية ستكون إذا انتهى بها الأمر إلى جلب التحديثات غير السريعة (على الرغم من أنه يمكنك تمكين عمليات الرش وتوسيع نوافذ انتهاء الصلاحية للمساعدة في الاحتفاظ بأي ارتباطات مهجورة قد تسبب مشكلة). يجب ألا تواجه أي مشاكل طالما
- أنت لا تجعل أي وحدة فرعية محلية ترتكز ، أو
- أي ارتكاب يترك يتدلى من خلال عدم الصعوبة التي قد تنشرها المستودعات الكنسيات ليست أسلافًا إلى الجهاز الفرعي المحلي الخاص بك ، أو
- أنت مجتهد بشأن الحفاظ على ارتكاب الجهاز الفرعي المحلي الخاص بك على رأس أي ما يمكن نشره غير سريع إلى الأمام في مستودعات الجهاز الفرعي الكنسي.
إذا ذهبت مع شيء من هذا القبيل ، وهناك أي فرصة لكي تتمكن من حمل الجهاز الفرعي المحلي في أشجار العمل الخاصة بك ، فربما يكون من الجيد إنشاء نظام آلي يتأكد من أن الكائنات الحرجة المشار إليها ترك يتدلى في مستودعات المرآة (وإذا تم العثور على أي منها ، يقوم بنسخها إلى المستودعات التي تحتاج إليها).
ومثل git clone
يقول manpage ، لا تستخدم --reference
إذا كنت لا تفهم هذه الآثار.
# Full clone (mirror), done once.
git clone --mirror $sub1_url $path_to_mirrors/$sub1_name.git
git clone --mirror $sub2_url $path_to_mirrors/$sub2_name.git
# Reference the full clones any time you initialize a submodule
git clone $super_url super
cd super
git submodule update --init --reference $path_to_mirrors/$sub1_name.git $sub1_path_in_super
git submodule update --init --reference $path_to_mirrors/$sub2_name.git $sub2_path_in_super
# To avoid extra packs in each of the superprojects' submodules,
# update the mirror clones before any pull/merge in super-projects.
for p in $path_to_mirrors/*.git; do GIT_DIR="$p" git fetch; done
cd super
git pull # merges in new versions of submodules
git submodule update # update sub refs, checkout new versions,
# but no download since they reference the updated mirrors
بدلا من ذلك ، بدلا من --reference
, ، يمكنك استخدام استنساخ المرآة مع وظائف الترابط الافتراضية لـ git clone
باستخدام المرايا المحلية كمصدر للفيروسات الفرعية الخاصة بك. في استنساخ جديد الفائق ، افعل git submodule init
, ، تحرير عناوين URL الفرعية في .git/config
للإشارة إلى المرايا المحلية ، ثم تفعل git submodule update
. ستحتاج إلى التخلص من أي مواد فرعية محددة موجودة للحصول على الروابط الصلبة. ستوفر عرض النطاق الترددي عن طريق التنزيل مرة واحدة فقط في المرايا ، ثم تجلبها محليًا من تلك التي تم فحصها. من شأن الربط الصلب أن ينقذ مساحة القرص (على الرغم من أن الجلبات تميل إلى التراكم وتكرارها عبر حالات متعددة من متاجر الكائنات الفرعية التي تم فحصها ؛ يمكنك أن تتخلى بشكل دوري من الجهاز الفرعي الذي تم فحصه من المرايا لاستعادة مساحة القرص التي توفرها بواسطة المتشددين).
لقد قمت بإنشاء نسخة مختلفة قليلاً ، لأنه عندما لا يتم تشغيله على حافة النزف ، وهو ما لا تفعل كل المشاريع. الإضافات الفرعية القياسية لم تعمل ولم تنص البرنامج النصي أعلاه. لذلك أضفت بحثًا عن التجزئة لـ Tag Ref ، وإذا لم يكن يحتوي على واحدة ، فإنه يعود إلى استنساخ كامل.
#!/bin/bash
git submodule init
git submodule | while read hash name junk; do
spath=$(git config -f .gitmodules --get submodule.$name.path)
surl=$(git config -f .gitmodules --get submodule.$name.url)
sbr=$(git ls-remote --tags $surl | sed -r "/${hash:1}/ s|^.*tags/([^^]+).*\$|\1|p;d")
if [ -z $sbr ]; then
git clone $surl $spath
else
git clone -b $sbr --depth 1 --single-branch $surl $spath
fi
done
git submodule update
إشارة إلى كيفية استنساخ مستودع GIT مع مراجعة/تغييرات محددة؟
لقد كتبت نصًا بسيطًا ليس لديه مشكلة عندما تكون مرجع الجهاز الفرعي الخاص بك بعيدًا عن السيد
git submodule foreach --recursive 'git rev-parse HEAD | xargs -I {} git fetch origin {} && git reset --hard FETCH_HEAD'
سيجلب هذا البيان النسخة المرجعية من الجهاز الفرعي.
إنه سريع ولكن لا يمكنك ارتكاب تحريرك على الجهاز الفرعي (عليك أن تجلبه من قبل https://stackoverflow.com/a/17937889/3156509)
كليا:
#!/bin/bash
git submodule init
git submodule foreach --recursive 'git rev-parse HEAD | xargs -I {} git fetch origin {} && git reset --hard FETCH_HEAD'
git submodule update --recursive
استنساخ ضحلة للوحدة الفرعية مثالية لأنها لقطة في مراجعة/تغييرات معينة. من السهل تنزيل Zip من موقع الويب ، لذا حاولت الحصول على نص.
#!/bin/bash
git submodule deinit --all -f
for value in $(git submodule | perl -pe 's/.*(\w{40})\s([^\s]+).*/\1:\2/'); do
mysha=${value%:*}
mysub=${value#*:}
myurl=$(grep -A2 -Pi "path = $mysub" .gitmodules | grep -Pio '(?<=url =).*/[^.]+')
mydir=$(dirname $mysub)
wget $myurl/archive/$mysha.zip
unzip $mysha.zip -d $mydir
test -d $mysub && rm -rf $mysub
mv $mydir/*-$mysha $mysub
rm $mysha.zip
done
git submodule init
git submodule deinit --all -f
يمسح شجرة الجهاز الفرعي الذي يسمح بإعادة استخدام البرنامج النصي.
git submodule
يسترجع 40 char sha1 متبوعًا بمسار يتوافق مع نفسه في .gitmodules
. أستخدم Perl لتسلسل هذه المعلومات ، المحددة بواسطة القولون ، ثم استخدام تحويل متغير لفصل القيم إلى mysha
و mysub
.
هذه هي المفاتيح الحرجة لأننا نحتاج إلى SHA1 للتنزيل والمسار لربط url
في .gitmodules.
بالنظر إلى إدخال وحدة فرعية نموذجية:
[submodule "label"]
path = localpath
url = https://github.com/repository.git
myurl
مفاتيح على path =
ثم يبحث عن سطرين بعد الحصول على القيمة. قد لا تعمل هذه الطريقة باستمرار وتتطلب التحسين. عنوان URL GREP يبقى أي .git
اكتب المراجع من خلال المطابقة مع الأخير /
وأي شيء يصل إلى أ .
.
mydir
هو mysub
ناقص النهائي /name
الذي من شأنه أن يؤدي إلى الاسم الفرعي.
التالي هو wget
مع تنسيق URL Archive zip القابل للتنزيل. هذا قد يتغير في المستقبل.
فك ضغط الملف mydir
والتي ستكون الدليل الفرعي المحدد في مسار الجهاز الفرعي. سيكون المجلد الناتج هو العنصر الأخير من url
-sha1
.
تحقق لمعرفة ما إذا كان الدليل الفرعي المحدد في مسار الجهاز الفرعي موجودًا وإزالته للسماح بإعادة تسمية المجلد المستخرج.
mv
أعد تسمية المجلد المستخرج الذي يحتوي على SHA1 إلى مسار الجهاز الفرعي الصحيح.
حذف ملف zip الذي تم تنزيله.
الجهاز الفرعي init
هذا هو أكثر إثبات WIP للمفهوم وليس الحل. عندما تعمل ، تكون النتيجة استنساخ ضحل للوحدة الفرعية في تغييرات محددة.
إذا قام المستودع بإعادة تشغيل وحدة فرعية لالتزام مختلف ، أعد تشغيل البرنامج النصي لتحديثه.
المرة الوحيدة التي سيكون فيها البرنامج النصي مثل هذا مفيدًا للبناء المحلي غير المتعاون لمشروع المصدر.