อะไรคือความหมายที่แม่นยำของ“ ของเรา” และ“ ของพวกเขา” ในคอมไพล์?


323

อาจฟังดูเป็นคำถามพื้นฐาน แต่ฉันได้ค้นหาคำตอบแล้วและตอนนี้ฉันก็สับสนมากกว่าเดิม

"ของเรา" และ "ของพวกเขา" หมายความว่าอย่างไรในการคอมไพล์เมื่อรวมสาขาของฉันเข้ากับสาขาอื่นของฉัน ทั้งสองสาขาเป็น "ของเรา"

ในความขัดแย้งผสานคือ "ของเรา" จะแสดงส่วนบนของทั้งสองเวอร์ชันเสมอหรือไม่

"ของเรา" อ้างถึงสาขาที่ HEAD ชี้ไปเมื่อรวมเริ่มหรือไม่ ถ้าเป็นเช่นนั้นทำไมไม่ใช้การอ้างอิงความเป็นเจ้าของที่ชัดเจนเช่น "สาขาปัจจุบัน" แทนการใช้คำสรรพนามความเป็นเจ้าของเช่น "ของเรา" ที่อ้างถึงกำกวม (เนื่องจากทั้งสองสาขาเป็นเทคนิคของเรา)?

หรือเพียงแค่ใช้ชื่อสาขา (แทนที่จะพูดว่า "ของเรา" เพียงแค่พูดว่า "เจ้านายท้องถิ่น" หรือเช่นนั้น)?

ส่วนที่สับสนที่สุดสำหรับฉันคือถ้าฉันระบุในไฟล์. gitattributes ของสาขาเฉพาะ ให้พูดในสาขาการทดสอบฉันมีไฟล์. gitattributes ต่อไปนี้:

config.xml merge=ours

ตอนนี้ฉันเช็คเอาท์และจุดมุ่งหน้าไปยังต้นแบบแล้วผสานในการทดสอบ เนื่องจากอาจารย์เป็นของเราและไม่ได้ชำระเงิน. gitattributes ของการทดสอบจึงจะมีผลหรือไม่ ถ้ามันมีผลกระทบเพราะตอนนี้อาจารย์เป็น "ของเรา" แล้วจะเกิดอะไรขึ้น?

คำตอบ:


374

ฉันสงสัยว่าคุณสับสนที่นี่เพราะมันสับสนพื้นฐาน เพื่อทำให้สิ่งเลวร้ายลงสิ่งต่าง ๆ ทั้งหมดของเรา / ของพวกเขาเปลี่ยนบทบาท (กลายเป็นถอยหลัง) เมื่อคุณทำการ rebase

ในที่สุดในระหว่างที่git mergeสาขา "ของเรา" อ้างถึงสาขาที่คุณกำลังรวมอยู่ :

git checkout merge-into-ours

และสาขา "พวกเขา" หมายถึงสาขา (เดี่ยว) ที่คุณกำลังรวม:

git merge from-theirs

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

ในขณะที่ใช้ชื่อสาขาที่แท้จริงอาจจะดูดี แต่มันก็แยกออกเป็นกรณี ๆ ที่ซับซ้อน ตัวอย่างเช่นแทนที่จะเป็นข้างต้นคุณอาจทำ:

git checkout ours
git merge 1234567

ตำแหน่งที่คุณรวมเข้าด้วย raw commit-ID ที่เลวร้ายยิ่งคุณสามารถทำได้:

git checkout 7777777    # detach HEAD
git merge 1234567       # do a test merge

ในกรณีที่ไม่มีชื่อสาขาเกี่ยวข้อง!

ฉันคิดว่ามันช่วยได้เล็กน้อยที่นี่ แต่ในความเป็นจริงแล้วในgitrevisionsไวยากรณ์คุณสามารถอ้างถึงแต่ละเส้นทางในดัชนีด้วยตัวเลขระหว่างการผสานที่ขัดแย้งกัน

git show :1:README
git show :2:README
git show :3:README

สเตจ # 1 เป็นบรรพบุรุษของไฟล์ทั่วไปสเตจ # 2 เป็นเวอร์ชันสาขาเป้าหมายและสเตจ # 3 เป็นเวอร์ชันที่คุณกำลังผสาน


เหตุผลที่ความคิด "ของเรา" และ "ของพวกเขา" เปลี่ยนไปในระหว่างrebaseนั้นคือการที่การคืนเงินทำงานโดยการทำชุดของเชอร์รี่ - หยิบเข้าไปในสาขาที่ไม่ระบุชื่อ (โหมด HEAD เดี่ยว) สาขาเป้าหมายเป็นสาขาที่ไม่ระบุชื่อและสาขาที่ผสานจากสาขาเป็นสาขาเดิมของคุณ (pre-rebase) ดังนั้น "- สี่" จึงหมายถึงการไม่ระบุชื่อหนึ่งครั้งกำลังสร้างขณะที่ "- พวก" หมายถึง "สาขาของเรากำลังถูกปฏิเสธ" .


สำหรับรายการ gitattributes: มันอาจมีผลกระทบ: "ของเรา" จริงๆหมายถึง "ใช้เวที # 2" ภายใน แต่ตามที่คุณทราบมันไม่ได้เกิดขึ้นจริงในเวลาดังนั้นจึงไม่ควรมีผลกระทบที่นี่ ... ดีไม่เว้นแต่คุณจะคัดลอกลงในแผนผังการทำงานก่อนที่จะเริ่ม

นอกจากนี้โดยวิธีการนี้ใช้กับการใช้งานทั้งหมดของเราและของพวกเขา แต่บางคนอยู่ในระดับไฟล์ทั้งหมด ( -s oursสำหรับกลยุทธ์การผสาน; git checkout --oursระหว่างความขัดแย้งผสาน) และบางส่วนอยู่บนพื้นฐานทีละชิ้น ( -X oursหรือ-X theirsระหว่าง-s recursiveผสาน). ซึ่งอาจไม่ช่วยอะไรสับสนได้

ฉันไม่เคยคิดชื่อที่ดีกว่านี้มาก่อน และ: ดูคำตอบของ VonC สำหรับคำถามอื่นที่git mergetoolแนะนำชื่อเหล่านี้เพิ่มเติมโดยเรียกพวกเขาว่า "local" และ "remote"!


28
+1 เกี่ยวกับเราและสิ่งที่พวกเขาถูกย้อนกลับในระหว่างการรีบูตดูได้ที่: stackoverflow.com/a/2960751/6309และstackoverflow.com/a/3052118/6309
VonC

1
สองสิ่ง "รวมเข้ากับ" กันและกัน เมื่อการผสานเกิดขึ้นทั้งสองข้างจะรวมกันเป็น "กันและกัน" ฉันรู้สึกว่ามันไม่ถูกต้องที่จะบอกว่าหนึ่งในสองด้านคือ "ไม่รวมเข้ากับอะไร" หากไม่มีชื่อสาขาที่เกี่ยวข้อง (ตามที่คุณชี้ให้เห็น) จะมีชื่อที่เกี่ยวข้อง (คุณสามารถพูดว่า "7777777's" และ "1234567's" แทนที่จะเป็น "เรา" และ "พวกเขา") ฉันเข้าใจว่าเกิดอะไรขึ้นในระหว่างการรีบูตและฉันไม่คิดว่ามันจะสับสน ฉันคิดว่า "HEAD's" และ "ขาเข้า" จะทำงานได้ดีกว่า "ของเรา" และ "ของพวกเขา" เพราะมี "HEAD" อยู่เสมอ (ไม่ว่าจะแยกออกหรือไม่ก็ตาม)
CommaToast

15
ฉันเดาว่าตั้งแต่หัวเป็นที่นั่งของจิตใจซึ่งเป็นแหล่งที่มาของตัวตนซึ่งเป็นแหล่งของตัวเองมันจึงสมเหตุสมผลกว่าที่จะคิดว่าสิ่งที่หัวหน้าชี้ไปที่ว่าเป็น "ของฉัน" ("ของเรา" เนื่องจาก ฉันเดาว่าฉันกับ HEAD ทำให้เป็นสอง) หากไม่มีอะไรเพิ่มเติมนั่นจะเป็นอุปกรณ์ช่วยในการจำที่ดี
CommaToast

1
ที่ถูกกล่าวว่าฉันยังคงต้องการทำสำเนาทางกายภาพของ repo ทั้งหมดก่อนที่จะทำอะไรเช่น rebasing ... : D
CommaToast

3
"ในกรณีนี้ไม่มีชื่อสาขาที่เกี่ยวข้อง!" ... ดังนั้นควรใช้คอมเม้นท์คอมเม้นท์ / แฮชแทน อะไรก็ตามที่มันสามารถทำได้ แทบทุกอย่างจะดีกว่า "ของเรา" และ "ของพวกเขา" ฉันสงสัยว่าความสับสนนี้ระเหยไปกี่พันชั่วโมง คำตอบของคอมไพล์ต่อ C ++ "Most vexing parse";)
Jarrod Smith

49

' ours ' ใน Git หมายถึงสาขาการทำงานดั้งเดิมซึ่งมีส่วนที่มีอำนาจ / เป็นที่ยอมรับในประวัติศาสตร์ของ git

' พวกเขา ' หมายถึงรุ่นที่มีการทำงานเพื่อที่จะได้รับการrebased (การเปลี่ยนแปลงที่จะเล่นซ้ำไปยังสาขาปัจจุบัน)

สิ่งนี้อาจปรากฏขึ้นเพื่อแลกเปลี่ยนกับผู้ที่ไม่ทราบว่าการรีบูต (เช่นgit rebase) กำลังทำให้งานของคุณถูกระงับ (ซึ่งก็คือของพวกเขา ) เพื่อเล่นซ้ำในประวัติ / หลักซึ่งเป็นที่ยอมรับของเราเพราะเรากำลัง เปลี่ยนเป็นการทำงานของบุคคลที่สาม

เอกสารประกอบสำหรับgit-checkoutการชี้แจงเพิ่มเติมใน Git> = 2.5.1 ตามการf303016กระทำ :

--ours --theirs

เมื่อตรวจสอบเส้นทางจากดัชนีให้ตรวจสอบขั้นตอนที่ # 2 ('ของเรา') หรือ # 3 ('ของพวกเขา') เพื่อหาเส้นทางที่ไม่รวม

โปรดทราบว่าในระหว่างgit rebaseและgit pull --rebase'พวกเรา' และ 'พวกเขา' อาจปรากฏสลับกัน --oursให้รุ่นจากสาขาการเปลี่ยนแปลงจะถูก rebased ลงในขณะที่--theirsให้รุ่นจากสาขาที่เก็บงานของคุณที่จะถูก rebased

นี่เป็นเพราะrebaseมีการใช้ในเวิร์กโฟลว์ที่ถือว่าประวัติที่ระยะไกลเป็นที่ยอมรับร่วมและปฏิบัติงานที่ทำในสาขาที่คุณกำลัง rebasing เป็นงานของบุคคลที่สามที่จะรวมและคุณกำลังสมมติบทบาทของ ผู้รักษาประวัติที่ยอมรับในระหว่าง rebase ในฐานะผู้รักษาประวัติบัญญัติคุณต้องดูประวัติจากระยะไกลเป็นours(เช่น "ประวัติบัญญัติบัญญัติร่วมของเรา") ในขณะที่สิ่งที่คุณทำในสาขาของคุณเป็นtheirs(กล่าวคือ "งานของผู้สนับสนุนคนหนึ่งอยู่ด้านบน")

เพราะgit-mergeมันอธิบายในวิธีต่อไปนี้:

ของเราเอง

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

สิ่งนี้ไม่ควรสับสนกับกลยุทธ์การผสานของเราซึ่งไม่แม้แต่จะดูว่าต้นไม้อื่นมีอะไรบ้าง มันทิ้งทุกสิ่งที่ต้นไม้อื่นทำประกาศประวัติศาสตร์ของเรามีทุกสิ่งที่เกิดขึ้นในนั้น

ของพวกเขา

นี่คือสิ่งที่ตรงกันข้ามกับเรา

ยิ่งไปกว่านั้นนี่คือคำอธิบายวิธีใช้:

กลไกการผสาน ( git mergeและgit pullคำสั่ง) ช่วยให้สามารถเลือกกลยุทธ์การผสานแบ็กเอนด์ด้วย-sตัวเลือก กลยุทธ์บางอย่างยังสามารถใช้ตัวเลือกของตัวเองซึ่งสามารถส่งผ่านโดยให้-X<option>ข้อโต้แย้งและgit merge / หรือgit pull


ดังนั้นบางครั้งอาจทำให้เกิดความสับสนตัวอย่างเช่น:

  • git pull origin master-Xoursท้องถิ่นของเราอยู่ที่ไหน มี-Xtheirsสาขา (ระยะไกล)
  • git pull origin master -r-Xoursพวกเขาอยู่ที่ไหน(ระยะไกล) -Xtheirsเป็นของเรา

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

คล้ายกับgit mergeกลยุทธ์ ( -X oursและ-X theirs)


2
คำตอบนี้ดูเหมือนจะล้าสมัย => "git merge --ours" ไม่ใช่ตัวเลือกที่ถูกต้อง
Alexander Mills

@AlexanderMills คำตอบไม่ได้พูดคุยเกี่ยวกับgit mergeแต่git pullและgit checkoutเป็นตัวอย่าง หากคุณต้องการใช้พารามิเตอร์นี้กับคุณควรใช้git merge -X oursคุณยังสามารถใช้ไวยากรณ์สำหรับ--ours git checkoutฉันชี้แจงเพิ่มเติมคำตอบเพิ่มเติม
kenorb

46

ฉันรู้ว่าสิ่งนี้ได้รับคำตอบแล้ว แต่ปัญหานี้ทำให้ฉันสับสนหลายครั้งที่ฉันได้จัดทำเว็บไซต์อ้างอิงขนาดเล็กขึ้นมาเพื่อช่วยฉันจำ: https://nitaym.github.io/ourstheirs/

นี่คือพื้นฐาน:

ผสาน:

$ git checkout master 
$ git merge feature

หากคุณต้องการเลือกรุ่นในmaster:

$ git checkout --ours codefile.js

หากคุณต้องการเลือกรุ่นในfeature:

$ git checkout --theirs codefile.js

rebases:

$ git checkout feature 
$ git rebase master 

หากคุณต้องการเลือกรุ่นในmaster:

$ git checkout --ours codefile.js

หากคุณต้องการเลือกรุ่นในfeature:

$ git checkout --theirs codefile.js

(นี่เป็นไฟล์ที่สมบูรณ์แน่นอน)


1
เว็บไซต์นั้นมีประโยชน์มาก รูปแบบการไหลของแผนภูมิและคำที่ใช้รหัสสีทำให้เว็บไซต์เข้าใจได้ง่ายกว่าคำตอบ SO ขอบคุณ.
Ron

10
  • ของเรา : นี่คือสาขาที่คุณอยู่ในขณะนี้
  • พวกเขา : นี่คือสาขาอื่น ๆ ที่ใช้ในการกระทำของคุณ

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

ปัญหาเดียวที่คนส่วนใหญ่ตกสำหรับเป็นกรณี rebase ถ้าคุณทำฐานอีกครั้งแทนที่จะผสานปกติบทบาทจะถูกสลับ วิธีที่ว่า? นั่นเกิดจากการรีบูตเท่านั้น คิดว่าการลดระดับการทำงานเช่นนั้น:

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

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

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


3

ฉันรู้ว่ามันไม่ได้อธิบายความหมาย แต่ฉันทำให้ตัวเองเป็นภาพเล็ก ๆ น้อย ๆ เป็นข้อมูลอ้างอิงเพื่อเตือนให้คนที่ใช้

ป้อนคำอธิบายรูปภาพที่นี่

หวังว่ามันจะช่วย!

ป.ล. - ให้เช็คที่ลิงค์ในคำตอบของ Nitay 🙂


3

ฉันจะโพสต์บันทึกที่นี่เพราะฉันต้องกลับมาที่นี่อีกครั้งแล้วครั้งเล่า

สถานการณ์ 1. ผู้พัฒนาปกติ:คุณเป็นนักพัฒนาที่ไม่สามารถผสานmasterและต้องเล่นกับfeatureสาขาเท่านั้น

กรณีที่ 1: อาจารย์เป็นราชา คุณต้องการรีเฟรชfeatureสาขา (= rebase ไปที่master) เนื่องจากmasterมีการอัพเดทใหม่ ๆ ของการพึ่งพาและคุณต้องการเขียนทับการเปลี่ยนแปลงเล็กน้อยของคุณ

git checkout master
git pull

git checkout feature
git rebase -X ours master

กรณีที่ 2: คุณเป็นราชา คุณต้องการรีบูตfeatureสาขาของคุณเพื่อmasterการเปลี่ยนแปลง แต่คุณทำมากกว่าเพื่อนร่วมงานของคุณและต้องการใช้การเปลี่ยนแปลงของคุณเองในลำดับความสำคัญ

git checkout master
git pull

git checkout feature
git rebase -X theirs master

สำคัญ: อย่างที่คุณเห็นนักพัฒนาปกติควรชอบrebaseและทำซ้ำทุกเช้าเช่นออกกำลังกาย / กาแฟ

สถานการณ์ 2. การรวมอาจารย์:คุณเป็นผู้นำทีมและต้องการรวมสาขาอื่น ๆ และส่งผลการผสานโดยตรงไปยังอาจารย์ masterเป็นสาขาที่คุณจะเปลี่ยน

กรณีที่ 1: เจ้านายเป็นราชาคุณต้องการรวมสาขาของบุคคลที่สาม แต่masterมีความสำคัญ featureเป็นสาขาที่ผู้อาวุโสของคุณทำ

git checkout feature
git pull

git checkout master
git merge -X ours master

กรณีที่ 2: การเปลี่ยนแปลงใหม่เป็นเรื่องใหญ่เมื่อนักพัฒนาอาวุโสของคุณเปิดตัวเจ๋ง ๆfeatureและคุณต้องการเขียนทับเก่า ** ในmasterสาขา

git checkout feature
git pull

git checkout master
git merge -X theirs master

โปรดจำไว้ว่าให้จำในเวลาเที่ยงคืนซึ่งตัวเลือก: masterเป็นoursเสมอ และtheirsนี่คือสิ่งfeatureที่พวกเขาได้กระทำ


2

จากgit checkoutการใช้งาน:

-2, --ours            checkout our version for unmerged files
-3, --theirs          checkout their version for unmerged files
-m, --merge           perform a 3-way merge with the new branch

เมื่อแก้ไขข้อขัดแย้งในการผสานคุณสามารถทำได้git checkout --theirs some_fileและgit checkout --ours some_fileเพื่อรีเซ็ตไฟล์เป็นเวอร์ชันปัจจุบันและเวอร์ชันที่เข้ามาตามลำดับ

ถ้าคุณได้ทำgit checkout --ours some_fileหรือgit checkout --theirs some_fileและต้องการที่จะตั้งค่าไฟล์ไปยังรุ่นผสาน 3 git checkout --merge some_fileทางของไฟล์ที่คุณสามารถทำได้

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