سؤال

هل من الممكن أن يكون لديك علامات فرعية ضحلة؟ لديّ مشروع فائق مع العديد من العلامات الفرعية ، ولكل منها تاريخ طويل ، لذلك يصبح الأمر كبيرًا بشكل لا لزوم له في سحب كل هذا التاريخ.

كل ما وجدته هو هذا الموضوع لم تتم الإجابة عليه.

هل يجب علي فقط اختراق 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

  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.
    
  2. 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 للمفهوم وليس الحل. عندما تعمل ، تكون النتيجة استنساخ ضحل للوحدة الفرعية في تغييرات محددة.

إذا قام المستودع بإعادة تشغيل وحدة فرعية لالتزام مختلف ، أعد تشغيل البرنامج النصي لتحديثه.

المرة الوحيدة التي سيكون فيها البرنامج النصي مثل هذا مفيدًا للبناء المحلي غير المتعاون لمشروع المصدر.

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