ฉันจะระบุสาขา / แท็กเมื่อเพิ่ม submodule Git ได้อย่างไร


756

วิธีการgit submodule add -bทำงานหรือไม่

หลังจากเพิ่ม submodule ด้วยสาขาเฉพาะที่เก็บโคลนใหม่ (หลังจากgit submodule update --init) จะอยู่ที่การกระทำเฉพาะไม่ใช่สาขาเอง ( git statusใน submodule แสดง "ไม่อยู่ในสาขาใด ๆ ")

ฉันไม่สามารถหาข้อมูลใด ๆ เกี่ยวกับ.gitmodulesหรือ.git/configเกี่ยวกับสาขาของ submodule หรือการกระทำที่เฉพาะเจาะจงดังนั้น Git จะหาได้อย่างไร?

นอกจากนี้ยังสามารถระบุแท็กแทนสาขาได้หรือไม่?

ฉันใช้เวอร์ชั่น 1.6.5.2


3
หากคุณมีที่มีอยู่ submodule ซึ่งไม่ติดตามสาขาเลยแต่คุณต้องการตอนนี้ก็จะติดตามสาขา ... ดูคำตอบของฉันด้านล่าง
VonC

คำตอบ:


745

หมายเหตุ: Git 1.8.2 เพิ่มความเป็นไปได้ในการติดตามสาขา ดูคำตอบบางส่วนด้านล่าง


มันสับสนเล็กน้อยที่จะคุ้นเคยกับสิ่งนี้ แต่ submodules ไม่ได้อยู่ในสาขา พวกเขาเป็นเหมือนที่คุณบอกว่าเป็นเพียงตัวชี้ไปยังการกระทำที่เฉพาะเจาะจงของพื้นที่เก็บข้อมูลของ submodule

ซึ่งหมายความว่าเมื่อมีคนอื่นตรวจสอบที่เก็บของคุณหรือดึงรหัสของคุณและทำการปรับปรุงซับไดโทลคอมไพล์ซับไดโทลนั้นจะถูกตรวจสอบกับการคอมมิทนั้น

นี่เป็นวิธีที่ดีสำหรับ submodule ที่ไม่เปลี่ยนแปลงบ่อยนักเพราะทุกคนในโครงการสามารถมี submodule ในการกระทำเดียวกันได้

หากคุณต้องการย้าย submodule ไปยังแท็กเฉพาะ:

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จริงผสานในรหัสใหม่


8
นั่นเป็นคำอธิบายที่ดีมากขอบคุณ! และแน่นอนหลังจากอ่านคำตอบของคุณฉันรู้ว่าการกระทำนั้นถูกบันทึกไว้ใน submodule (submodule / .git / HEAD)
Ivan

4
ดูเหมือนว่านี่จะใช้งานไม่ได้กับ git 1.7.4.4 อัตราผลตอบแทนcd my_submodule; git checkout [ref in submodule's repository fatal: reference is not a tree: ...มันเป็นถ้าgitจะทำงานเฉพาะในพื้นที่เก็บข้อมูลผู้ปกครอง
James A. Rosen

3
มันเป็นการดีที่จะใช้ submodules git แม้สำหรับโครงการที่มีการปรับปรุงบ่อยครั้ง เคอร์เนล linux ใช้มันและมันก็ไม่ได้แย่ขนาดนั้น

10
คือgit checkout v1.0สาขาหรือแท็กหรือไม่?
Bernhard Döbler

8
พิจารณาแท็กนามแฝงที่มนุษย์อ่านได้เพื่อกระทำการ และการคอมมิตคือชุดของสถานะเฉพาะสำหรับแต่ละไฟล์ สาขาเป็นสิ่งเดียวกันยกเว้นคุณสามารถทำการเปลี่ยนแปลงได้
deadbabykitten

656

ฉันต้องการเพิ่มคำตอบที่นี่ซึ่งเป็นเพียงกลุ่ม บริษัท ของคำตอบอื่น ๆ แต่ฉันคิดว่ามันอาจจะสมบูรณ์กว่า

คุณรู้ว่าคุณมี submodule Git เมื่อคุณมีสองสิ่งนี้

  1. คุณ.gitmodulesมีรายการดังนี้:

    [submodule "SubmoduleTestRepo"]
        path = SubmoduleTestRepo
        url = https://github.com/jzaccone/SubmoduleTestRepo.git
    
  2. คุณมีวัตถุ submodule (ชื่อ SubmoduleTestRepo ในตัวอย่างนี้) ในที่เก็บ Git ของคุณ GitHubแสดงสิ่งเหล่านี้เป็นวัตถุ "submodule" หรือทำgit submodule statusจากบรรทัดคำสั่ง Git submodule วัตถุเป็นวัตถุ 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ไฟล์ในแต่ละครั้ง)

    วัตถุ submodule ยังคงชี้ไปที่การกระทำที่เฉพาะเจาะจง สิ่งเดียวที่-bตัวเลือกซื้อคือความสามารถในการเพิ่ม--remoteตั้งค่าสถานะให้กับการอัปเดตของคุณตามคำตอบของ Vogella:

    git submodule update --remote
    

    แทนการเติมเนื้อหาของ submodule ไปยังการกระทำที่ชี้ไปที่ submodule มันแทนที่ด้วยการกระทำที่มีความมุ่งมั่นล่าสุดในสาขาหลักแล้วมันจะเติม submodule ด้วยความมุ่งมั่นที่ สามารถทำได้สองขั้นตอนโดยคำตอบ djacobs7 เนื่องจากขณะนี้คุณได้อัปเดตการยอมรับวัตถุ submodule แล้วคุณจะต้องส่งมอบวัตถุที่เปลี่ยนไปในที่เก็บ Git ของคุณ

    git submodule add -bไม่ใช่วิธีที่น่าอัศจรรย์ในการรักษาทุกสิ่งให้ทันสมัยด้วยสาขา มันเป็นเพียงการเพิ่มข้อมูลเกี่ยวกับสาขาใน.gitmodulesไฟล์และให้คุณเลือกที่จะปรับปรุงวัตถุ submodule เพื่อกระทำล่าสุดของสาขาที่ระบุก่อนที่จะเติมมัน


14
คำตอบนี้ควรมีการโหวตมากขึ้น ฉันอ่านข้อความมากมายในวันที่ผ่านมาและสิ่งนี้ก็ช่วยขจัดความสับสนทั้งหมด มาจากโลก SVN และการใช้งานภายนอก - ใคร ๆ ก็อยากจะเชื่อว่าการติดตามสาขาย่อยของ Git submodule นั้นทำให้ทุกอย่างทันสมัยจากสาขาอย่างน่าอัศจรรย์ แต่นี่ไม่เป็นความจริง! คุณต้องอัปเดตพวกเขาอย่างชัดเจน! ดังที่คุณพูดถึงคุณจะต้องส่งมอบวัตถุที่เปลี่ยนไป
dtmland

12
การติดตามสาขานี้ใช้งานกับแท็กได้หรือไม่ แทนที่จะสาขาที่ผมระบุแท็กในของฉัน.gitmodulesและหลังจากทำ$ git submodule update --init --remote TestModuleผมได้รับข้อผิดพลาดว่าและfatal: Needed a single revision Unable to find current origin/TestTag revision in submodule path 'TestModule'เมื่อทำกับสาขาจริงมันทำงาน อย่างไรก็ตามมีการระบุแท็ก.gitmodulesโดยไม่ต้องระบุการมอบหมายที่แน่นอนหรือไม่
ฮัท

5
ดูเหมือนจะใช้งานไม่ได้ ฉันอัพเดตแฮช.gitmodulesแล้วรันgit submodule updateและไม่มีอะไรเกิดขึ้น?
CMCDragonkai

2
ยังไงก็เถอะมันใช้งานไม่ได้สำหรับฉัน ด้วยรหัส Comm ของ SHA ฉันจะได้รับข้อผิดพลาดเสมอ "ไม่สามารถหาการแก้ไขในปัจจุบันได้ (ฉันตรวจสอบหมายเลขการแก้ไขของ HEAD และถูกต้องอีกครั้ง) อย่างไรก็ตามถ้าฉันใช้ master มันจะทำงานได้
infoclogged

2
การป้อน SHA ลงในแอตทริบิวต์ Branch ไม่เหมาะสำหรับฉัน การใช้งานนี้ไม่ได้รับการสนับสนุนจากเอกสาร: git-scm.com/docs/gitmodules
Jakub Bochenski

339

(Git 2.22, Q2 2019 ได้เปิดตัวแล้วgit submodule set-branch --branch aBranch -- <submodule_path>)

โปรดทราบว่าถ้าคุณมีที่มีอยู่ submodule ซึ่งไม่ได้ติดตามสาขาเลยแล้ว ( ถ้าคุณมี 1.8.2+ คอมไพล์ ):

  • ตรวจสอบให้แน่ใจ repo ผู้ปกครองรู้ว่า submodule ของมันติดตามสาขา:

    cd /path/to/your/parent/repo
    git config -f .gitmodules submodule.<path>.branch <branch>
    
  • ตรวจสอบให้แน่ใจว่า submodule ของคุณเป็นสาขาล่าสุดจริง ๆ :

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

         (ที่มีต้นกำเนิด 'เป็นชื่อของระยะไกลต้นน้ำ repo submodule ที่ได้รับการโคลนจาก. ภายใน submodule ที่จะแสดงมัน. มักจะเป็น 'ต้นกำเนิด')
git remote -v

  • อย่าลืมที่จะบันทึกสถานะใหม่ของ submodule ของคุณใน repo แม่ของคุณ:

    cd /path/to/your/parent/repo
    git add path/to/your/submodule
    git commit -m "Make submodule tracking a branch"
    
  • การปรับปรุงที่ตามมาสำหรับ submodule นั้นจะต้องใช้--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+ (ไตรมาส 3 ปี 2559) คุณสามารถใช้ ' .' เป็นชื่อสาขาได้:

ชื่อของสาขาจะถูกบันทึกเป็นsubmodule.<name>.branchในสำหรับ.gitmodules ค่าพิเศษที่ใช้ในการแสดงให้เห็นว่าชื่อของสาขาใน submodule ที่ควรจะเป็นชื่อเดียวกับชื่อสาขาในปัจจุบันที่เก็บในปัจจุบันupdate --remote
.

แต่เป็นความเห็นโดยLubosD

ด้วยgit checkoutหากชื่อสาขาที่ต้องการติดตามคือ " ." มันจะฆ่างานที่ไม่ได้รับอนุญาตของคุณ!
ใช้git switchแทน

นั่นหมายถึง Git 2.23 (สิงหาคม 2019) หรือมากกว่า

ดู " สับสนgit checkout "


หากคุณต้องการอัพเดท submodules ทั้งหมดของคุณตามสาขา:

    git submodule update --recursive --remote

โปรดทราบว่าผลที่ได้สำหรับแต่ละ submodule ปรับปรุงจะมักจะเป็นหัวเดี่ยวเป็นแดนคาเมรอนทราบในคำตอบของเขา

( Clintmบันทึกไว้ในความคิดเห็นที่ถ้าคุณเรียกใช้git submodule update --remoteและ sha1 ที่ได้นั้นเหมือนกับสาขาที่ submodule เปิดอยู่มันจะไม่ทำอะไรเลยและปล่อยให้ submodule ยังคง "อยู่ที่สาขานั้น" และไม่อยู่ในสถานะผู้นำเดี่ยว )

เพื่อให้แน่ใจว่าสาขานั้นเช็คเอาท์จริง (และที่จะไม่แก้ไข SHA1 ของรายการพิเศษที่เป็นตัวแทนของ submodule สำหรับผู้ปกครอง repo) เขาแนะนำ:

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

แต่ละ submodule จะยังคงอ้างอิง SHA1 เดียวกัน แต่ถ้าคุณทำคอมมิทใหม่คุณจะสามารถผลักดันมันได้เพราะจะมีการอ้างอิงโดยสาขาที่คุณต้องการให้ submodule ติดตาม
หลังจากนั้นกดภายใน submodule อย่าลืมกลับไปที่ repo parent เพิ่มกระทำและกด SHA1 ใหม่สำหรับ submodules ที่แก้ไขแล้ว

หมายเหตุการใช้ของ$toplevelแนะนำในการแสดงความคิดเห็นโดยอเล็กซานเด Pogrebnyak
$toplevelเป็นที่รู้จักใน git1.7.2 พฤษภาคม 2010: กระทำ f030c96

มันมีเส้นทางที่แน่นอนของไดเรกทอรีระดับบนสุด (ที่ไหน.gitmodules)

dtmlandเพิ่มในความคิดเห็น :

สคริปต์ foreach จะล้มเหลวในการชำระเงิน submodules ที่ไม่ได้ติดตามสาขา
อย่างไรก็ตามคำสั่งนี้ให้ทั้งคู่:

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

คำสั่งเดียวกัน แต่อ่านง่ายกว่า:

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

umläuteปรับแต่งคำสั่งdtmlandด้วยเวอร์ชันที่เรียบง่ายในความคิดเห็น :

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

หลายบรรทัด:

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

ก่อนที่ Git 2.26 (ไตรมาสที่ 1 ปี 2020) การดึงข้อมูลที่ได้รับการบอกให้เรียกการอัปเดตซ้ำ ๆ ใน submodules ย่อมก่อให้เกิดการส่งออกรีมอย่างหลีกเลี่ยงไม่ได้และมันก็ยากที่จะสังเกตเห็นข้อความผิดพลาด

คำสั่งที่ได้รับการสอนให้ submodules การระบุว่ามีข้อผิดพลาดในตอนท้ายของการดำเนินการ

ดูกระทำ 0222540 (16 มกราคม 2020) โดยเอมิลี่ Shaffer (nasamuffin )
(ผสานโดยJunio ​​C Hamano - gitster- in b5c71cc , 05 Feb 2020)

fetch: เน้นความล้มเหลวในระหว่างการดึงข้อมูล submodule

ลงชื่อออกโดย: Emily Shaffer

ในกรณีที่การดึงข้อมูล submodule ล้มเหลวเมื่อมี submodule จำนวนมากข้อผิดพลาดจากการดึงข้อมูล submodule ที่ล้มเหลวจะถูกฝังอยู่ภายใต้กิจกรรมบน submodule อื่น ๆ หากมีการดึงข้อมูลมากกว่าหนึ่งfetch-by-oidครั้ง โทรออกความล้มเหลวในช่วงปลายเพื่อให้ผู้ใช้ทราบว่าสิ่งที่ผิดพลาดและที่

เพราะfetch_finish()เป็นเพียงการเรียกพร้อมกันโดยrun_processes_parallel,mutexing submodules_with_errorsไม่จำเป็นต้องไปรอบ ๆ


1
คำถาม: ถ้าฉันมีโฟลเดอร์ subModule1 และต้องการที่จะติดตาม branch master คำสั่งผลลัพธ์จะมีลักษณะเช่นนี้: git config -f .gitmodules submodule.subModule1.branch master
BraveNewMath

1
foreachสคริปต์จะไม่ขึ้นอยู่กับ hardcoded <path>ถ้าคุณแทนด้วย<path> $toplevel/
Alexander Pogrebnyak

1
foreachสคริปต์จะล้มเหลวใน submodules เช็คเอาท์ที่ไม่ได้ดังต่อไปนี้สาขา อย่างไรก็ตามคำสั่งนี้ให้ทั้งคู่:git submodule foreach -q --recursive 'branch="$(git config -f $toplevel/.gitmodules submodule.$name.branch)"; [ "$branch" = "" ] && git checkout master || git checkout $branch'
dtmland

2
นี่เป็นเวอร์ชั่นที่เรียบง่ายของสคริปต์ของ @ dtmland:git submodule foreach -q --recursive 'git checkout $(git config -f $toplevel/.gitmodules submodule.$name.branch || echo master)'
umläute

1
Ohh! จริงๆแล้วสคริปต์ foreach นั้นไม่จำเป็น เรามีการดำเนินการปรับปรุง submodule กับ --merge หรือสลับ --rebase: หรือgit submodule update --remote --merge git submodule update --remote --rebaseคำสั่งเหล่านี้ทำการติดตามสาขาระยะไกล
GregTom

206

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 submodules


4
สิ่งนี้ใช้ได้กับแท็กด้วยหรือไม่
ThorSummoner

1
การเพิ่ม submodule ในแบบนั้นสะท้อนถึง.gitmodulesไฟล์อย่างไร
ยูจีน

1
ขอบคุณฉันเพิ่งใช้ข้อมูลเกี่ยวกับเพื่อช่วยฉันในการสร้างโฟลเดอร์ submodule ที่ซิงค์กับเว็บไซต์ gh-pages GitHub: ตัวอย่างเต็มรูปแบบที่github.com/o2platform/fluentnode/issues/22
Dinis Cruz

4
คุณสามารถล็อคกับแท็กด้วยgit submodule add -b tags/<sometag> <url>ซึ่งคุณสามารถเห็นเป็นเส้นbranch = tags/<sometag>ใน.gitmodules
KCD

9
@KCD เวอร์ชันใดที่คอมไพล์สามารถทำได้ด้วยแท็ก ของฉันไม่ทำงานเหรอ
CMCDragonkai

58

ตัวอย่างของวิธีใช้ Git submodules

  1. สร้างที่เก็บใหม่
  2. จากนั้นโคลนที่เก็บอื่นเป็น submodule
  3. จากนั้นเรามี submodule ที่ใช้แท็กชื่อ 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 

อาจช่วยได้ (แม้ว่าฉันจะใช้แท็กและไม่ใช่สาขา)?


4
มันเป็นพื้นคำตอบเดียวกับ djacobs7 แต่ต้องขอบคุณล่ะค่ะ :)
อีวาน

1
คุณควรจะทำการเปลี่ยนแปลงหลังจากคุณgit reset --hard V3.1.2หรือไม่? ฉันเพิ่งได้รับ "ไม่มีอะไรที่จะกระทำ" กับgit statusไดเรกทอรีหลัก
Nick Radford

1
@Ivan: คุณอธิบายได้ไหมว่ามันเหมือนกับการตอบสนองของ djacobs7 อย่างไร? เท่าที่ฉันเห็นการตอบสนองของเขาไม่ได้รวมคำสั่ง 'submodule add' แทน repo จะถูกเพิ่มโดยตรงโดยไม่มีลิงก์ไปยัง repo git ดั้งเดิมของโมดูล อย่างน้อยเมื่อฉันลองวิธีนี้ไม่มีลิงก์ใน. gitmodules
Michel Müller

คำตอบของ djacobs7 ไม่รวมถึงคำอธิบายทั้งหมดเริ่มต้นจากการเพิ่ม submodule เขาถือว่าคุณมีอยู่แล้ว
CodeMonkey

ไม่เพียงเพิ่มเนื้อหา submodule ทั้งหมดเป็นวัตถุที่ถูกติดตามใน repo หลักของคุณ
user1312695

38

จากประสบการณ์ของฉันในการสลับสาขาในซูเปอร์โปรเจ็กต์หรือการจ่ายเงินในอนาคตจะยังคงทำให้เกิดหัวหน้าส่วนย่อยของ submodules โดยไม่คำนึงถึงว่ามีการเพิ่มและติดตาม submodule อย่างเหมาะสม (เช่น @ djacobs7 และ @Johnny Z ตอบ)

และแทนที่จะตรวจสอบสาขาที่ถูกต้องด้วยตนเองหรือผ่านสคริปต์Git submodule foreachสามารถใช้ได้

นี้จะตรวจสอบไฟล์ config submodule สำหรับคุณสมบัติสาขาและชำระเงินสาขาที่ตั้งไว้

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


ดี +1 ฉันรวมคำสั่งของคุณไว้ในคำตอบแล้ว
VonC

33

Git submodules นั้นแปลกเล็กน้อย - พวกมันอยู่ในโหมด "head head" เสมอ - พวกมันไม่ได้อัปเดตการกระทำล่าสุดในสาขาอย่างที่คุณคาดไว้

สิ่งนี้ทำให้รู้สึกบางอย่างเมื่อคุณคิดถึงมัน สมมติว่าฉันจะสร้างพื้นที่เก็บข้อมูลfooกับ submodule บาร์ ฉันผลักดันการเปลี่ยนแปลงของฉันและบอกให้คุณลองใช้ a7402be จาก repository foo foo

จากนั้นลองนึกภาพว่ามีคนยอมรับการเปลี่ยนแปลงที่เก็บบาร์ก่อนที่คุณจะสร้างโคลนได้

เมื่อคุณตรวจสอบกระทำ a7402be จากที่เก็บfooคุณคาดหวังว่าจะได้รหัสที่ฉันกดไว้ นั่นเป็นสาเหตุที่ submodules ไม่ได้อัปเดตจนกว่าคุณจะบอกให้ชัดเจนและทำการคอมมิทใหม่

โดยส่วนตัวแล้วฉันคิดว่า submodules เป็นส่วนที่สับสนมากที่สุดของ Git มีสถานที่มากมายที่สามารถอธิบาย submodules ได้ดีกว่าที่ฉันสามารถทำได้ ฉันแนะนำPro Gitโดย Scott Chacon


ฉันคิดว่าถึงเวลาแล้วที่ฉันจะเริ่มอ่านหนังสือ git ขอบคุณสำหรับคำแนะนำ
Ivan

ขออภัย แต่คุณไม่ได้ชี้แจงว่าใครจะได้รับเหมือนกันกับคุณผลักไปที่ a7402be หรือรับบาร์ล่าสุดแม้จะเป็นเวอร์ชั่น foo ก็ตาม ขอบคุณ :)
mmm

6
ปัญหาคือควรมีตัวเลือกในการพูดว่า "เก็บ submodule นี้ไว้ใน Branch X" เพื่อที่ว่าหากคุณต้องการให้มันอัพเดตตัวเองโดยอัตโนมัติคุณสามารถทำให้เกิดขึ้นได้ มันจะทำให้ submodules มีประโยชน์มากขึ้นสำหรับการจัดการเช่นการติดตั้ง WordPress ที่ปลั๊กอินเป็น repos Git ทั้งหมดโดยไม่ต้องบันทึก superproject ใหม่สำหรับทุกปลั๊กอินที่อัปเดต
jerclarke

@ jeremyclark git clone git://github.com/git/git.gitและดันคุณลักษณะนั้น ... = D
Alastair

1
ส่วนที่สับสนมากที่สุดเกี่ยวกับ Git คือแม้จะใช้เวลานานกว่าทศวรรษในการพัฒนาเครื่องมือที่ช่วยให้ฉันทำงานของฉันได้สำเร็จ แต่ก็ยังมีประสบการณ์การใช้งานที่ไม่ดีและด้วยเหตุผลที่เกินกว่าฉัน เวลา.
0xC0000022L

20

ในการสลับสาขาสำหรับ submodule (สมมติว่าคุณมี submodule เป็นส่วนหนึ่งของที่เก็บ):

  • cd เพื่อรูทของที่เก็บของคุณที่มี submodules
  • เปิด.gitmodulesสำหรับการแก้ไข
  • เพิ่มบรรทัดด้านล่างpath = ...และurl = ...ระบุว่าbranch = your-branchสำหรับแต่ละ submodule; .gitmodulesไฟล์บันทึก
  • แล้วโดยไม่ต้องเปลี่ยนไดเรกทอรีทำ $ git submodule update --remote

... สิ่งนี้ควรดึงข้อมูลล่าสุดในสาขาที่ระบุสำหรับแต่ละ submodule ที่แก้ไขดังนั้น


10

ฉันมีสิ่งนี้ในไฟล์. 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-"

3

เราใช้Quackเพื่อดึงโมดูลเฉพาะจากที่เก็บ 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

และดึงรหัสจากการกำหนดค่าด้านบน


2

ลักษณะพิเศษเฉพาะของการเลือกสาขาสำหรับ submodule คือเมื่อใดก็ตามที่คุณผ่าน--remoteตัวเลือกในgit submodule updateบรรทัดคำสั่ง Git จะเช็คเอาท์ในโหมดHEAD เดี่ยว (ถ้าเลือก--checkoutพฤติกรรมเริ่มต้น) การยอมรับล่าสุดของสาขาระยะไกลที่เลือกนั้น

คุณจะต้องระมัดระวังเป็นพิเศษเมื่อใช้ฟีเจอร์การติดตามสาขาระยะไกลนี้สำหรับ submodules Git ถ้าคุณทำงานกับ clone ตื้นของ submodules สาขาที่คุณเลือกเพื่อการนี้ในการตั้งค่า submodule IS NOTgit submodule update --remoteหนึ่งที่จะโคลนในช่วง ถ้าคุณผ่าน--depthพารามิเตอร์ด้วยและคุณไม่ได้สั่งให้ Git เกี่ยวกับสาขาที่คุณต้องการโคลน - และจริงๆแล้วคุณไม่สามารถอยู่ในgit submodule updateบรรทัดคำสั่งได้ !! - มันโดยปริยายจะทำตัวเหมือนที่อธิบายไว้ในgit-clone(1)เอกสารgit clone --single-branchเมื่อชัดเจน--branchพารามิเตอร์จะหายไปและดังนั้นมันจะโคลนสาขาหลักเท่านั้น

ด้วยความประหลาดใจหลังจากgit submodule updateคำสั่งโคลนดำเนินการโดยคำสั่งในที่สุดก็จะพยายามตรวจสอบการกระทำล่าสุดสำหรับสาขาระยะไกลที่คุณตั้งค่าไว้สำหรับ submodule ก่อนหน้านี้และหากนี่ไม่ใช่หลักแรกมันไม่ได้เป็นส่วนหนึ่งของ โคลนน้ำตื้นในพื้นที่ของคุณและดังนั้นจึงจะล้มเหลวด้วย

ร้ายแรง: ต้องการการแก้ไขเพียงครั้งเดียว

ไม่พบแหล่งที่มาปัจจุบัน / การแก้ไขNotThePrimaryBranchในเส้นทาง submodule 'mySubmodule'


วิธีแก้ไขข้อผิดพลาด - ต้องมีการแก้ไขครั้งเดียว?
NidhinSPradeep

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.