วิธีการแปลงตัวชี้โมดูลย่อย Git กลับเป็นคอมมิตที่เก็บไว้ในที่เก็บข้อมูล


128

ฉันมีโมดูลย่อย git ใน repo คอมไพล์หลักของฉัน ตามที่ฉันเข้าใจ repo หลักจะจัดเก็บค่า SHA (ที่ใดที่หนึ่ง ... ) โดยชี้ไปที่การกระทำเฉพาะของโมดูลย่อยที่ "เชื่อมโยงกับ"

ผมไปใน submodule git checkout some_other_branchของฉันและพิมพ์ ฉันไม่รู้ว่าฉันมาจากการกระทำใด

ฉันต้องการเปลี่ยนกลับตัวชี้เพื่อให้ repo หลักและโมดูลย่อยซิงค์อีกครั้ง

สัญชาตญาณแรก (อาจจะไร้เดียงสา) ของฉันคือการพูดgit reset --hardซึ่งดูเหมือนจะใช้ได้กับทุกอย่าง ฉันแปลกใจที่มันไม่ได้ผลกับสถานการณ์นี้

ดังนั้นฉันคิดว่าฉันสามารถพิมพ์git diffบันทึก SHA ID ที่ตัวชี้โมดูลย่อยเคยมีจากนั้นมุ่งหน้าไปยังโมดูลย่อยและgit checkout [SHA ID]... แต่ต้องมีวิธีที่ง่ายกว่านี้แน่ ๆ ?

ในขณะที่ฉันยังคงเรียนรู้เกี่ยวกับ git submodules โปรดอย่าลังเลที่จะแก้ไขคำศัพท์ของฉันหากมีคำศัพท์สำหรับแนวคิดที่ฉันไม่รู้

คำตอบ:


167

คุณต้องการอัปเดตโมดูลย่อยของคุณเพื่อให้สอดคล้องกับสิ่งที่ที่เก็บพาเรนต์เชื่อว่าควรเป็น นี่คือคำสั่งอัพเดตสำหรับ:

จาก manpage โมดูลย่อย:

อัปเดตโมดูลย่อยที่ลงทะเบียนเช่นโคลนโมดูลย่อยที่ขาดหายไปและ
ชำระเงินค่าคอมมิตที่ระบุในดัชนีของไฟล์
กรุ สิ่งนี้จะทำให้โมดูลย่อย HEAD ถูกแยกออกเว้นแต่
--rebase หรือ --merge ถูกระบุหรือโมดูลย่อยที่สำคัญ $ name.update
ถูกตั้งค่าเป็นฐานใหม่หรือรวม

เรียกใช้สิ่งนี้และทุกอย่างควรจะดี:

git submodule update

4
--initอย่างใดสำหรับฉันฉันต้องการที่จะเพิ่ม ก็ไม่มี submodules (new commits)จะอยู่ในสถานะที่มี แม้ว่าโมดูลย่อยของฉันจะเริ่มต้นแล้วก็ตาม
Ambidex

@Ambidex ใช่--initตัวเลือกมีความสำคัญในทั้งหมดนี้ ฉันได้รับแจ้งให้ใส่ชื่อผู้ใช้และรหัสผ่านเนื่องจากโมดูลย่อยของฉันถูกโคลนผ่าน https ฉันเข้าไปในโฟลเดอร์ทั้งสองและตั้งค่ารีโมทให้ใช้sshโปรโตคอลสำหรับการชำระเงิน
A-Dubb

1
ไม่ทำงานถ้า submodule กระทำกัญชามีการแก้ไขและ unstaged
tribbloid

สามารถเพิ่ม --recursive เพื่อที่คุณจะได้ไม่ต้องไปที่โมดูลย่อยทั้งหมด
Gaspa79

21

หากต้องการเปลี่ยนการคอมมิตที่โมดูลย่อยชี้ไปคุณต้องชำระเงินเวอร์ชันนั้นในโมดูลย่อยจากนั้นกลับไปที่ repo ที่มีเพิ่มและยอมรับการเปลี่ยนแปลงนั้น

หรือหากคุณต้องการ submodule git submodule update --recursiveที่จะอยู่กับรุ่นจุดที่จะซื้อคืนด้านบนทำ เพิ่ม--initหากคุณเพิ่งโคลน

นอกจากนี้git submoduleหากไม่มีคำสั่งโมดูลย่อยจะแสดงการกระทำที่คุณกำลังชี้ไป จะมี - หรือ + อยู่ข้างหน้าคอมมิตหากไม่ได้ซิงค์

หากคุณดูต้นไม้ที่มีโมดูลย่อยอยู่คุณจะเห็นว่าโมดูลย่อยถูกทำเครื่องหมายเป็นส่วนcommitที่ต่างจากส่วนที่เหลือที่เป็นกลุ่มย่อยหรือต้นไม้

เพื่อดูว่าจุดคอมมิตเฉพาะใดที่เขียนถึงโมดูลย่อยคุณสามารถ:

git ls-tree <some sha1, or branch, etc> Submodule/path

จากนั้นคุณสามารถดูการกระทำหรือสิ่งอื่นใดก็ได้หากคุณต้องการโดยส่งสิ่งนั้นไปยังบันทึก ฯลฯ ( git-dirตัวเลือกในระดับคำสั่ง git ช่วยให้คุณสามารถข้ามไม่ต้องลง cd ลงไปที่โมดูลย่อย):

git --git-dir=Submodule/path log -1 $(<the above statement>)

คำสั่งด้านล่างช่วยฉันได้ (ฉันต้องการที่จะเพิกเฉยต่อการเปลี่ยนแปลงใด ๆ ในโมดูลย่อยและในโมดูลของฉันด้วย): git submodule update --init --recursive
Rajesh Goel

6

อีกกรณีหนึ่งที่ฉันเพิ่งพบคือหากมีการเปลี่ยนแปลงที่ไม่ได้จัดขั้นตอนในโมดูลย่อยที่คุณต้องการทิ้ง การอัปเดตโมดูลย่อย git จะไม่ลบการเปลี่ยนแปลงนั้นและจะไม่ git reset --hard บนไดเร็กทอรีหลัก คุณต้องไปที่ไดเร็กทอรีโมดูลย่อยและทำการรีเซ็ตคอมไพล์ - ฮาร์ด ดังนั้นหากฉันต้องการยกเลิกการเปลี่ยนแปลงที่ไม่ได้จัดขั้นตอนทั้งในโมดูลหลักและโมดูลย่อยของฉันโดยสิ้นเชิงฉันจะดำเนินการดังต่อไปนี้:

ในผู้ปกครอง:

git reset --hard

git submodule update

ในโมดูลย่อย:

git reset --hard

5

ใช้git ls-tree HEADในโฟลเดอร์ "superproject" เพื่อดูว่าโมดูลย่อยของคุณอยู่ที่ใด จากนั้นเปลี่ยนเป็นไดเร็กทอรีโมดูลย่อยและใช้git log --oneline --decorateเพื่อดูว่าสาขาใดที่คอมมิตเดิมอยู่ สุดท้ายgit checkout original-commit-branch.

การใช้ไดเร็กทอรีการทดสอบที่ฉันตั้งค่าไว้นี่คือลักษณะของคำสั่ง:

$ git --version
git version 1.7.4.1
$ git status
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   sm2 (new commits)
#
no changes added to commit (use "git add" and/or "git commit -a")
$ git ls-tree HEAD
100644 blob 76813a07ae558db274cefc6d903ec24323fdeb0d    .gitmodules
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391    main
160000 commit 7c5889497938cd5699a9234a98ee93947e52b1ed  sm1
160000 commit f68bed61cba6f94cef57554f2cf46a45a4a0d337  sm2
$ cd sm2
$ git log --oneline --decorate
5b8d48f (HEAD, foo1) foo1.1
f68bed6 (origin/master, origin/HEAD, master) Initial commit.
$ git checkout master
Switched to branch 'master'
$ cd ..
$ git status
# On branch master
nothing to commit (working directory clean)

"การ superproject" แสดง submodule SM2 ที่กระทำf68bed6แต่ SM2 5b8d48fมีหัวที่ การคอมมิตโมดูลย่อยf68bed6มีสามสาขาในนั้นซึ่งอาจใช้สำหรับการชำระเงินในไดเร็กทอรีโมดูลย่อย


ขอบคุณ DAN PERFECTO!
Alec

4

คำตอบที่นี่ไม่ได้ช่วยแก้ปัญหาเฉพาะของฉันกับโมดูลย่อยดังนั้นในกรณีที่เกิดขึ้นกับคุณเช่นกันให้ลองทำดังต่อไปนี้ ...

 git submodule foreach git reset --hard

https://kalyanchakravarthy.net/blog/git-discard-submodule-changes/


1
ซับเดียวดี!
user8162

1

ฉันต้องการที่จะเพิกเฉยต่อการเปลี่ยนแปลงใด ๆ ในโมดูลย่อยและในโมดูลของฉันด้วย

คำสั่งด้านล่างช่วยฉัน:

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