ฉันจะจัดการความขัดแย้งกับโมดูลย่อย git ได้อย่างไร


128

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

สำหรับคำถามนี้ช่วยบอก superproject ของฉันเรียกว่าsuperyและ submodule subbyที่เรียกว่า (จากนั้นเป็นการลดความซับซ้อนของสิ่งที่ฉันกำลังพยายามทำ ... ฉันไม่ได้ใช้กิ่งก้านสำหรับเวอร์ชันจริงๆ แต่ฉันคิดว่ามันจะง่ายที่สุดในการจัดวางเป็นคำถาม)

สาขาหลักของฉันsuperyมีแท็กv1.0ของโครงการ git ที่subbyอ้างถึงเป็นโมดูลย่อย สาขาของsuperyเรียกone.oneและเปลี่ยนการอ้างอิงของ submodule ที่จะชี้ไปที่แท็กของv1.1subby

ฉันสามารถทำงานในแต่ละสาขาเหล่านี้ได้โดยไม่มีข้อติดขัด แต่ถ้าฉันพยายามอัปเดตone.oneสาขาด้วยการเปลี่ยนแปลงจากmasterสาขาฉันได้รับความขัดแย้งบางอย่างและฉันไม่สามารถแก้ไขได้อย่างไร

โดยทั่วไปหลังจากทำงานgit pull . masterในsubbyสาขาไประยะหนึ่งดูเหมือนว่าจะสร้างโมดูลย่อยเพิ่มเติม

ก่อนที่จะดึง / รวมฉันได้รับคำตอบที่ต้องการgit submoduleจากone.oneสาขา:

$ git checkout master
$ git submodule
qw3rty...321e subby (v1.0)
$ git checkout one.one
$ git submodule
asdfgh...456d subby (v1.1)

แต่หลังจากดึงมันจะเพิ่มโมดูลย่อยเพิ่มเติมเมื่อฉันเรียกใช้git submodule:

$ git pull . master
Auto-merged schema
CONFLICT (submodule): Merge conflict in subby - needs qu3rty...321e
Automatic merge failed; fix conflicts and then commit the results.

$ git submodule
qw3rty...321e subby (v1.0)
asdfgh...456d subby (v1.1)
zxcvbn...7890 subby (v1.1~1)

ฉันจะลบ / ละเว้นการอ้างอิงโมดูลย่อยที่ไม่ต้องการและยอมรับข้อขัดแย้งและการเปลี่ยนแปลงของฉันได้อย่างไร หรือมีพารามิเตอร์ที่ฉันสามารถใช้กับต้นฉบับของฉันgit pullที่จะเพิกเฉยต่อโมดูลย่อยของฉันได้หรือไม่

คำตอบ:


23

ฉันไม่เห็นข้อผิดพลาดที่แน่นอนมาก่อน แต่ฉันเดาเกี่ยวกับปัญหาที่คุณกำลังพบ ดูเหมือนว่าเพราะmasterและone.oneสาขาsuperyประกอบด้วย refs แตกต่างกันสำหรับsubbysubmodule เมื่อคุณผสานการเปลี่ยนแปลงจากmasterคอมไพล์ไม่ทราบว่าโทษ - v1.0หรือv1.1- ควรจะเก็บไว้และติดตามโดยสาขาของone.onesupery

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

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


1
ขอขอบคุณที่ให้ความกระจ่างเกี่ยวกับคำถามนี้ นั่นเป็นเหตุผลสำหรับฉันในตอนนี้และคำสั่งรีเซ็ตทำงานได้อย่างสมบูรณ์แบบสำหรับสถานการณ์ของฉันด้านบน แต่คำสั่งใดที่จะยอมรับการอ้างอิงโมดูลย่อยจากสาขาหลักและทิ้งการอ้างอิงไปยังโมดูลย่อยของสาขาปัจจุบัน ฉันรู้วิธีจัดการกับความขัดแย้งตามปกติ แต่หลังจากสามวันของการกำจัดสิ่งสกปรกบนเว็บฉันไม่พบตัวอย่างโค้ดอื่นนอกจาก rm -r และฉันเริ่มคิดว่ามีเหตุผลสำหรับตัวอย่างที่ไม่มีอยู่ โมดูลย่อยนั้นแยกออกจาก superproject ที่คุณต้องจัดการทุกการเปลี่ยนแปลง
Tyler

26
ในที่สุด! คำตอบ! ผมมีadded by us: ../Mono.Cecilในgit statusแต่git addและgit rmล้มเหลวด้วยMono.Cecil: needs merge, pathspec 'Mono.Cecil/' did not match any filesเพราะมันเป็นเพียงแค่โฟลเดอร์ที่ว่างเปล่าและคอมไพล์เท่านั้นจริงๆจัดการไฟล์ git checkoutให้ฉันMono.Cecil: needs merge, error: you need to resolve your current index first, git submodule updateให้Skipping unmerged submodule Mono.Cecilและgit checkout master Mono.Cecilคงที่ในที่สุดมันก็ ปัญหาพื้นฐาน: git statusข้อเสนอแนะไม่ถูกต้องดังนั้นเลือกสาขาและถ่ายสำเนาของโฟลเดอร์ด้วยcheckout!
IBBoard

6
@ คำสั่ง IBBoard ช่วยฉันด้วยสถานการณ์เช่นนี้ - ฉันพยายามgit checkout --ours SUBMODและgit add SUBMODและคนอื่น ๆ แต่ในที่สุดก็ทำgit checkout master SUBMODคงความขัดแย้ง ความคิดเห็นนี้น่าจะเป็นคำตอบไม่ใช่ความคิดเห็น ... :)
Colin D Bennett

90

มันไม่ได้จัดการความขัดแย้งทางเทคนิคกับโมดูลย่อย (เช่น: เก็บสิ่งนี้ไว้ แต่ไม่ใช่อย่างนั้น) แต่ฉันพบวิธีที่จะทำงานต่อไป ... และสิ่งที่ฉันต้องทำคือใส่ใจกับgit statusผลลัพธ์ของฉันและรีเซ็ตโมดูลย่อย:

git reset HEAD subby
git commit

นั่นจะเป็นการรีเซ็ตโมดูลย่อยเป็น pre-pull คอมมิต ซึ่งในกรณีนี้เป็นสิ่งที่ฉันต้องการ และในกรณีอื่น ๆ ที่ฉันต้องการการเปลี่ยนแปลงที่ใช้กับโมดูลย่อยฉันจะจัดการสิ่งเหล่านั้นด้วยเวิร์กโฟลว์โมดูลย่อยมาตรฐาน (หลักเช็คเอาต์ดึงแท็กที่ต้องการลง ฯลฯ )


สำหรับฉันสิ่งนี้ดูเหมือนจะเปลี่ยนสถานะของโมดูลที่ขัดแย้งกันจาก "ทั้งคู่ที่แก้ไข" เป็น "ลบแล้ว"
Matt Zukowski

4
คุณอาจต้องการเก็บโมดูลย่อยของสาขาที่ผสานไว้แทน: git reset <merged-branch> subby
Edward Anderson

1
ได้ผลสำหรับฉันตามที่กำหนดไว้ในคำตอบ .. git reset HEAD path / to / submodule / dir
estoy

56

ฉันต่อสู้เล็กน้อยกับคำตอบกับคำถามนี้และไม่ได้มีโชคดีมากที่มีคำตอบในการโพสต์ SO ที่คล้ายกันอย่างใดอย่างหนึ่ง ดังนั้นนี่คือสิ่งที่ได้ผลสำหรับฉัน - โดยจำไว้ว่าในกรณีของฉันโมดูลย่อยได้รับการดูแลโดยทีมอื่นดังนั้นความขัดแย้งจึงมาจากเวอร์ชันย่อยที่แตกต่างกันในต้นแบบและสาขาในพื้นที่ของฉันในโครงการที่ฉันกำลังดำเนินการ:

  1. เรียกใช้git status- จดบันทึกโฟลเดอร์โมดูลย่อยที่มีข้อขัดแย้ง
  2. รีเซ็ตโมดูลย่อยเป็นเวอร์ชันที่คอมมิตล่าสุดในสาขาปัจจุบัน:

    git reset HEAD path/to/submodule

  3. ณ จุดนี้คุณมีโมดูลย่อยเวอร์ชันที่ไม่มีข้อขัดแย้งซึ่งตอนนี้คุณสามารถอัปเดตเป็นเวอร์ชันล่าสุดได้ในที่เก็บของโมดูลย่อย:

    เส้นทาง cd / ถึง / โมดูลย่อย
    git submodule foreach git pull origin SUBMODULE-BRANCH-NAME
  4. ตอนนี้คุณทำได้commitและกลับไปทำงาน


16

ขั้นแรกค้นหาแฮชที่คุณต้องการให้โมดูลย่อยของคุณอ้างอิง จากนั้นเรียกใช้

~/supery/subby $ git co hashpointerhere
~/supery/subby $ cd ../
~/supery $ git add subby
~/supery $ git commit -m 'updated subby reference'

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


1
หรือคุณสามารถชำระเงินด้วยคอมไพล์ - ของพวกเขา (หรือ - ชั่วโมง) subby
Bachi

@Bachi: git checkout --theirs และ --ours ไม่มีผลต่อโมดูลย่อย
Edward Anderson

1
แม้ว่าสิ่งนี้จะช่วยแก้ปัญหาความขัดแย้งได้ แต่ก็ไม่ง่ายที่จะระบุ <hashpointerhere> ฉันไม่รู้วิธีง่ายๆในการดูการคอมมิตโมดูลย่อยที่เช็คเอาต์ในแต่ละด้านของความขัดแย้ง สิ่งที่คุณตรวจสอบใน subby อาจแตกต่างจากด้านใดด้านหนึ่งของการผสานซึ่งไม่เหมาะสมในการรวมคอมมิต
Edward Anderson

@nilbus ว่าจริง. เราได้ละทิ้งการทำงานกับโมดูลย่อยคอมไพล์เนื่องจากนั่นเป็นหนึ่งในข้อกังวลที่เรามีและทำให้ยากที่จะบอกได้ว่าคุณต้องการสิ่งใดจริง เราใช้นักแต่งเพลง (php) เป็นตัวจัดการแพ็คเกจซึ่งจริงๆแล้วฉันชอบเพราะมันสร้างไฟล์ล็อคที่ล็อค repos กับแฮชบางตัว อย่างไรก็ตามเนื่องจากเราใช้ node_modules ภายในหลาย repos เราจึงพบกับโมดูลที่ขัดแย้งกันที่นี่และที่นั่น ตั้งแต่นั้นมาเราเปลี่ยนมาใช้ npm เพื่อจัดการสิ่งนี้ แต่นั่นก็เป็นเวิร์มอื่น ๆ ทั้งหมด
hellatan

12

ฉันมีปัญหากับgit rebase -i origin/masterสาขานี้ ฉันต้องการใช้การอ้างอิงโมดูลย่อยเวอร์ชันมาสเตอร์ดังนั้นฉันจึงทำ:

git reset master path/to/submodule

แล้ว

git rebase --continue

นั่นช่วยแก้ปัญหาให้ฉันได้


3
สิ่งนี้ได้ผลสำหรับฉัน ฉันยังคงคิดว่าพวกเขาทำอะไรเพื่อที่จะสร้างความเสียหายให้กับโมดูลย่อย
Checo R

3

ได้รับความช่วยเหลือจากการสนทนานี้ ในกรณีของฉันไฟล์

git reset HEAD subby
git commit

ทำงานให้ฉัน :)


2

ในไดเรกทอรีหลักของฉันฉันเห็น:

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Unmerged paths:
(use "git reset HEAD <file>..." to unstage)
(use "git add <file>..." to mark resolution)

ก็เลยทำแค่นี้

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