Git จะไม่เริ่ม / ซิงค์ / อัปเดตโมดูลย่อยใหม่


113

นี่คือส่วนหนึ่งของเนื้อหาใน.gitmodulesไฟล์ของฉัน:

[submodule "src/static_management"]
        path = src/static_management
        url = git://github.com/eykd/django-static-management.git
[submodule "external/pyfacebook"]
        path = external/pyfacebook
        url = http://github.com/sciyoshi/pyfacebook.git

อย่างไรก็ตาม.git/configมีเพียงรายการแรกเท่านั้น:

[submodule "src/static_management"]
        url = git://github.com/eykd/django-static-management.git

โมดูลย่อยที่สอง ( external/pyfacebook) ถูกเพิ่มโดยนักพัฒนารายอื่นในสาขาคุณลักษณะ ตอนนี้ฉันได้รับช่วงการพัฒนาและได้ตรวจสอบสาขาคุณลักษณะแล้ว อย่างไรก็ตาม Git จะไม่ดึงโมดูลย่อยมาให้ฉัน ฉันพยายามแล้ว:

  • git submodule init
  • git submodule update
  • git submodule update --init
  • git submodule sync
  • การถอดคำจำกัดความ submodule ทั้งหมดจากการทำงาน.git/config git submodule initโดยจะคัดลอกเฉพาะโมดูลย่อยที่มีอยู่ก่อนหน้านี้และละเว้นโมดูลใหม่
  • การป้อนคำจำกัดความ submodule ใหม่ในตนเองและทำงาน.git/config git submodule updateเฉพาะโมดูลย่อยที่มีอยู่ก่อนหน้านี้เท่านั้นที่ต้องอัปเดต

ในชุดค่าผสมต่างๆ แต่คอมไพล์จะไม่อัปเดต.git/configตามเนื้อหาใหม่ของ.gitmodulesและจะไม่สร้างexternal/pyfacebookโฟลเดอร์และดึงเนื้อหาของโมดูลย่อย

ฉันขาดอะไรไป? การแทรกแซงด้วยตนเอง (การเพิ่มรายการโมดูลย่อยด้วยมือ.git/config) จำเป็นอย่างแท้จริงหรือไม่และเพราะเหตุใด

แก้ไข:การแทรกแซงด้วยตนเองไม่ทำงาน การเพิ่มรายการโมดูลย่อยใหม่ด้วยตนเองเพื่อ.git/configไม่ทำสิ่งใดสิ่งหนึ่ง โมดูลย่อยใหม่จะถูกละเว้น


1
กำลังรัน 1.7.7.1 และมีปัญหาเดียวกัน: "git submodule sync" ไม่อัปเดต. git / config หลังจากเปลี่ยนเป็น. gitmodules
James Pritts

2
บทความนี้มีประโยชน์: chrisjean.com/git-submodules-adding-using-removing-and-updating
IgorGanapolsky

คำตอบ:


92

ฉันมีปัญหาเดียวกันนี้ - ปรากฎว่ามีการคอมมิตไฟล์. gitmodules แต่การคอมมิตโมดูลย่อยจริง (เช่นบันทึก ID การคอมมิตของโมดูลย่อย) ไม่ได้

การเพิ่มด้วยตนเองดูเหมือนจะทำเคล็ดลับ - เช่น:

git submodule add http://github.com/sciyoshi/pyfacebook.git external/pyfacebook

(แม้ว่าจะไม่ได้ลบอะไรออกจาก. git / config หรือ. gitmodules ก็ตาม)

จากนั้นยืนยันเพื่อบันทึก ID อย่างถูกต้อง

การเพิ่มความคิดเห็นเพิ่มเติมในคำตอบที่ใช้งานได้นี้: หากการอัปเดตโมดูลย่อยของ git submodule หรือ git ใช้ไม่ได้ตามที่อธิบายไว้ข้างต้น git submodule add url ควรทำเคล็ดลับ เราสามารถตรวจสอบสิ่งนี้ได้โดย

 git config --list

และควรได้รับรายการของโมดูลย่อยที่คุณต้องการดึงจากผลลัพธ์ของคำสั่ง git config --list หากมีรายการของโมดูลย่อยของคุณในผลการกำหนดค่าตอนนี้การอัปเดตโมดูลย่อย git ตามปกติ --init ควรดึงโมดูลย่อยของคุณ ในการทดสอบขั้นตอนนี้คุณสามารถเปลี่ยนชื่อโมดูลย่อยด้วยตนเองจากนั้นอัปเดตโมดูลย่อย

 mv yourmodulename yourmodulename-temp
 git submodule update --init

หากต้องการทราบว่าคุณมีการเปลี่ยนแปลงภายในโมดูลย่อยหรือไม่สามารถดูได้ผ่านสถานะ git -u (หากคุณต้องการดูการเปลี่ยนแปลงในโมดูลย่อย) หรือสถานะ git --ignore-submodules (หากคุณไม่ต้องการเห็นการเปลี่ยนแปลงใน โมดูลย่อย)


มีexternal/pyfacebookไว้เพื่ออะไร?
IgorGanapolsky

2
@IgorGanapolsky นั่นคือเส้นทางปลายทางสำหรับโมดูลย่อยของคุณ
yuhua

สิ่งนี้ช่วยฉันได้ขอบคุณมาก! ฉันสามารถเพิ่มได้ว่าถ้าเส้นทางปลายทางมีอยู่แล้ว (ซึ่งมันทำให้ฉันเป็นผลมาจากการลองใช้คำสั่งอื่น ๆ ) ข้อความต่อไปนี้ทำให้เกิดความสับสน:'your/local/path' already exists and is not a valid git repo
Michael Ambrus

1
หนึ่งซับสำหรับการอ่านรายการใน "git config git config --list | grep submodule | sed -e "s/submodule\.//" -e "s/\(.*\)\.url=\(.*\)/git submodule add --force \2 \1/" | bash
--list

64

git เวอร์ชัน 2.7.4 คำสั่งนี้อัพเดตโค้ดโลคัล git submodule update --init --force --remote


21
ไม่ทำอะไรให้ฉัน.
Carlo Wood

1
เกี่ยวกับ git-submodule [เอกสารประกอบ) ( git-scm.com/docs/git-submodule#git-submodule---remote ) คำสั่งดังกล่าวควรอัปเดตสาขาภายในของโมดูลย่อย
palik

1
@palik คุณร็อค!
Denis Trofimov

1
คุณสามารถอัปเดตแต่ละโมดูลด้วยgit submodule update --init --force --remote <module-name>ไฟล์.
Adam Faryna

15

มีปัญหาเดียวกันเมื่อคอมไพล์ละเว้นinitและupdateสั่งและไม่ทำอะไรเลย

วิธีแก้ไข

  1. โฟลเดอร์ subodule ของคุณควรถูกผูกมัดใน git repo
  2. ไม่ควรอยู่ใน. gitignore

หากตรงตามข้อกำหนดก็จะใช้ได้ มิฉะนั้นคำสั่งทั้งหมดจะดำเนินการโดยไม่มีข้อความและผลลัพธ์ใด ๆ

หากคุณทำทุกอย่างแล้ว แต่ยังไม่ได้ผล:

  1. เพิ่มโมดูลย่อยด้วยตนเองเช่น git submodule add git@... path/to
  2. git submodule init
  3. git submodule update
  4. คอมมิตและพุชไฟล์ทั้งหมด - .gitmodulesและโฟลเดอร์โมดูลของคุณ (โปรดทราบว่าเนื้อหาของโฟลเดอร์จะไม่คอมมิต)
  5. วาง git repo ในพื้นที่ของคุณ
  6. โคลนใหม่
  7. ตรวจสอบให้แน่ใจว่า.git/configยังไม่มีโมดูลย่อยใด ๆ
  8. ตอนนี้git submodule init- และคุณจะเห็นข้อความที่ลงทะเบียนโมดูล
  9. git submodule update - จะดึงโมดูล
  10. ตอนนี้ดู.git/configและคุณจะพบโมดูลย่อยที่ลงทะเบียนแล้ว

1
ฉันเชื่อว่าเส้นทางไปยังโมดูลย่อยสามารถอยู่ใน. gitignore อย่างน้อยฉันก็ทำได้โดยทำตามคำตอบจาก @DaveJamesMiller ไม่มีอะไรอื่นที่ใช้ได้ผลสำหรับฉัน
gebbissimo

7

ดูเหมือนจะมีความสับสนมากมายในคำตอบที่นี่ (เช่นกัน)

git submodule initจะไม่ได้ตั้งใจที่จะสร้างได้อย่างน่าอัศจรรย์สิ่งที่อยู่ใน .git / config (จาก .gitmodules) มีจุดประสงค์เพื่อตั้งค่าบางสิ่งในไดเร็กทอรีย่อยที่ว่างเปล่าทั้งหมดหลังจากการโคลนโปรเจ็กต์หลักหรือดึงคอมมิตที่เพิ่มโมดูลย่อยที่ไม่มีอยู่ก่อนหน้านี้

กล่าวอีกนัยหนึ่งคุณติดตามgit cloneโครงการที่มีโมดูลย่อย (ซึ่งคุณจะรู้ได้จากข้อเท็จจริงที่ว่าโคลนตรวจสอบไฟล์. gitmodules) โดยไฟล์git submodule update --init --recursive.

คุณไม่ได้ติดตามgit submodule add ...ด้วยgit submodule init(หรือgit submodule update --init) ซึ่งไม่ควรได้ผล ในความเป็นจริงการเพิ่มจะอัปเดต. git / config ที่เหมาะสมอยู่แล้วหากสิ่งต่างๆทำงานได้ดี

แก้ไข

หากผู้อื่นเพิ่มโมดูลย่อย git ที่ไม่มีอยู่ก่อนหน้านี้และคุณทำการคอมgit pullมิตนั้นไดเร็กทอรีของโมดูลย่อยนั้นจะว่างเปล่าทั้งหมด (เมื่อคุณเรียกใช้git submodule statusงานแฮชของโมดูลย่อยใหม่ควรมองเห็นได้ แต่จะมี-ด้านหน้า ) ในกรณีนี้คุณต้องติดตามgit pullด้วยgit submodule update --init(บวก--recursiveเมื่อเป็นโมดูลย่อยภายในโมดูลย่อย) เพื่อให้ได้รับการตรวจสอบโมดูลย่อยใหม่ที่ไม่มีอยู่ก่อนหน้านี้ เช่นเดียวกับหลังจากการโคลนเริ่มต้นของโครงการที่มีโมดูลย่อย (ซึ่งเห็นได้ชัดว่าคุณไม่มีโมดูลย่อยเหล่านั้นมาก่อน)


1
เป็นสิ่งที่น่าสนใจเพราะgit help submoduleพูดถึงเรื่องนี้ init: "init: เริ่มต้นโมดูลย่อยที่บันทึกในดัชนี (ซึ่งถูกเพิ่มและกำหนดไว้ที่อื่น) โดยคัดลอกชื่อโมดูลย่อยและ URL จาก. gitmodules เป็น. git / config" ดังนั้นจึงแน่ใจว่าเสียงเหมือนมันควรจะทำสิ่งที่คุณบอกว่ามันไม่ได้ทำ ... ? ถึงเวลาอัปเดตเอกสารคอมไพล์แล้วหรือยัง?
Brad

@brad ฉันไม่คิดว่าฉันพูดแบบนั้น - แต่ฉันได้เพิ่มคำชี้แจงสำหรับกรณีเฉพาะนั้น ขอบคุณ.
Carlo Wood

@CarloWood มีความคิดว่าทำไมผู้เขียน git submodules จึงตัดสินใจว่า--initควรจะต้องรับโมดูลย่อยใหม่ (แทนที่จะคว้าโดยอัตโนมัติupdate)? ดูเหมือนว่าการอัปเดตที่เก็บของคุณควรคว้าทุกสิ่งที่จำเป็นเว้นแต่ว่าจะทำลายข้อมูล ด้วยการ--initบังคับให้คุณทราบว่าโมดูลย่อยใหม่อาจถูกสร้างขึ้นหรือเพียงแค่ออก--initทุกครั้งในกรณีนี้อีกครั้งดูเหมือนว่าควรเปิดใช้งานตามค่าเริ่มต้น
Catskul

@Catskul เห็นได้ชัดว่าฉันไม่รู้ว่าทำไมผู้เขียน git submodules จึงตัดสินใจอะไร แต่ฉันเดาว่า "การอัปเดต" สงวนไว้สำหรับอัปเดตบางสิ่งที่มีอยู่แล้วและ "init" ใช้เพื่อสร้างสิ่งใหม่ (ในเครื่อง) ใหม่ ภายใต้ฝากระโปรงทั้งสองอาจแตกต่างกันมากพอที่จะรับประกันคำสั่งที่แตกต่างกัน
Carlo Wood

6

ฉันมีปัญหาเดียวกัน แต่ไม่มีวิธีแก้ไขใด ๆ ข้างต้นช่วยได้ รายการใน. gitmodules และใน. git / config ถูกต้อง แต่คำสั่งgit submodules update --init --recursiveไม่ทำอะไรเลย ฉันยังลบไดเร็กทอรีโมดูลย่อยและรันgit submodules update --init --recursiveและรับไดเร็กทอรีโมดูลย่อยกลับมา แต่มีคอมมิตเหมือนเดิมทุกประการ

ฉันพบคำตอบในหน้านี้ คำสั่งคือ:git submodule update --remote


2
นี่เป็นวิธีแก้ปัญหาที่ถูกต้องสำหรับฉันด้วย ฉันวิ่งgit submodule updateแทนgit submodule update --remote.
Andrew Medlin

5

การเรียงลำดับของน่าอัศจรรย์ แต่วันนี้ฉันวิ่งgit submodule initตามมาด้วย git submodule syncตามมาด้วยgit submodule updateและมันเริ่มดึง submodules ของฉัน ... Magic? บางที! นี่เป็นหนึ่งในประสบการณ์ที่น่ารำคาญที่สุดกับ Git ...

เกานั่นแหละ git submodule update --init --recursiveที่จริงผมได้รับมันทำงานโดยการทำ หวังว่านี่จะช่วยได้

PS: ตรวจสอบให้แน่ใจว่าคุณอยู่ในไดเร็กทอรี root git ไม่ใช่โมดูลย่อย


7
ไม่สิ่งนี้ไม่ได้ทำอะไรเลยสำหรับฉัน
IgorGanapolsky

@IgorGanapolsky ฉันแก้ไขคำตอบข้างต้นด้วยสิ่งที่เหมาะกับฉัน แจ้งให้เราทราบหากได้ผล!
Levi Figueira

ฉันลองใช้คำสั่งใหม่ของคุณแล้ว แต่ก็ไม่ได้ทำอะไรเลย
IgorGanapolsky

5

คิดว่าตนเองตั้งค่า.gitmodulesเป็นพอเป็นผิด

ท้องถิ่นของฉันในgit version 2.22.0ขณะที่เขียนนี้

ดังนั้นผมจึงมาถึงหัวข้อนี้สงสัยว่าทำไมไม่ได้git submodule initทำงาน ฉันตั้งค่า.gitmodulesไฟล์และดำเนินการgit submodule init...

สำคัญ

  1. git submodule add company/project.git includes/projectถูกต้อง (เมื่อมีการเพิ่มโมดูลสำหรับครั้งแรก) นี้จะ:

    • เพิ่ม config ไปที่ .git/config
    • อัปเดต.gitmodulesไฟล์
    • ติดตามตำแหน่งโมดูลย่อย ( includes/projectในตัวอย่างนี้)
  2. คุณต้องแล้วgit commitหลังจากที่คุณได้เพิ่ม submodule นี้จะกระทำ.gitmodulesและสถานที่ตั้ง submodule ติดตาม

เมื่อโปรเจ็กต์ถูกโคลนอีกครั้งโปรเจ็กต์จะมี.gitmodulesไดเร็กทอรีโมดูลย่อยและว่างเปล่า (เช่นincludes/projectในตัวอย่างนี้) ณ จุดนี้.git/configยังไม่มีการกำหนดค่าโมดูลย่อยจนกว่าgit submodule initจะมีการรันและจำไว้ว่าสิ่งนี้ใช้ได้ผลเพราะ.gitmodulesAND includes/projectถูกติดตามใน repo หลักของคอมไพล์

สำหรับการอ้างอิงโปรดดู:


4

ตามคำตอบของ Dave James Miller ฉันสามารถยืนยันได้ว่ามันได้ผลสำหรับฉัน สิ่งสำคัญที่นี่คือการคอมมิตโปรเจ็กต์ย่อยคอมมิต ID เพียงเพื่อให้รายการใน. gitmodules นั้นไม่เพียงพอ

นี่คือการกระทำที่เหมาะสม:

https://github.com/dirkaholic/vagrant-php-dev-box/commit/d5f4c40bdbd80eefbb5ac6029823733f591435ae


3

ผมมีปัญหาเหมือนกัน.

.gitmodulesมี submodule แต่หลังจากที่คำสั่งมันไม่ได้อยู่ในgit submodule init.git/config

ปรากฎว่านักพัฒนาที่เพิ่มโมดูลย่อยได้เพิ่มไดเร็กทอรีโมดูลย่อยลงใน.gitignoreไฟล์ด้วย ไม่ได้ผล


2

เช่นเดียวกับคุณฉันพบว่าการซิงค์โมดูลย่อย git ไม่ได้ทำในสิ่งที่คุณคาดหวัง หลังจากทำการ Explicit git submodule addอีกครั้งเท่านั้นจึงจะมีการเปลี่ยนแปลง URL ของโมดูลย่อย

ดังนั้นฉันจึงใส่สคริปต์นี้ใน~/bin/git-submodule-sync.rb:

https://gist.github.com/frimik/5125436

และฉันยังใช้ตรรกะเดียวกันกับสคริปต์ปรับใช้ git หลังรับสองสามตัว

สิ่งที่ฉันต้องทำตอนนี้คือแก้ไข.gitmodulesจากนั้นเรียกใช้สคริปต์นี้และในที่สุดมันก็ใช้งานได้อย่างที่ฉันคิดgit submodule syncไว้


สิ่งนี้ดูเหมือนจะเกิดขึ้นเฉพาะในบาง repos ... อาจเป็นเพราะข้อผิดพลาดบางอย่างใน Git มันไม่ได้เกิดขึ้นกับฉันในที่เก็บข้อมูลที่สร้างขึ้นใหม่มาเป็นเวลานานแล้ว แต่เมื่อย้อนกลับไปมันเคยเกิดขึ้นตลอดเวลาในบาง repos ...
fridh

2

วันนี้ฉันมีปัญหาเดียวกันและพบว่าเพราะฉันพิมพ์git submodule initแล้วฉันมีบรรทัดเหล่านั้นใน.git/config:

[submodule]
   active = .

ฉันลบสิ่งนั้นและพิมพ์:

git submodule update --init --remote

และทุกอย่างก็กลับมาเป็นปกติโมดูลย่อยของฉันได้รับการอัปเดตในไดเรกทอรีย่อยตามปกติ


2

ปัญหาสำหรับฉันคือนักพัฒนาก่อนหน้าของ repo ได้กำหนดให้submodules/thingโฟลเดอร์เป็นเพียงโฟลเดอร์ปกติซึ่งหมายความว่าเมื่อฉันพยายามเรียกใช้git submodule add ...มันจะล้มเหลวด้วย:'submodules/thing' already exists in the indexแต่การพยายามอัปเดตโมดูลย่อยก็จะล้มเหลวเช่นกันเนื่องจากเห็นว่าเส้นทางไม่ได้ มีโมดูลย่อย

ในการแก้ไขฉันต้องลบsubmodules/thingโฟลเดอร์ทำการลบจากนั้นเรียกใช้git submodule addคำสั่งเพื่อเพิ่มกลับอย่างถูกต้อง:

git submodule add --force --name thing https://github.com/person/thing.git submodules/thing

1

เมื่อฉันเห็นสิ่งนี้ในวันนี้นักพัฒนาได้ย้ายส่วนหนึ่งของทรีไปยังไดเร็กทอรีย่อยใหม่และดูเหมือนว่าไคลเอนต์ git ของเขาไม่ได้บันทึกกฎ Subproject ที่อัปเดตแล้วในทรี แต่เป็นเพียงแค่ nuked โดยปล่อยให้การ.gitmodulesอ้างถึงทั้งสองค้าง สถานที่และโครงการย่อยที่ไม่มีอยู่ในโครงสร้างปัจจุบันอีกต่อไป

การเพิ่มโมดูลย่อยกลับเข้าไปและเปรียบเทียบรูปแบบการคอมมิตของโมดูลย่อยกับโมดูลที่พบในgit show $breaking_commit_sha(ค้นหาบรรทัดที่ตรงกับ regexp ^-Subproject) เพื่อปรับเปลี่ยนตามความจำเป็น


1

การลบ dir โมดูลย่อยและเนื้อหา (โฟลเดอร์ "ภายนอก / pyfacebook") หากมีอยู่ก่อนgit submodule add ...อาจแก้ปัญหาได้


1
นี่คือปัญหาสำหรับฉัน มีคนกำหนดให้โฟลเดอร์ "โมดูลย่อย" เป็นเพียงโฟลเดอร์ธรรมดาซึ่งหมายความว่าเมื่อฉันพยายามเรียกใช้ "git submodule add ... " จะล้มเหลวเนื่องจาก: "" vendor / mobx-state-tree "มีอยู่แล้วในดัชนี" แต่การพยายามอัปเดตโมดูลย่อยก็จะล้มเหลวเช่นกันเนื่องจากเห็นว่าพา ธ ไม่มีโมดูลย่อย) ในการแก้ไขฉันต้องลบโฟลเดอร์ทำการลบแล้วเรียกใช้คำสั่ง git add เพื่อเพิ่มกลับอย่างถูกต้อง
Venryx

1

ฉันมีปัญหาคล้ายกันกับโมดูลย่อย มันไม่ต้องการที่จะโคลน / ดึง / ปรับปรุง / อะไรก็ตาม

เมื่อพยายามเพิ่มโมดูลย่อยอีกครั้งโดยใช้git submodule add git@my-repo.git destinationฉันได้ผลลัพธ์ต่อไปนี้:

A git directory for 'destination' is found locally with remote(s):
  origin        git@my-repo.git
If you want to reuse this local git directory instead of cloning again from
  git@my-repo.git
use the '--force' option. If the local git directory is not the correct repo
or you are unsure what this means choose another name with the '--name' option.

ดังนั้นฉันจึงพยายามบังคับใช้คำสั่ง add :
git submodule add --force git@my-repo.git destination

นั่นใช้ได้ผลในกรณีของฉัน


1

สำหรับเร็กคอร์ด:
ฉันสร้างปัญหาเดียวกันโดยการเพิ่มที่เก็บว่างเป็นโมดูลย่อย ในกรณีนี้ไม่มีแฮชอ้างอิงสำหรับโมดูลย่อยซึ่งนำไปสู่ข้อผิดพลาดที่อธิบายโดยผู้โพสต์ต้นฉบับ

การบังคับให้เพิ่มที่เก็บหลังจากที่ยืนยันแล้วจะสามารถแก้ไขปัญหาได้ (เช่นเดียวกับในโพสต์ Arvids)
git submodule add --force git@my-repo.git destination


0
  • ลบโมดูลย่อยออกจากไฟล์ .git/config
  • วิ่ง git submodule initคำสั่ง
  • ไปที่ไดเร็กทอรีโมดูลย่อยของคุณและเรียกใช้ git pull origin master

ตอนนี้ควรใช้งานได้แล้ว


0

เพียงแค่แบ่งปันสิ่งที่ได้ผลสำหรับฉัน:

git clone --recurse-submodules <repository path>

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


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