เลือกกลยุทธ์การรวม Git สำหรับไฟล์เฉพาะ (“ ของเรา”,“ ของฉัน”,“ ของพวกเขา”)


207

ผมอยู่ในช่วงกลางของ rebasing git pull --rebaseหลังจากที่ ฉันมีไฟล์ไม่กี่ไฟล์ที่มีข้อขัดแย้งผสาน ฉันจะยอมรับการเปลี่ยนแปลง "ของพวกเขา" หรือ "การเปลี่ยนแปลง" ของฉันสำหรับไฟล์เฉพาะได้อย่างไร

$ git status
# Not currently on any branch.
# You are currently rebasing.
#   (fix conflicts and then run "git rebase --continue")
#   (use "git rebase --skip" to skip this patch)
#   (use "git rebase --abort" to check out the original branch)
#
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:  CorrectlyMergedFile
#
# Unmerged paths:
#   (use "git reset HEAD <file>..." to unstage)
#   (use "git add <file>..." to mark resolution)
#
#       both modified: FileWhereIWantToAcceptTheirChanges
#       both modified: FileWhereIWantToAcceptMyChanges

โดยปกติฉันเพิ่งเปิดไฟล์หรือเครื่องมือผสานและยอมรับการเปลี่ยนแปลง "ของพวกเขา" หรือ "ของฉัน" ด้วยตนเองทั้งหมด อย่างไรก็ตามฉันสงสัยว่าฉันขาดคำสั่ง git สะดวก

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


@AbeVoelker ฉันไม่คิดว่าจะแก้ปัญหาของฉันได้ ฉันต้องการเลือกกลยุทธ์การรวมสำหรับไฟล์เฉพาะ นอกจากนี้โปรดทราบว่าฉันจะรู้ได้ว่าจะใช้ stragegy ใดรวมกันเมื่อฉันอยู่ในการรีบูตและดูว่าไฟล์ใดบ้างที่มีข้อขัดแย้งการเข้าชมและความขัดแย้งคืออะไร
Steven Wexler

ฉันแก้ไขคำถามนี้จะเป็นทั่วไปมากขึ้น: stackoverflow.com/questions/278081/... บางทีเราสามารถปิดคำถามนี้ซ้ำซ้อนได้ มีความเหมาะสมหรือไม่

@ TheShadow ดูเหมือนว่าสมเหตุสมผลสำหรับฉัน
Steven Wexler

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

ซ้ำเป็นไปได้ของเครื่องมือที่ง่ายต่อการ 'ยอมรับพวกเขา' หรือ 'ยอมรับเหมือง' บนไฟล์ทั้งหมดโดยใช้คอมไพล์

คำตอบ:


251

สำหรับไฟล์ที่ขัดแย้งแต่ละไฟล์ที่คุณได้รับคุณสามารถระบุได้

git checkout --ours -- <paths>
# or
git checkout --theirs -- <paths>

จากgit checkoutเอกสาร

git checkout [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <paths>...

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

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


9
เป็นไปได้ไหมที่จะยอมรับแฟ้มเหล่านั้นสำหรับไฟล์ทั้งหมดที่ยังไม่ได้รวมกัน?
aslakjo

41
@aslakjo หรือgit rebase -s recursive -X <ours/theirs> git merge -s recursive -X <ours/theirs>โปรดทราบว่าการคืนเงิน "ของเรา" และ "ของพวกเขา" จะถูกย้อนกลับจากสิ่งที่พวกเขาอยู่ในระหว่างการรวม คุณอาจใช้ไฟล์ / เชลล์ glob ได้เช่นgit checkout --theirs -- *.txtกัน

2
ขอบคุณมาก @Cupcake การกลับมาโดยไม่คาดคิดของours/theirsrebase ทำให้ฉันบ้ามาก !! (มันสมเหตุสมผลแล้วตอนนี้ที่ฉันคิดว่าการลดระดับเสียงใช้งานได้จริง แต่ไม่ง่ายเลย)
Dan Lenski

2
@DanLenski rebase โดยทั่วไปเป็นเพียงเครื่องมือที่ยุ่งยากจริงๆสำหรับคนที่จะเข้าใจในตอนแรก แต่เมื่อคุณเข้าใจวิธีการทำงานแล้วคุณสามารถทำสิ่งที่ทรงพลังทุกอย่างกับมันได้

1
@VincentSels จริง ๆ แล้วคุณต้องปิดบังอักขระ * มิฉะนั้นเชลล์จะพยายามขยาย ดังนั้นในกรณีของคุณgit checkout --outs -- "**/*.csproj"จะทำในสิ่งที่คุณหมายถึง git lfs track "*.jpg"เดียวกันเป็นเช่นจริงสำหรับ หากคุณมีไฟล์ jpg บางไฟล์ใน CWD ของคุณโดยไม่มีเครื่องหมายคำพูดจะมีการติดตามเฉพาะไฟล์เหล่านี้
eFloh

117

แม้ว่าจะตอบคำถามนี้ได้ แต่ให้ตัวอย่างว่า "ของพวกเขา" และ "ของเรา" หมายถึงอะไรในกรณีของการคืนค่า Git และผสาน ดูลิงค์นี้

Git Rebase
theirsเป็นจริงสาขาในปัจจุบันในกรณีของrebase ดังนั้นชุดคำสั่งด้านล่างจึงยอมรับการเปลี่ยนแปลงสาขาปัจจุบันของคุณมากกว่าสาขาระยะไกล

# see current branch
$ git branch
... 
* branch-a
# rebase preferring current branch changes during conflicts
$ git rebase -X theirs branch-b

Git Merge
สำหรับการผสานความหมายtheirsและการoursย้อนกลับ ดังนั้นเพื่อให้ได้ผลที่เหมือนกันระหว่างการผสานคือทำให้การเปลี่ยนแปลงสาขาปัจจุบันของคุณ ( ours) อยู่เหนือการรวมสาขาจากระยะไกล ( theirs)

# assuming branch-a is our current version
$ git merge -X ours branch-b  # <- ours: branch-a, theirs: branch-b

2
นี่มันค่อนข้างแตกต่างที่สำคัญ! ขอบคุณสำหรับการชี้แจง
verboze

26

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

แต่หากคุณต้องการดำเนินการผสานสามทางที่ไฟล์และเพียงแก้ไขhunks ขัดแย้งที่ใช้--ours|--theirsในขณะที่การรักษา hunks ไม่ใช่ขัดแย้งจากทั้งสองฝ่ายในสถานที่ที่คุณอาจต้องการที่จะหันไปgit merge-file; ดูรายละเอียดในคำตอบนี้


1
เกี่ยวกับ "การเปลี่ยนแปลงที่ไม่ขัดแย้ง" ซึ่งจะหายไป - นี่หมายถึงเฉพาะไฟล์ที่มีการเปลี่ยนแปลงที่ไม่ขัดแย้งกันในบรรทัดที่เฉพาะเจาะจงซึ่งอยู่ในไฟล์เดียวกันหรือการเปลี่ยนแปลงทั้งหมดจากไฟล์ทั้งหมดในประวัติสอดคล้องกัน?
ktamlyn

2
@ktamlyn โดย "การเปลี่ยนแปลงที่ไม่ขัดแย้งกัน" ฉันหมายถึงการเปลี่ยนแปลงในไฟล์เดียวกัน ตัวอย่างเช่นมีสอง hunks เปลี่ยนแปลง (ชิ้นส่วน) ในexample.txtในoursรุ่นหนึ่งคือการขัดแย้ง (ยังมีการเปลี่ยนแปลงในtheirsการแก้ไข) อื่น ๆ ที่ไม่ได้มีความขัดแย้ง หากคุณทำเช่นgit checkout --theirs example.txtนั้นไฟล์จะอ่านไฟล์ทั้งหมดในขณะที่theirsแก้ไขและส่วนที่ไม่ขัดแย้งของส่วนต่างจะหายไป
jakub.g

1
ขอบคุณ! นี่เป็นคำอธิบายที่จำเป็นสำหรับฉันแม้ว่า "การเปลี่ยนแปลงในไฟล์เดียวกัน" จะเหมาะสมที่สุดในบริบทนี้
ktamlyn

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

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