อัปเดต submodule เป็นคอมมิทล่าสุด


269

ฉันมีโครงการ A ซึ่งเป็นห้องสมุดและใช้ในโครงการ B

ทั้งสองโครงการ A และ B มีพื้นที่เก็บข้อมูลแยกต่างหากใน Github แต่ภายใน B เรามี submodule ของ A.

ฉันแก้ไขบางคลาสในไลบรารีซึ่งอยู่ใน repo A ฉันผลักไปที่ repo ระยะไกลดังนั้นไลบรารี (repo A) จึงได้รับการอัปเดต

การปรับปรุงเหล่านี้ไม่ได้สะท้อนถึง "การอ้างอิง" (submodule) the submodule หมายถึงการกระทำก่อนหน้านี้ .... ฉันควรทำอย่างไรเพื่อที่จะอัพเดท submodule บน git?

คำตอบ:


358

ป้อนไดเรกทอรี submodule:

cd projB/projA

ดึง repo จากคุณโปรเจ็กต์ A (จะไม่อัปเดตสถานะ git ของโปรเจค B):

git pull origin master

กลับไปที่ไดเรกทอรีราก & ตรวจสอบการอัปเดต:

cd ..
git status

หาก submodule อัปเดตก่อนหน้านี้มันจะแสดงดังนี้:

# Not currently on any branch.
# Changed but not updated:
#   (use "git add ..." to update what will be committed)
#   (use "git checkout -- ..." to discard changes in working directory)
#
#       modified:   projB/projA (new commits)
#

จากนั้นคอมมิชชันการอัพเดต:

git add projB/projA
git commit -m "projA submodule updated"

UPDATE

ดังที่ @paul ชี้ให้เห็นตั้งแต่ git 1.8 เราสามารถใช้

git submodule update --remote --merge

เพื่ออัปเดต submodule เป็นการกระทำระยะไกลล่าสุด มันจะสะดวกในกรณีส่วนใหญ่


35
BTW หากคุณไม่ได้เป็นเจ้าของ submodule คุณสามารถทำได้git submodule updateเมื่อมีคนอัปเดต projA คนอื่น (คุณจะได้รับรหัสยืนยันใหม่)
Kjuly

ฉันเป็นเจ้าของ repod หลัก main (proj A) แต่ฉันเป็น commitor ใน proj B.
fat

@ Kjuly หลังจากคอมมิชชันใครจะผลักมันไปยังรีโมตได้อย่างไร? มันเป็นเพียงแค่git push?
KR29

1
@ KR29 ขวาและ cmd เต็มรูปแบบเช่นgit push <remote> <branch> git push origin dev
Kjuly

2
git submodule updateใช้งานได้โดยไม่ต้องตั้งค่าสถานะเมื่อมีการดึงการคอมมิต (ใน proj B) ที่อัปเดตการอ้างอิงไปยัง submodule (s) ในคำถาม (proj A) หากต้องการอัพเดท proj B เพื่ออ้างอิงHEADสาขาการติดตามระยะไกลสำหรับ proj A คุณจะต้องทำgit submodule update --remote --mergeตามที่แสดงในคำตอบของ Paul Hatcher ด้านล่าง
Ben Burns

109

ตั้งแต่ git 1.8 คุณสามารถทำได้

git submodule update --remote --merge

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

git commit

จากนั้นจึงผลักดันการเปลี่ยนแปลงโดยที่ไม่มีสิ่งนี้ข้อมูลประจำตัว SHA-1 ที่ชี้ไปยัง submodule จะไม่ได้รับการอัปเดตดังนั้นบุคคลอื่นจะไม่สามารถมองเห็นการเปลี่ยนแปลงได้


แม้ว่าฉันจะทำgit commitคนอื่นยังไม่เห็น On branch master Your branch is up-to-date with 'origin/master'. Changes not staged for commit: modified: SubmoduleA (new commits) modified: SubmoduleB (new commits)
Max N

1
คุณได้ทำ "git push" หลังจากกระทำของคุณแล้วโปรดจำไว้ว่ากระทำการเปลี่ยนแปลงที่เก็บข้อมูลในเครื่องของคุณคุณต้องผลักมันออกจากระยะไกลเพื่อให้ทุกคนได้เห็น
Paul Hatcher

หายไปจากคำตอบนี้ (แต่ถูกบันทึกไว้ในคำตอบอื่น ๆ ด้านล่าง): submodule ที่อัปเดตจะต้องมีการจัดฉากด้วยgit addก่อนที่จะกระทำ
joshng

1
@ joshng ฉันรู้สึกว่าทุกคนที่อยู่ในจุดที่พวกเขากำลังทำงานกับ submodules จะเข้าใจว่า นี่เป็นโพสต์เดียวที่ช่วยฉันขอบคุณมาก
Husk Rekoms

38

หากคุณอัปเดต submodule และยอมรับมันคุณต้องไปที่ repo ระดับที่มีหรือสูงกว่าและเพิ่มการเปลี่ยนแปลงที่นั่น

git status

จะแสดงสิ่งที่ชอบ:

modified:
   some/path/to/your/submodule

ความจริงที่ว่า submodule ไม่สามารถซิงค์ได้ด้วย

git submodule

ผลลัพธ์จะแสดง:

+afafaffa232452362634243523 some/path/to/your/submodule

เครื่องหมายบวกแสดงว่า submodule ของคุณชี้ไปข้างหน้าว่าที่ repo ด้านบนคาดว่ามันจะชี้ไปที่

เพียงเพิ่มการเปลี่ยนแปลงนี้:

git add some/path/to/your/submodule

และกระทำมัน:

git commit -m "referenced newer version of my submodule"

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

git submodule update

ข้อมูลเพิ่มเติมเกี่ยวกับ submodules สามารถพบได้ที่นี่http://progit.org/book/ch6-6.html


หากคุณไม่เห็น a +เมื่อคุณเรียกใช้git submoduleตรวจสอบให้แน่ใจว่าคุณได้เริ่มต้นและนำเข้า submodules คำสั่งสำหรับสิ่งนั้นคือgit submodule initและgit submodule updateตามลำดับ
fureigh


2

คำตอบอื่น ๆ สองสามข้อแนะนำการผสาน / การคอมมิตภายในไดเรกทอรีของ submodule ซึ่ง IMO อาจกลายเป็นความยุ่งเหยิงเล็กน้อย

สมมติว่าชื่อเซิร์ฟเวอร์ระยะไกลoriginและเราต้องการmasterสาขาของ submodule (s) ฉันมักจะใช้:

git submodule foreach "git fetch && git reset --hard origin/master"

หมายเหตุ: นี่จะดำเนินการฮาร์ดรีเซ็ตในแต่ละ submodule - ถ้าคุณไม่อยากให้เรื่องนี้คุณสามารถเปลี่ยนไป--hard--soft


1

โครงการของฉันควรใช้ 'ล่าสุด' สำหรับ submodule ใน Mac OSX 10.11, git เวอร์ชั่น 2.7.1, ฉันไม่จำเป็นต้องไปที่ 'เข้าไปใน' โฟลเดอร์ submodule ของฉันเพื่อรวบรวมคอมมิชชัน ฉันแค่ทำตามปกติ

git pull --rebase 

ที่ระดับสูงสุดและอัปเดต submodule ของฉันอย่างถูกต้อง


0

การตอบสนองของ Andy ทำงานให้ฉันโดยการหลีกเลี่ยง $ path:

git submodule foreach "(git checkout master; git pull; cd ..; git add \$path; git commit -m 'Submodule Sync')"

น่าจะเป็นเหตุผลที่คำตอบของ @Andy Webovไม่ต้องการการหลบหนีคือเพราะพวกเขาใช้เครื่องหมายคำพูดเดี่ยวรอบ ๆ พา ธ เช่น '$path'
S0AndS0
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.