git stash blunder: git stash pop และจบลงด้วยการรวมความขัดแย้ง


200

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

chirag-patels-macbook-pro:haloror patelc75$ git status
app/views/layouts/_choose_patient.html.erb: needs merge
app/views/layouts/_links.html.erb: needs merge
# On branch prod-temp
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   db/schema.rb
#
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       unmerged:   app/views/layouts/_choose_patient.html.erb
#       unmerged:   app/views/layouts/_links.html.erb

chirag-patels-macbook-pro:haloror patelc75$ git checkout app/views/layouts/_choose_patient.html.erb
error: path 'app/views/layouts/_choose_patient.html.erb' is unmerged
chirag-patels-macbook-pro:haloror patelc75$ git checkout -f app/views/layouts/_choose_patient.html.erb
warning: path 'app/views/layouts/_choose_patient.html.erb' is unmerged

หมายเหตุ: การกู้คืนสถานะก่อนที่git stash apply/popจะง่ายขึ้นด้วย Git 2.5 (Q2 2015) เนื่องจากต้นไม้ทำงานตอนนี้ต้องสะอาด: ดูคำตอบของฉันด้านล่าง
VonC

คำตอบ:


219

ดูman git merge ( วิธีแก้ไขความขัดแย้ง )

หลังจากเห็นความขัดแย้งคุณสามารถทำได้สองสิ่ง:

  • ตัดสินใจที่จะไม่รวม การล้างข้อมูลที่คุณต้องการเพียงอย่างเดียวคือการรีเซ็ตไฟล์ดัชนีให้เป็น HEAD เพื่อย้อนกลับ 2. และทำความสะอาดการเปลี่ยนแปลงแผนผังการทำงานที่ทำโดย 2 และ 3 git-reset - ฮาร์ดสามารถใช้สำหรับสิ่งนี้

  • แก้ไขข้อขัดแย้ง Git จะทำเครื่องหมายข้อขัดแย้งในแผนผังการทำงาน แก้ไขไฟล์เป็นรูปร่างและ git เพิ่มลงในดัชนี ใช้คอมไพล์คอมมิทเพื่อประทับตราดีล

และภายใต้TRUE MERGE (เพื่อดูว่า 2 และ 3 หมายถึงอะไร):

เมื่อไม่ชัดเจนว่าจะกระทบยอดการเปลี่ยนแปลงอย่างไรสิ่งต่อไปนี้จะเกิดขึ้น:

  1. ตัวชี้ HEAD ยังคงเหมือนเดิม

  2. การอ้างอิง MERGE_HEAD ถูกตั้งค่าให้ชี้ไปที่ส่วนหัวสาขาอื่น

  3. เส้นทางที่ผสานอย่างหมดจดจะได้รับการอัปเดตทั้งในไฟล์ดัชนีและในแผนผังการทำงานของคุณ

  4. ...

ดังนั้น: ใช้git reset --hardถ้าคุณต้องการลบการเปลี่ยนแปลงที่ซ่อนออกจากแผนผังการทำงานของคุณหรือgit resetถ้าคุณต้องการล้างข้อมูลดัชนีและปล่อยให้ความขัดแย้งในแผนผังการทำงานของคุณรวมเข้าด้วยกัน

ภายใต้ที่เก็บ git ( OPTIONS, pop ) คุณสามารถอ่านเพิ่มเติมได้ที่:

การใช้สถานะอาจล้มเหลวด้วยความขัดแย้ง ในกรณีนี้มันจะไม่ถูกลบออกจากรายการที่ซ่อน คุณต้องแก้ไขข้อขัดแย้งด้วยตนเองและโทร git stash drop ด้วยตนเองหลังจากนั้น


9
ในความเป็นจริงแม้หลังจากที่คุณวางที่เก็บข้อมูลก็ยังคงเป็นไปได้ (แม้ว่าจะยากขึ้น) ในการดึงข้อมูลอีกครั้งเนื่องจากชุดการเปลี่ยนแปลงยังคงมีอยู่ในที่เก็บ stackoverflow.com/search?q=git+recover+dropped+stash
phils

3
@ ชัด ๆ : ดีหรือไม่ดี? คุณจะยินดีที่จะปรับปรุงคำตอบของฉันที่คุณไม่เข้าใจมันในสถานที่แรก ...
tanascius

1
ฉันคิดว่าการแก้ไขซอร์สโค้ดเป็นโดเมนปัญหาที่ซับซ้อน มันง่ายที่จะสับสน ฉันยังคิดว่าคำตอบของคุณดีเพราะยืนยันวิธีการของฉันอีกครั้ง
nalply

1
ไม่เพียง แต่ช่วยฉันได้มากที่จะรู้ว่า stash ไม่ได้ถูกลบออกอย่างที่ฉันคิดไว้ แต่สิ่งนี้อธิบายได้ว่าทำไมที่เก็บของฉันยังคงเติบโตแม้ว่าฉันจะแน่ใจว่าฉันไม่ลืมที่จะดึงสิ่งต่าง ๆ ออกจากมัน
Thor84no

11
"การใช้สถานะอาจล้มเหลวด้วยความขัดแย้งในกรณีนี้มันจะไม่ถูกลบออกจากรายการที่ซ่อน" นี่เป็นส่วนที่สำคัญที่สุดของการโพสต์ในความคิดของฉัน พิจารณาแก้ไขคำตอบของคุณเพื่อนำไปใช้พร้อมกับคำที่ไม่ต้องตกใจด้วยตัวอักษรขนาดใหญ่และเป็นมิตร (+1 แล้วแม้ว่า) ขอบคุณ
Patrick M

42

ฉันมีสิ่งที่คล้ายกันเกิดขึ้นกับฉัน ฉันไม่ได้ต้องการที่จะเป็นเวทีไฟล์เพียง แต่ดังนั้นฉันเพิ่มพวกเขาด้วยแล้วก็ไม่ได้git add git resetโดยทั่วไปเพิ่งเพิ่มและไม่เปลี่ยนแปลงการเปลี่ยนแปลงของฉัน แต่ล้างเส้นทางที่ไม่ได้รวม


4
สิ่งนี้น่าจะดีกว่าการใช้reset --hardเพราะมันไม่ได้เขียนทับไฟล์ของคุณ (ยกเว้นไฟล์ที่มีปัญหาการรวม) ขอบคุณ!
sinelaw

ฉันยังไม่ต้องการจัดแสดงไฟล์ดังนั้นฉันจึงเพิ่มไฟล์ - ไม่addแสดงเนื้อหาจากแผนผังการทำงานไปยังดัชนีหรือไม่ ฉันไม่คิดว่าฉันเข้าใจว่าเหตุใดคำตอบของคุณจึงมาจากคำอธิบาย
Drew Noakes

2
git addเวทีพวกเขา แต่git resetที่ฉันทำทันทีหลังจาก unstages พวกเขา โดยพื้นฐานแล้วมันจะล้างเส้นทางที่ไม่ได้จมน้ำและนำฉันกลับไปที่ต้นไม้ทำงานตามปกติโดยการแกล้งออก
แอรอน

3
คุณไม่จำเป็นต้องถ้าคุณกำลังจะไปgit add ได้อย่างมีประสิทธิภาพ "เลิกทำการที่" ( <- ค่าเริ่มต้น) อย่างมีประสิทธิภาพไม่ได้สัมผัสไดเรกทอรีการทำงานดังนั้นสิ่งที่อยู่ในไดเรกทอรีการทำงานของคุณผสานความขัดแย้งและทั้งหมดจะถูกทิ้งให้อยู่คนเดียว ดัชนี (และในทางเทคนิคส่วนหัวสาขา) ถูกรีเซ็ตแม้ว่า (โดยไม่มีการอ้างอิงพวกเขาจะถูกรีเซ็ตกลับไปซึ่งอาจหมายถึงไม่มีการเปลี่ยนแปลงสำหรับส่วนหัวสาขาและยกเลิกการทำดัชนีใด ๆ ได้อย่างมีประสิทธิภาพ. git resetgit resetgit addgit reset--mixedHEADgit add
bambams

3
ลำดับ , แก้ไข / แก้ไข , git resetและgit stash dropทำงานได้ดี มันทำในสิ่งที่git stash popจะทำโดยไม่มีข้อขัดแย้ง ดูเหมือนว่าgit addมันไม่จำเป็น แม้ว่ามันจะมีประโยชน์ แต่คุณมีไฟล์จำนวนมากที่มีข้อขัดแย้ง เมื่อแก้ไขแต่ละรายการแล้วจะสามารถเพิ่มและgit statusติดตามได้
เสียงอึกทึกครึกครื้น

13

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

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

คุณอาจต้องการเรียกใช้git stash drop [<stash name>]หลังจากนั้นเพื่อกำจัดการซ่อนเนื่องจากgit stash popไม่ลบในกรณีที่มีข้อขัดแย้ง


2

สังเกตได้ว่า Git 2.5 (Q2 2558) Git ในอนาคตอาจพยายามทำให้สถานการณ์เป็นไปไม่ได้

ดูคอมมิท ed178efโดยJeff King ( peff), 22 เม.ย. 2558
(ผสานโดยJunio ​​C Hamano - gitster- ในการลงทะเบียน 05c3967 , 19 พฤษภาคม 2558)

หมายเหตุ: สิ่งนี้ถูกเปลี่ยนกลับ ดูด้านล่าง

stash: ต้องการดัชนีแบบใหม่เพื่อใช้ / ป๊อปอัป

ปัญหา

หากคุณมีเนื้อหาตามขั้นตอนในดัชนีและเรียกใช้ " stash apply/pop" เราอาจพบข้อขัดแย้งและนำรายการใหม่เข้าสู่ดัชนี
การกู้คืนสู่สถานะดั้งเดิมของคุณเป็นเรื่องยาก ณ จุดนั้นเนื่องจากเครื่องมือเช่น "รีเซ็ต git --keep" จะทำให้ทุกอย่างที่จัดฉากหายไป

ในคำอื่น ๆ :

" git stash pop/apply" ลืมที่จะตรวจสอบให้แน่ใจว่าไม่ใช่แค่ต้นไม้ทำงานที่สะอาด แต่ยังดัชนีสะอาด
สิ่งหลังมีความสำคัญเนื่องจากแอปพลิเคชันสะสมอาจขัดแย้งกันและดัชนีจะถูกใช้สำหรับการแก้ไขข้อขัดแย้ง

สารละลาย

เราสามารถทำให้ปลอดภัยยิ่งขึ้นโดยปฏิเสธที่จะใช้เมื่อมีการเปลี่ยนแปลงระยะเวลา

นั่นหมายความว่าหากมีการรวมก่อนหน้านี้เนื่องจากการใช้ที่ซ่อนบนไฟล์ที่แก้ไข (เพิ่ม แต่ไม่มุ่งมั่น) ตอนนี้พวกเขาจะไม่ถูกรวมเข้าด้วยกันเพราะ stash Apply / pop จะหยุดทันทีด้วย:

Cannot apply stash: Your index contains uncommitted changes.

การบังคับให้คุณยอมรับการเปลี่ยนแปลงหมายความว่าในกรณีของการรวมคุณสามารถคืนค่าสถานะเริ่มต้น (ก่อนgit stash apply/pop) ด้วย a git reset --hardได้อย่างง่ายดาย


ดูกระทำ 1937610 (15 มิถุนายน 2015) และกระทำ ed178ef (22 เมษายน 2015) โดยเจฟฟ์คิง (peff )
(ผสานโดยJunio ​​C Hamano - gitster- in bfb539b , 24 Jun 2558)

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

โชคไม่ดีสิ่งนี้ทำให้เวิร์กโฟลว์ทั่วไปเกิดความเสียหายรอบ ๆ " git stash -k" เช่น:

git add -p       ;# (1) stage set of proposed changes
git stash -k     ;# (2) get rid of everything else
make test        ;# (3) make sure proposal is reasonable
git stash apply  ;# (4) restore original working tree

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

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