كيف يمكنني تحديد فرع/علامة عند إضافة وحدة فرعية git؟

StackOverflow https://stackoverflow.com/questions/1777854

  •  21-09-2019
  •  | 
  •  

سؤال

كيف git submodule add -b الشغل؟

بعد إضافة وحدة فرعية مع فرع معين ، مستودع مستنسخ جديد (بعد git submodule update --init) سيكون في التزام معين ، وليس الفرع نفسه (git status على الجهاز الفرعي يظهر "ليس حاليًا على أي فرع").

لا يمكنني العثور على أي معلومات عن .gitmodules أو .git/config حول فرع الجهاز الفرعي أو أي التزام محدد ، فكيف تكتشف Git ذلك؟

أيضا ، هل من الممكن تحديد علامة بدلاً من فرع؟

أنا أستخدم الإصدار 1.6.5.2.

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

المحلول

ملاحظة: أضافت GIT 1.8.2 إمكانية تتبع الفروع. انظر بعض الإجابات أدناه.


إنه أمر مربك بعض الشيء التعود على هذا ، لكن العارض الفرعي ليست في فرع. إنهم ، كما تقول ، مجرد مؤشر لالتزام معين بمستودع العرض الفرعي.

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

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

إذا كنت ترغب في نقل الجهاز الفرعي إلى علامة معينة:

cd submodule_directory
git checkout v1.0
cd ..
git add submodule_directory
git commit -m "moved submodule to v1.0"
git push

بعد ذلك ، تم تغيير مطور آخر يريد أن يكون قد تم تغيير Submodule_Directory إلى تلك العلامة ، يفعل هذا

git pull
git submodule update --init

git pull التغييرات التي تلتزم دليل الجهاز الفرعي الخاص بهم يشير إلى. git submodule update يندمج في الواقع في الكود الجديد.

نصائح أخرى

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

أنت تعلم أن لديك وحدة فرعية git عندما يكون لديك هذين الأمرين.

  1. لك .gitmodules لديه إدخال مثل ذلك:

    [submodule "SubmoduleTestRepo"]
        path = SubmoduleTestRepo
        url = https://github.com/jzaccone/SubmoduleTestRepo.git
    
  2. لديك كائن عرض فرعي (اسمه submoduletestrepo في هذا المثال) في مستودع GIT الخاص بك. جيثب يظهر هذه ككائنات "submodule". أو تفعل git submodule status من سطر الأوامر. كائنات الجهاز الفرعي GIT هي أنواع خاصة من كائنات GIT ، وهي تحمل معلومات SHA لالتزام معين.

    كلما فعلت git submodule update, ، سوف يملأ الجهاز الفرعي الخاص بك مع المحتوى من الالتزام. إنها تعرف مكان العثور على الالتزام بسبب المعلومات الموجودة في .gitmodules.

    الآن ، كل -b هل إضافة سطر واحد في الخاص بك .gitmodules ملف. لذا اتباع نفس المثال ، سيبدو هكذا:

    [submodule "SubmoduleTestRepo"]
        path = SubmoduleTestRepo
        url = https://github.com/jzaccone/SubmoduleTestRepo.git
        branch = master
    

    ملحوظة: يتم دعم اسم الفرع فقط في أ .gitmodules ملف ، ولكن Sha و Tag غير مدعومة! (بدلاً من ذلك ، يمكن تتبع التزام الفرع بكل وحدة نمطية وتحديثه باستخدام "git add ."، على سبيل المثال مثل git add ./SubmoduleTestRepo, ، ولا تحتاج إلى تغيير .gitmodules ملف في كل مرة)

    لا يزال كائن الجهاز الفرعي يشير إلى التزام محدد. الشيء الوحيد الذي -b الخيار يشتري لك القدرة على إضافة ملف --remote قم بإعلام التحديث الخاص بك وفقًا لإجابة Vogella:

    git submodule update --remote
    

    بدلاً من ملء محتوى الجهاز الفرعي إلى الالتزام التي أشار إليها الجهاز الفرعي ، فإنه يحل محل الالتزام بأحدث الالتزام في الفرع الرئيسي ، ثم يملأ العرض الفرعي بهذا الالتزام. يمكن القيام بذلك في خطوتين بواسطة إجابة djacobs7. نظرًا لأنك قمت الآن بتحديث الالتزام الذي يشير إليه كائن الجهاز الفرعي ، يجب عليك ارتكاب كائن الجهاز الفرعي الذي تم تغييره في مستودع GIT الخاص بك.

    git submodule add -b ليست طريقة سحرية للحفاظ على كل شيء محدثًا مع فرع. إنه ببساطة يضيف معلومات حول فرع في .gitmodules الملف ويمنحك خيار تحديث كائن الجهاز الفرعي إلى أحدث التزام بفرع محدد قبل ملءه.

(GIT 2.22 ، Q2 2019 ، قدم git submodule set-branch --branch aBranch -- <submodule_path>)

لاحظ أن إذا كان لديك موجود الجهاز الفرعي الذي ليس تتبع فرع حتى الآن, ، ومن بعد (إذا كان لديك Git 1.8.2+):

  • تأكد من أن الريبو الأصل يعرف أن الجهاز الفرعي الخاص به يتتبع الآن فرعًا:

    cd /path/to/your/parent/repo
    git config -f .gitmodules submodule.<path>.branch <branch>
    
  • تأكد

    cd path/to/your/submodule
    git checkout -b branch --track origin/branch
      # if the master branch already exist:
      git branch -u origin/master master
    

(مع "الأصل" هو اسم ريبو عن بعد المنبع تم استنساخ الجهاز الفرعي.
أ git remote -v داخل تلك الحداثة الفرعية سوف يعرضها. عادة ، هو "الأصل")

  • لا تنس تسجيل الحالة الجديدة للوحدة الفرعية الخاصة بك في ريبو والديك:

    cd /path/to/your/parent/repo
    git add path/to/your/submodule
    git commit -m "Make submodule tracking a branch"
    
  • التحديث اللاحق لهذا الجهاز الفرعي سيتعين عليه استخدام --remote اختيار:

    # update your submodule
    # --remote will also fetch and ensure that
    # the latest commit from the branch is used
    git submodule update --remote
    
    # to avoid fetching use
    git submodule update --remote --no-fetch 
    

لاحظ ذلك مع Git 2.10+ (Q3 2016) ، يمكنك استخدام "."كاسم فرع:

تم تسجيل اسم الفرع باسم submodule.<name>.branch في .gitmodules إلى عن على update --remote.
قيمة خاصة . يستخدم للإشارة إلى أن اسم الفرع في الجهاز الفرعي يجب أن يكون نفس اسم الفرع الحالي في المستودع الحالي.


إذا كنت ترغب في تحديث جميع العوامل الفرعية الخاصة بك بعد فرع:

    git submodule update --recursive --remote

لاحظ أن النتيجة ، لكل وحدة فرعية محدثة ، سوف دائما تكون دائما رأس منفصل, ، كما دان كاميرون لاحظ في إجابته.

(كلنتم ملحوظات في التعليقات ذلك ، إذا قمت بتشغيل git submodule update --remote و SHA1 الناتج هو نفسه الفرع الذي يوجد فيه الجهاز الفرعي حاليًا ، ولن يفعل أي شيء ويترك الجهاز الفرعي "على هذا الفرع" وليس في حالة رأس منفصلة.)

لضمان فحص الفرع فعليًا (ولن يعدل SHA1 من دخول خاص ويقترح: يمثل الجهاز الفرعي لإعادة الريبو الأم)

git submodule foreach -q --recursive 'branch="$(git config -f $toplevel/.gitmodules submodule.$name.branch)"; git checkout $branch'

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

لاحظ استخدام $toplevel, ، مستحسن في التعليقات بواسطة ألكساندر بوغربنياك.
$toplevel تم تقديمه في Git1.7.2 في مايو 2010: ارتكاب F030C96.

أنه يحتوي على المسار المطلق للدليل العلوي (حيث .gitmodules هو).

dtmland يضيف في التعليقات:

سيفشل البرنامج النصي foreach في الخروج من العارضات الفرعيات التي لا تتبع فرعًا.
ومع ذلك ، يمنحك هذا الأمر كلاهما:

 git submodule foreach -q --recursive 'branch="$(git config -f $toplevel/.gitmodules submodule.$name.branch)"; [ "$branch" = "" ] && git checkout master || git checkout $branch' –

نفس الأمر ولكن أسهل في القراءة:

git submodule foreach -q --recursive \
    'branch="$(git config -f $toplevel/.gitmodules submodule.$name.branch)"; \
     [ "$branch" = "" ] && \
     git checkout master || git checkout $branch' –

umläute صقل DTMLANDأمر مع نسخة مبسطة في التعليقات:

git submodule foreach -q --recursive 'git checkout $(git config -f $toplevel/.gitmodules submodule.$name.branch || echo master)'

خطوط متعددة:

git submodule foreach -q --recursive \
  'git checkout \
  $(git config -f $toplevel/.gitmodules submodule.$name.branch || echo master)'

وأضاف GIT 1.8.2 إمكانية تتبع الفروع.

# add submodule to track master branch
git submodule add -b branch_name URL_to_Git_repo optional_directory_rename

# update your submodule
git submodule update --remote 

أنظر أيضا GIT الفرعية

مثال على كيفية استخدام الجهاز الفرعي git.

  1. إنشاء مستودع جديد
  2. ثم استنساخ مستودع آخر كوحدة فرعية
  3. ثم لدينا هذه الجهاز الفرعي استخدم علامة تسمى v3.1.2
  4. ثم نلتزم.

وهذا يبدو مثل هذا قليلاً:

git init 
vi README
git add README
git commit 
git submodule add git://github.com/XXXXX/xxx.yyyy.git stm32_std_lib
git status

git submodule init
git submodule update

cd stm32_std_lib/
git reset --hard V3.1.2 
cd ..
git commit -a

git submodule status 

ربما يساعد (على الرغم من أنني أستخدم علامة وليس فرعًا)؟

في تجربتي ، سيظل تبديل الفروع في المخزون الفائق أو الخروج المستقبلي يتسبب في رؤوس منفصلة من العارض الفرعي بغض النظر عما إذا كانت الجهاز الفرعي إضافة وتتبع بشكل صحيح (IE @DJACOBS7 و johnny Z الإجابات).

وبدلاً من فحص الفرع الصحيح يدويًا يدويًا أو من خلال البرنامج النصي GIT Submodule foreach من الممكن استخدامه.

سيؤدي ذلك إلى التحقق من ملف التكوين الفرعي لخاصية الفرع والخروج من فرع تعيين.

git submodule foreach -q --recursive 'branch="$(git config -f <path>.gitmodules submodule.$name.branch)"; git checkout $branch'

تعتبر الجهاز الفرعي GIT غريبًا بعض الشيء - إنها دائمًا في وضع "Detached Head" - فهي لا تحديث لأحدث الالتزام على فرع كما قد تتوقعه.

هذا أمر منطقي عندما تفكر في الأمر. لنفترض أنني أقوم بإنشاء مستودع فو مع الجهاز الفرعي شريط. أدفع التغييرات الخاصة بي وأقول لك أن تتحقق من الالتزام A7402BE من المستودع فو.

ثم تخيل أن شخصًا ما يرتكب تغييرًا في المستودع شريط قبل أن تتمكن من صنع استنساخك.

عندما تحقق من الالتزام A7402BE من المستودع فو, ، تتوقع الحصول على نفس الرمز الذي دفعته. لهذا السبب لا يتم تحديث العارض الفرعي حتى تخبرهم أن يلتزموا بشكل صريح ثم التزام جديد.

أنا شخصياً أعتقد أن العارض الفرعي هي الجزء الأكثر إرباكًا من GIT. هناك الكثير من الأماكن التي يمكن أن تفسر العلامات الفرعية بشكل أفضل مما أستطيع. انصح برو git بقلم سكوت تشاكون.

لتبديل الفرع للحصول على وحدة فرعية (على افتراض أن لديك بالفعل الجهاز الفرعي كجزء من المستودع):

  • cd إلى جذر مستودعك الذي يحتوي على العارض الفرعي
  • فتح .gitmodules للتحرير
  • أضف السطر أدناه path = ... و url = ... هذا يقول branch = your-branch, ، لكل وحدة فرعية ؛ احفظ الملف .gitmodules.
  • ثم بدون تغيير الدليل $ git submodule update --remote

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

لدي هذا في ملف .gitConfig الخاص بي. إنها لا تزال مسودة ، لكنها أثبتت أنها مفيدة حتى الآن. يساعدني ذلك دائمًا على إعادة توحيد العارض الفرعي إلى فرعهم.

[alias]

######################
#
#Submodules aliases
#
######################


#git sm-trackbranch : places all submodules on their respective branch specified in .gitmodules
#This works if submodules are configured to track a branch, i.e if .gitmodules looks like :
#[submodule "my-submodule"]
#   path = my-submodule
#   url = git@wherever.you.like/my-submodule.git
#   branch = my-branch
sm-trackbranch = "! git submodule foreach -q --recursive 'branch=\"$(git config -f $toplevel/.gitmodules submodule.$name.branch)\"; git checkout $branch'"

#sm-pullrebase :
# - pull --rebase on the master repo
# - sm-trackbranch on every submodule
# - pull --rebase on each submodule
#
# Important note :
#- have a clean master repo and subrepos before doing this !
#- this is *not* equivalent to getting the last committed 
#  master repo + its submodules: if some submodules are tracking branches 
#  that have evolved since the last commit in the master repo,
#  they will be using those more recent commits !
#
#  (Note : On the contrary, git submodule update will stick 
#to the last committed SHA1 in the master repo)
#
sm-pullrebase = "! git pull --rebase; git submodule update; git sm-trackbranch ; git submodule foreach 'git pull --rebase' "

# git sm-diff will diff the master repo *and* its submodules
sm-diff = "! git diff && git submodule foreach 'git diff' "

#git sm-push will ask to push also submodules
sm-push = push --recurse-submodules=on-demand

#git alias : list all aliases
#useful in order to learn git syntax
alias = "!git config -l | grep alias | cut -c 7-"

نحن نستخدم الدجال لسحب وحدة معينة من مستودع GIT آخر. نحتاج إلى سحب التعليمات البرمجية بدون قاعدة التعليمات البرمجية بأكملها للمستودع المقدم - نحتاج إلى وحدة / ملف محدد للغاية من هذا المستودع الضخم ويجب تحديثه في كل مرة نقوم فيها بتشغيل التحديث.

لذلك حققناها بهذه الطريقة:

إنشاء التكوين

name: Project Name

modules:
  local/path:
    repository: https://github.com/<username>/<repo>.git
    path: repo/path
    branch: dev
  other/local/path/filename.txt:
    repository: https://github.com/<username>/<repo>.git
    hexsha: 9e3e9642cfea36f4ae216d27df100134920143b9
    path: repo/path/filename.txt

profiles:
  init:
    tasks: ['modules']

مع التكوين أعلاه ، يقوم بإنشاء دليل واحد من مستودع GitHub المقدم كما هو محدد في تكوين الوحدة الأولى ، والآخر هو سحب وإنشاء ملف من المستودع المحدد.

يحتاج المطورين الآخرون فقط إلى الجري

$ quack

ويسحب الرمز من التكوينات أعلاه.

التأثير الوحيد لاختيار فرع للوحدة الفرعية هو ذلك ، كلما مررت --remote الخيار في git submodule update سطر الأوامر ، سوف تحقق git في رأس منفصل الوضع (إذا كان الافتراضي --checkout تم اختيار السلوك) أحدث التزام بهذا المحدد التحكم عن بعد فرع.

يجب أن تكون حذراً بشكل خاص عند استخدام ميزة تتبع الفرع عن بُعد للفيروسات الفرعية GIT إذا كنت تعمل مع استنساخ ضحل من العارض الفرعي. الفرع الذي تختاره لهذا الغرض في إعدادات الجهاز الفرعي ليس الشخص الذي سيتم استنساخه خلال git submodule update --remote. إذا قمت بتمرير أيضا --depth المعلمة و أنت لا تطلب من الفرع الذي تريد استنساخه -- وفي الواقع لا يمكنك ذلك في ال git submodule update سطر الأوامر!! - ، سوف يتصرف ضمنيًا كما هو موضح في git-clone(1) وثائق ل git clone --single-branch عندما واضحة --branch المعلمة مفقودة ، وبالتالي سوف يستنسخ الفرع الأساسي فقط.

ليس من المستغرب ، بعد مرحلة الاستنساخ التي تؤديها git submodule update الأمر ، سيحاول أخيرًا الاطلاع على أحدث الالتزام بـ التحكم عن بعد الفرع الذي قمت بإعداده مسبقًا للوحدة الفرعية ، وإذا لم يكن هذا هو الأساسي ، فهو ليس جزءًا من استنساخ الضحل المحلي الخاص بك ، وبالتالي فسوف يفشل

قاتلة: تحتاج إلى مراجعة واحدة

غير قادر على العثور على الأصل الحالي/nottheprimarybranch مراجعة في مسار الجهاز الفرعي "mysubmodule"

الجهاز الفرعي git إضافة -b تطوير -اسم الفرع -اسم - https: //branch.git

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