سؤال

سؤال لطيف وبسيط - هل وظيفة "جلب git" مجموعة فرعية صارمة من git fetch --tags?

أي إذا ركضت git fetch --tags, ، هل هناك سبب للتشغيل على الفور git fetch مباشرة بعد ذلك؟

ماذا عن git pull و git pull --tags؟ نفس الموقف؟

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

المحلول

ملاحظة: بدءا من GIT 1.9/2.0 (Q1 2014), git fetch --tags تجلب العلامات بالإضافة إلى ما الذي يتم جلبه بواسطة سطر الأوامر نفسه بدون الخيار.

نرى ارتكاب C5A84E9 بواسطة مايكل هاجرتي (مخاغر):

سابقا ، جلب "--tags"تم اعتبار الخيار مكافئًا لتحديد المرجع

refs/tags/*:refs/tags/*

على سطر الأوامر ؛ على وجه الخصوص ، تسبب في remote.<name>.refspec التكوين ليتم تجاهله.

لكن ليس من المفيد جدًا إحضار العلامات دون جلب مراجع أخرى أيضًا هو مفيد جدًا لتكون قادرًا على جلب العلامات بالإضافة إلى مراجع أخرى.
لذا قم بتغيير دلالات هذا الخيار للقيام بهذا الأخير.

إذا أراد المستخدم إحضاره فقط العلامات ، ثم لا يزال من الممكن تحديد refspec صريح:

git fetch <remote> 'refs/tags/*:refs/tags/*'

يرجى ملاحظة أن الوثائق قبل 1.8.0.3 كانت غامضة حول هذا الجانب من "fetch --tags" سلوك.
ارتكاب F0CB2F1 (2012-12-14) fetch --tags جعل الوثائق تطابق السلوك القديم.
يغير هذا الالتزام الوثائق لمطابقة السلوك الجديد (انظر Documentation/fetch-options.txt).

اطلب جلب جميع العلامات من جهاز التحكم عن بُعد بالإضافة إلى أي شيء آخر يتم جلبه.


منذ GIT 2.5 (Q2 2015) git pull --tags أكثر قوة:

نرى الالتزام 19d122b بواسطة بول تان (pyokagan), ، 13 مايو 2015.
(دمجها جونيو سي هامانو - gitster -- في ارتكاب CC77B99, ، 22 مايو 2015)

pull: إزالة --tags خطأ في حالة عدم دمج المرشحين

حيث 441ED41 ("git pull --tags": خطأ في رسالة أفضل. ، 2007-12-28 ، GIT 1.5.4+) ، git pull --tags سوف تطبع رسالة خطأ مختلفة إذا git-fetch لم يعيد أي مرشحين لدمج:

It doesn't make sense to pull all tags; you probably meant:
       git fetch --tags

هذا لأنه في ذلك الوقت ، git-fetch --tags من شأنه أن يتجاوز أي مصادر تم تكوينها ، وبالتالي لن يكون هناك مرشحين دمج. وبالتالي تم تقديم رسالة الخطأ لمنع الارتباك.

لكن منذ C5A84E9 (fetch --tags: جلب العلامات بالإضافة إلىأشياء أخرى ، 2013-10-30 ، git 1.9.0+) ، git fetch --tags من شأنه أن يجلب العلامات بالإضافة إلى أي مصممات تم تكوينها.
وبالتالي ، إذا لم يحدث أي حالة من المرشحين ، فهذا ليس بسبب --tags تم تعيين. على هذا النحو ، أصبحت رسالة الخطأ الخاصة هذه غير ذات صلة الآن.

لمنع الارتباك ، قم بإزالة رسالة الخطأ هذه.


مع GIT 2.11+ (Q4 2016) git fetch أسرع.

نرى الالتزام 5827A03 (13 أكتوبر 2016) جيف كينغ (peff).
(دمجها جونيو سي هامانو - gitster -- في الالتزام 9FCD144, ، 26 أكتوبر 2016)

fetch: استخدم "سريع" has_sha1_file للعلامة التالية

عند جلبه من جهاز تحكم عن بُعد يحتوي على العديد من العلامات التي لا علاقة لها بالفروع التي نتابعها ، اعتدنا أن نضيع الكثير من الدورات عند التحقق مما إذا كان الكائن الموجود في علامة (لن نجلبه!) موجود في مستودعنا بعناية جدا.

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

فيما يلي نتائج من البرنامج النصي المُشمل ، والذي يقوم بإعداد موقف مشابه للواحد الموضح أعلاه:

Test            HEAD^               HEAD
----------------------------------------------------------
5550.4: fetch   11.21(10.42+0.78)   0.08(0.04+0.02) -99.3%

هذا ينطبق فقط على موقف حيث:

  1. لديك الكثير من الحزم على جانب العميل لصنعها reprepare_packed_git() باهظ الثمن (الجزء الأكثر تكلفة هو العثور على التكرارات في قائمة غير موضحة ، والتي هي في الوقت الحالي التربيعي).
  2. أنت بحاجة إلى عدد كبير من المراجعات على جانب الخادم المرشحين للمتابعة التلقائية (أي أن العميل ليس لديه). كل واحد يؤدي إلى إعادة قراءة دليل الحزمة.
  3. في ظل الظروف العادية ، كان العميل يتبع تلك العلامات تلقائيًا وبعد إحضار كبير ، (2) لن يكون صحيحًا.
    ولكن إذا كانت هذه العلامات تشير إلى التاريخ الذي يتم فصله عن ما يجلبه العميل على خلاف ذلك ، فلن يتبع ذلك أبدًا ، وسيؤثر هؤلاء المرشحون على كل جلب.

يبدو أن GIT 2.21 (فبراير 2019) قد أدخل انحدارًا عندما يكون تكوين remote.origin.fetch هو ليس الافتراضي واحد ('+refs/heads/*:refs/remotes/origin/*')

fatal: multiple updates for ref 'refs/tags/v1.0.0' not allowed

نصائح أخرى

ملاحظة: هذه الإجابة صالحة فقط لـ Git V1.8 وما فوق.

وقد قيل معظم هذا في الإجابات والتعليقات الأخرى ، ولكن إليك تفسير موجز:

  • git fetch يجلب جميع رؤوس الفروع (أو كلها محددة بواسطة خيار التكوين عن بعد. في معظم الحالات ، يمكن الوصول إلى جميع العلامات بهذه الطريقة.
  • git fetch --tags يجلب جميع العلامات ، كل الالتزامات اللازمة لهم. فإنه سوف ليس تحديث رؤوس فرع ، حتى لو كانت قابلة للوصول من العلامات التي تم جلبها.

ملخص: إذا كنت تريد حقًا أن تكون محدثًا تمامًا ، باستخدام الجلب فقط ، فيجب عليك القيام بالأمرين.

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

سأجيب على هذا بنفسي.

لقد قررت أن هناك فرقًا. "Git Fetch -Tags" قد تجلب جميع العلامات ، لكنه لا يجلب أي ارتباط جديد!

تبين أن على المرء أن يفعل هذا ليكون "محدثًا تمامًا" ، أي تكرار "سحب git" دون دمج:

$ git fetch --tags
$ git fetch

هذا عار ، لأنه بطيء. إذا كان فقط "Git Fetch" لديه خيار للقيام بما يفعله عادة و جلب جميع العلامات.

المشكلة العامة هنا هي ذلك git fetch سوف يجلب +refs/heads/*:refs/remotes/$remote/*. إذا كان لدى أي من هذه الالتزامات علامات ، فسيتم أيضًا إحضار هذه العلامات. ومع ذلك ، إذا كانت هناك علامات لا يمكن الوصول إليها من قبل أي فرع على جهاز التحكم عن بُعد ، فلن يتم جلبها.

ال --tags الخيار يقوم بتبديل RefSpec إلى +refs/tags/*:refs/tags/*. أنت استطاع يطلب git fetch للاستيلاء على حد سواء. أنا متأكد من أن أفعل فقط git fetch && git fetch -t كنت تستخدم الأمر التالي:

git fetch origin "+refs/heads/*:refs/remotes/origin/*" "+refs/tags/*:refs/tags/*"

وإذا كنت ترغب في جعل هذا الافتراضي لهذا الريبو ، فيمكنك إضافة Refspec الثاني إلى الجلب الافتراضي:

git config --local --add remote.origin.fetch "+refs/tags/*:refs/tags/*"

هذا سيضيف ثانية fetch = خط في .git/config لهذا عن بُعد.


قضيت بعض الوقت أبحث عن طريقة للتعامل مع هذا للمشروع. هذا هو ما خطرت لي.

git fetch -fup origin "+refs/*:refs/*"

في حالتي أردت هذه الميزات

  • احصل على جميع الرؤوس والعلامات من جهاز التحكم عن بُعد لذا استخدم RefSpec refs/*:refs/*
  • الكتابة فوق الفروع والعلامات المحلية مع غير سريع إلى الأمام + قبل المرجع
  • الكتابة فوقها تم فحصها حاليًا إذا لزم الأمر -u
  • حذف الفروع والعلامات غير موجودة في عن بعد -p
  • والقوة للتأكد -f

في معظم المواقف ، git fetch يجب أن تفعل ما تريد ، وهو "الحصول على أي شيء جديد من المستودع البعيد ووضعه في نسختك المحلية دون الاندماج على فروعك المحلية". git fetch --tags يفعل ذلك بالضبط ، إلا أنه لا يحصل على أي شيء باستثناء علامات جديدة.

في هذا المعنى، git fetch --tags ليس بأي حال من الأحوال مجموعة كبيرة من git fetch. إنه في الواقع عكس ذلك بالضبط.

git pull, بالطبع ، ليس سوى غلاف ل git fetch <thisrefspec>; git merge. يوصى بأن تعتاد على ممارسة دليل git fetchجي و git mergeجي قبل أن تقفز إلى git pull ببساطة لأنه يساعدك على فهم ماذا git pull يفعل في المقام الأول.

ومع ذلك ، فإن العلاقة هي نفسها كما هو الحال مع git fetch. git pull هو superset من git pull --tags.

git fetch upstream --tags

يعمل بشكل جيد ، بل سيحصل فقط على علامات جديدة ولن تحصل على أي قاعدة رمز أخرى.

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