วิธีการกู้คืนที่ถูกทิ้งใน Git?


1737

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

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

มีวิธีง่าย ๆ ในการกู้คืนข้อมูลอ้างอิงของเมื่อวานหรือไม่?

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


74
หมายเหตุสำหรับอนาคต: หากคุณไม่ต้องการที่จะสูญเสีย stashes ของคุณทุกครั้งที่คุณgit stash popคุณสามารถทำgit stash applyแทน มันทำสิ่งเดียวกันยกเว้นจะไม่ลบการอ้างอิงไปยังที่เก็บที่ใช้
Kevin

3
พยายามทุกอย่างที่นี่ไม่พบที่ซ่อนที่ผุดขึ้นมาแล้ว ดีใจมากสำหรับjetbrains.com/help/idea/local-history.html
Juan Mendes


ฉันมีปัญหานี้ การอัปเดต repo ของฉันฉันวิ่งgit stash, git pull -r upstream, git push -f origin, git stash pop, และป๊อปกล่าวว่า "ร้ายแรง: บันทึกสำหรับ refs / ซ่อนเป็นที่ว่างเปล่า" 😲ฉันลองคำตอบเหล่านี้มาจำนวนมากแล้วก็ไม่มีอะไรทำงาน เมื่อฉันดู. git / refs / stash SHA ก็อยู่ในนั้น อาจมีปัญหากับการทำเครื่องหมายไดรฟ์เครือข่าย Windows สำหรับการซิงค์ออฟไลน์หรือไม่ 🤷‍♂️
บาทหลวง

คำตอบ:


2785

เมื่อคุณรู้ว่าแฮชของการคอมมิทกระทำคุณตกหล่นคุณสามารถใช้มันเป็นที่ซ่อน

git stash apply $stash_hash

หรือคุณสามารถสร้างสาขาแยกได้ด้วย

git branch recovered $stash_hash

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

ค้นหาความยุ่งเหยิง

หากคุณเพิ่งผุดขึ้นมาและเทอร์มินัลยังคงเปิดอยู่คุณจะยังคงมีค่าแฮชที่พิมพ์git stash popบนหน้าจอ (ขอบคุณ Dolda)

มิฉะนั้นคุณสามารถค้นหาโดยใช้สิ่งนี้สำหรับ Linux, Unix หรือ Git Bash สำหรับ Windows:

git fsck --no-reflog | awk '/dangling commit/ {print $3}'

... หรือใช้ Powershell สำหรับ Windows:

git fsck --no-reflog | select-string 'dangling commit' | foreach { $bits = $_ -split ' '; echo $bits[2];}

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

วิธีที่ง่ายที่สุดในการค้นหาที่เก็บข้อมูลที่คุณต้องการน่าจะผ่านรายการนั้นไปที่gitk:

gitk --all $( git fsck --no-reflog | awk '/dangling commit/ {print $3}' )

... หรือดูคำตอบจาก emraginsหากใช้ Powershell สำหรับ Windows

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

คุณสามารถแทนที่gitkด้วยสิ่งที่ชอบgit log --graph --oneline --decorateถ้าคุณต้องการกราฟที่ดีบนคอนโซลมากกว่าแอพ GUI แยก

ในการมองหาคอมมิชชันให้มองหาการส่งข้อความของแบบฟอร์มนี้:

        WIP ในsomebranch : commithash บางเก่ากระทำข้อความ

หมายเหตุ : ผู้กระทำข้อความเท่านั้นที่จะเป็นในรูปแบบนี้ (เริ่มต้นด้วย "WIP บน") git stashถ้าคุณไม่ได้จัดหาข้อความเมื่อคุณทำ


49
Jaydel เอาคำพูดออกมาจากปากของฉัน โพสต์นี้บันทึกงานของฉัน :) ฉันต้องการเพิ่ม - การจดจำวันที่คุณทำงานในสิ่งที่คุณทำหายไปทำให้การเรียกดู gitk ง่ายขึ้นสำหรับสิ่งที่คุณกำลังมองหา
Sridhar Sarnobat

4
@Codey: เพราะ PowerShell ฉันไม่รู้ว่า MsysGit จัดส่งเป็นไบนารี AWK หรือไม่ Googling บอกฉันสิ่งที่ชอบ%{ $_.Split(' ')[2]; }ที่ควรทำเทียบเท่าของ{print $3}ในการที่awkคำสั่งใน PowerShell แต่ฉันไม่ได้มีการใช้ระบบปฏิบัติการ Windows ในการทดสอบนั้นและคุณยังคงต้องเทียบเท่าสำหรับ/dangling commit/ส่วนหนึ่ง อย่างไรก็ตามเพียงแค่เรียกใช้git fsck --no-reflogและดูผลลัพธ์ คุณต้องการแฮชจากบรรทัด“ dangling commit <commitID>”
อริสโตเติล Pagaltzis

7
เป็นมูลค่าการกล่าวขวัญว่าข้อความกระทำจะมีสตริง "WIP" หากคุณไม่ได้ให้ข้อความของคุณเองเมื่อ stashing (เช่นโดยการทำgit stash save "<message>")
กลั้ว Aguiar

12
ถ้าคุณรู้ว่าเมื่อลดลงที่เกิดขึ้นคุณสามารถใช้นี้หนึ่งซับที่จะได้รับรายชื่อของห้อยกระทำตามเวลาที่เพิ่มขึ้น: รายการสุดท้ายน่าจะเป็นหนึ่งที่คุณต้องการgit fsck --no-reflog | awk '/dangling commit/ {print $3}' | xargs -L 1 git --no-pager show -s --format="%ci %H" | sort stash apply
ris8_allo_zen0

3
git stash apply {ref}กู้คืนการสะสมที่ลดลง! gitมันยอดเยี่ยมมากมันควรผิดกฎหมาย!
Tom Russell

707

หากคุณไม่ได้ปิดเทอร์มินัลให้ดูที่เอาต์พุตจากgit stash popและคุณจะมี ID วัตถุของที่เก็บที่หลุด ปกติแล้วจะมีลักษณะเช่นนี้:

$ git stash pop
[...]
Dropped refs/stash@{0} (2ca03e22256be97f9e40f08e6d6773c7d41dbfd1)

(โปรดทราบว่าgit stash dropจะสร้างบรรทัดเดียวกันด้วย)

เพื่อให้ได้ข้อมูลนั้นกลับมาเพียงแค่เรียกใช้git branch tmp 2cae03eและคุณจะได้รับเป็นสาขา หากต้องการแปลงเป็น stash ให้รัน:

git stash apply tmp
git stash

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


54
คุณสามารถทำเช่นgit stash apply commitidนั้นgit stashเพื่อรับที่ซ่อนใหม่
Matthew Flaschen

32
โปรดทราบว่าหากคอมไพล์ผสานการซ่อนและมีข้อขัดแย้งโดยอัตโนมัติจะไม่แสดงการแฮช
James

31
@James: ถ้าเป็นเช่นนั้นอีกถ้าความขัดแย้งเหล่านั้นเป็นผลมาจากการทำงานgit stash popมันจะไม่ลดลงอย่างใดอย่างหนึ่งดังนั้นจึงไม่เป็นปัญหา
Dolda2000

2
ไม่มี SHA ในเอาต์พุต git stash pop ของฉัน :(
ทิ้งบัญชีตั้งแต่

2
@Honey: git stash popนั่นเป็นจุด หากคุณต้องการที่จะใช้ซ่อนโดยไม่ต้องวางมันใช้git stash applyแทน นอกจากนี้หากคุณต้องการใช้การเปลี่ยนแปลงกับสาขาหลายแห่งคุณสามารถเลือกรับเชอร์รี่แทนได้
Dolda2000

271

แค่อยากจะพูดถึงนอกจากนี้ในการแก้ปัญหาที่ยอมรับได้ ไม่เห็นได้ชัดสำหรับฉันในครั้งแรกที่ฉันลองใช้วิธีนี้ (อาจเป็นไปได้) แต่เมื่อต้องการใช้การซ่อนจากค่าแฮชให้ใช้ "git stash Apply":

$ git stash apply ad38abbf76e26c803b27a6079348192d32f52219

เมื่อฉันยังใหม่กับ git นี่ก็ไม่ชัดเจนสำหรับฉันและฉันกำลังลองชุด "git show", "git Apply", "patch" ฯลฯ


3
โปรดทราบว่าสิ่งนี้ใช้ (duh!) ที่ซ่อนในแผนผังการทำงานปัจจุบัน หากต้นไม้สกปรกคุณอาจต้องการใช้สาขาชั่วคราวหรือที่เก็บข้อมูลก่อนอื่นให้ใช้ที่เก็บจาก SHA-1, ที่เก็บข้อมูลอีกครั้งและจากนั้นเปิดที่ที่สองที่ซ่อนสุดท้าย (เรียกว่า stash @ {1})
musiKk

111

ในการรับรายการของการซ่อนที่ยังอยู่ในที่เก็บของคุณ แต่ไม่สามารถเข้าถึงได้อีก:

git fsck --unreachable | grep commit | cut -d" " -f3 | xargs git log --merges --no-walk --grep=WIP

ถ้าคุณให้ชื่อเพื่อซ่อนของคุณแทน "WIP" ในตอนท้ายของคำสั่งที่มีส่วนหนึ่งของข้อความของคุณเช่น-grep=WIP-grep=Tesselation

คำสั่ง grepping สำหรับ "WIP" เนื่องจากข้อความคอมมิทเริ่มต้นสำหรับการซ่อนอยู่ในรูปแบบ WIP on mybranch: [previous-commit-hash] Message of the previous commit.


1
echo 'git fsck - ไม่สามารถเข้าถึงได้ | grep commit | ตัด -d "" -f3 | xargs git log --merge - no-walk --grep = WIP '> / usr / local / bin / git-stashlog; chmod a + rx / usr / local / bin / git-stashlog # git stashlog
Erik Martino

หรือคุณสามารถเพิ่มสิ่งนี้ลงใน. gitconfig ของคุณเป็นนามแฝง (นำหน้าคำสั่งด้วย a !)
asmeurer

บันทึกเบคอนของฉัน - ไม่จริง แต่บันทึกฉันอีกครั้งการเข้ารหัสงานวัน - ชื่นชม - เนื่องจากที่ฉันเพิ่งลดลงเมื่อเร็ว ๆ นี้ฉันเพิ่งเลือก SHA ยอดนิยมจากผลลัพธ์ของคำสั่งของคุณ - แล้ว .... git stash ใช้ SHA ... ตามที่กล่าวไว้ในคำตอบอื่น ๆ - ขอบคุณมาก
danday74

75

ฉันเพิ่งสร้างคำสั่งที่ช่วยให้ฉันพบการสูญหายที่สะสมไว้:

for ref in `find .git/objects | sed -e 's#.git/objects/##' | grep / | tr -d /`; do if [ `git cat-file -t $ref` = "commit" ]; then git show --summary $ref; fi; done | less

สิ่งนี้จะแสดงรายการวัตถุทั้งหมดในต้นไม้. git / objects หาวัตถุที่เป็นชนิดของการกระทำจากนั้นจะแสดงข้อมูลสรุปของแต่ละวัตถุ จากจุดนี้มันเป็นเพียงเรื่องของการมองผ่านความมุ่งมั่นที่จะหา "งานระหว่างทำที่เหมาะสม: 6a9bb2" ("งาน" เป็นสาขาของฉัน 619bb2 เป็นความมุ่งมั่นที่ผ่านมา)

ฉันทราบว่าถ้าฉันใช้ "git stash Apply" แทน "git stash pop" ฉันจะไม่มีปัญหานี้และถ้าฉันใช้ "git stash save message " แล้วการกระทำอาจหาง่ายกว่า

อัปเดต: ด้วยความคิดของนาธานสิ่งนี้จะสั้นลง:

for ref in `git fsck --unreachable | grep commit | cut -d' ' -f3`; do git show --summary $ref; done | less

41

git fsck --unreachable | grep commitควรแสดง sha1 แม้ว่ารายการที่ส่งคืนอาจมีขนาดค่อนข้างใหญ่ git show <sha1>จะแสดงว่าเป็นการกระทำที่คุณต้องการหรือไม่

git cherry-pick -m 1 <sha1> จะผสานกระทำไปยังสาขาในปัจจุบัน


37

Windows PowerShell ที่เทียบเท่าโดยใช้ gitk:

gitk --all $(git fsck --no-reflog | Select-String "(dangling commit )(.*)" | %{ $_.Line.Split(' ')[2] })

อาจมีวิธีที่มีประสิทธิภาพมากขึ้นในการทำเช่นนี้ในไปป์เดียว แต่ก็ใช้งานได้


1
ฉันขอบคุณมากสำหรับคำตอบของคุณ
ВиталийШебаниц

32

หากคุณต้องการที่จะเก็บสะสมที่หายไปคุณจะต้องค้นหาที่ซ่อนของที่เก็บของที่หายไปก่อน

ในฐานะที่อริสโตเติล Pagaltzis แนะนำgit fsckควรช่วยคุณ

ส่วนตัวฉันใช้log-allนามแฝงของฉันซึ่งแสดงให้ฉันทุกคนกระทำ (กู้คืนได้กระทำ) เพื่อให้มีมุมมองที่ดีขึ้นของสถานการณ์:

git log --graph --decorate --pretty=oneline --abbrev-commit --all $(git fsck --no-reflogs | grep commit | cut -d' ' -f3)

คุณสามารถค้นหาได้เร็วยิ่งขึ้นหากคุณมองหาเฉพาะข้อความ "WIP on"

เมื่อคุณรู้จัก sha1 ของคุณคุณเพียงแค่เปลี่ยนการอ้างอิงที่เก็บของคุณเพื่อเพิ่มที่เก็บเก่า:

git update-ref refs/stash ed6721d

คุณอาจต้องการที่จะมีข้อความที่เกี่ยวข้องดังนั้น -m

git update-ref -m "$(git log -1 --pretty=format:'%s' ed6721d)" refs/stash ed6721d

และคุณยังต้องการใช้สิ่งนี้เป็นนามแฝง:

restash = !git update-ref -m $(git log -1 --pretty=format:'%s' $1) refs/stash $1

2
อย่างไรก็ตามสิ่งที่-d\\ ควรจะเป็น-d\ (หรือชัดเจนยิ่งขึ้น-d' ')
joeytwiddle

มีข้อผิดพลาด: "ร้ายแรง: อาร์กิวเมนต์ที่คลุมเครือ 'dangling': การแก้ไขที่ไม่รู้จักหรือเส้นทางที่ไม่ได้อยู่ในแผนผังการทำงาน"
Daniel Ryan

คุณต้องgit update-ref -m "$(git log -1 --pretty=format:'%s' ed6721d)" refs/stash ed6721
ล้อม

18

ฉันชอบแนวทางของอริสโตเติล แต่ไม่ชอบใช้ GITK ... เพราะฉันคุ้นเคยกับการใช้ GIT จากบรรทัดคำสั่ง

แต่ฉันเอา dangling คอมมิทและเอาท์พุทรหัสไปที่ไฟล์ DIFF เพื่อตรวจสอบในเครื่องมือแก้ไขโค้ดของฉัน

git show $( git fsck --no-reflog | awk '/dangling commit/ {print $3}' ) > ~/stash_recovery.diff

ตอนนี้คุณสามารถโหลดไฟล์ diff / txt ที่เกิดขึ้น (ในโฟลเดอร์โฮมของคุณ) ลงในเครื่องมือแก้ไข txt ของคุณแล้วดูรหัสจริงและ SHA

จากนั้นก็ใช้

git stash apply ad38abbf76e26c803b27a6079348192d32f52219

17

คุณสามารถแสดงรายการคอมมิทที่ไม่สามารถเข้าถึงได้ทั้งหมดโดยการเขียนคำสั่งนี้ในเทอร์มินัล -

git fsck --unreachable

ตรวจสอบแฮชคอมมิทที่ไม่สามารถเข้าถึงได้ -

git show hash

สุดท้ายใช้หากคุณพบรายการที่ถูกเก็บ -

git stash apply hash

15

ทำไมผู้คนถึงถามคำถามนี้ เพราะพวกเขายังไม่รู้หรือเข้าใจ reflog

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

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


1
สวัสดี Robby สิ่งนี้มีความเกี่ยวข้องหากคุณกำลังทำงานได้รับการติดตามด้านข้างและจำเป็นต้องรับข้อมูลที่คุณทิ้งไว้เมื่อสองสามสัปดาห์ก่อนเท่านั้นเพื่อเรียนรู้ว่าคุณไม่สามารถหางานที่ถูกเก็บซ่อนได้ - มันอาจจะหายไปจากที่อื่น กำลังทำ. reflog นั้นยอดเยี่ยมถ้ามันเป็นประวัติศาสตร์เมื่อไม่นานมานี้
emragins

1
เฮ้ emragins ฉันเห็นด้วย แต่นี่เป็นกรณีการใช้งานของ OP อย่างแน่นอน ฉันไม่รู้แน่ชัดว่าคำสั่งอื่น ๆ ที่โพสต์ที่นี่จะทำงานได้อย่างไร แต่ geuss ของฉันก็คือพวกเขาจะหยุดทำงานเมื่อการอ้างอิงที่เขาได้ทำไว้ถูกทำความสะอาด
RobbyD

1
อืม ... สถานการณ์ด้านบนเป็นสิ่งที่นำฉันมาที่คำถามนี้และฉันรู้ว่าอย่างน้อยสองสามสัปดาห์ถ้าไม่ได้ใกล้เดือนมากกว่าระหว่างที่ฉัน (ไม่รู้ตัว) สูญเสียที่ซ่อนของฉันและเมื่อฉันสามารถกู้คืนได้
emragins

15

ใน OSX ด้วย git v2.6.4 ฉันเพิ่งรัน git stash drop โดยไม่ตั้งใจแล้วฉันก็พบว่ามันทำตามขั้นตอนด้านล่าง

หากคุณรู้ชื่อของที่เก็บสะสมให้ใช้:

$ git fsck --unreachable | grep commit | cut -c 20- | xargs git show | grep -B 6 -A 2 <name of the stash>

มิฉะนั้นคุณจะพบ ID จากผลลัพธ์ด้วยตนเองด้วย:

$ git fsck --unreachable | grep commit | cut -c 20- | xargs git show

จากนั้นเมื่อคุณพบ commit-id เพียงกด git stash จะใช้ {commit-id}

หวังว่าจะช่วยให้ใครบางคนได้อย่างรวดเร็ว


12

ฉันต้องการเพิ่มวิธีการแก้ปัญหาที่ยอมรับได้อีกวิธีที่ดีในการผ่านการเปลี่ยนแปลงทั้งหมดเมื่อคุณไม่ได้มี gitk หรือไม่มี X สำหรับการส่งออก

git fsck --no-reflog | awk '/dangling commit/ {print $3}' > tmp_commits

for h in `cat tmp_commits`; do git show $h | less; done

จากนั้นคุณจะได้รับความแตกต่างทั้งหมดสำหรับแฮชเหล่านั้นที่แสดงทีละอัน กด 'q' เพื่อไปยังส่วนต่างถัดไป


12

ฉันไม่สามารถรับคำตอบใด ๆ ในการทำงานบน Windows ในหน้าต่างคำสั่งแบบง่าย (Windows 7 ในกรณีของฉัน) awk, grepและSelect-stringไม่ได้รับการยอมรับว่าเป็นคำสั่ง ดังนั้นฉันจึงลองวิธีอื่น:

  • วิ่งครั้งแรก: git fsck --unreachable | findstr "commit"
  • คัดลอกผลลัพธ์ไปยัง notepad
  • ค้นหาแทนที่ "ไม่สามารถเข้าถึงกระทำได้" ด้วย start cmd /k git show

จะมีลักษณะเช่นนี้:

start cmd /k git show 8506d235f935b92df65d58e7d75e9441220537a4 start cmd /k git show 44078733e1b36962571019126243782421fcd8ae start cmd /k git show ec09069ec893db4ec1901f94eefc8dc606b1dbf1 start cmd /k git show d00aab9198e8b81d052d90720165e48b287c302e

  • บันทึกเป็นไฟล์. bat และเรียกใช้
  • สคริปต์จะเปิดหน้าต่างคำสั่งจำนวนมากเพื่อแสดงการกระทำแต่ละอย่าง
  • หากคุณพบสิ่งที่คุณกำลังมองหาเรียกใช้: git stash apply (your hash)

อาจไม่ใช่วิธีที่ดีที่สุด แต่ใช้ได้สำหรับฉัน


คุณสามารถใช้ git bash แม้กระทั่งบน Windows ในทุบตี git คุณมีเครื่องมือบรรทัดคำสั่ง (unixoid) ทั้งหมดที่คุณต้องการ
เอเดรียน W

10

คำตอบที่ได้รับการยอมรับจาก Aristotle จะแสดงข้อผูกพันที่เข้าถึงได้ทั้งหมดรวมถึงข้อผูกพันที่ไม่เหมือนที่สะสม วิธีกรองสัญญาณรบกวน:

git fsck --no-reflog | \
awk '/dangling commit/ {print $3}' | \
xargs git log --no-walk --format="%H" \
  --grep="WIP on" --min-parents=3 --max-parents=3

ซึ่งจะรวมเฉพาะการกระทำที่มีการกระทำหลัก 3 รายการ (ซึ่งจะมีที่เก็บ) และมีข้อความว่า "WIP เปิด"

โปรดทราบว่าหากคุณบันทึกที่เก็บของคุณด้วยข้อความ (เช่นgit stash save "My newly created stash") สิ่งนี้จะแทนที่ข้อความ "WIP on ... "

คุณสามารถแสดงข้อมูลเพิ่มเติมเกี่ยวกับการส่งแต่ละครั้งเช่นแสดงข้อความการส่งหรือส่งไปที่git stash show:

git fsck --no-reflog | \
awk '/dangling commit/ {print $3}' | \
xargs git log --no-walk --format="%H" \
  --grep="WIP on" --min-parents=3 --max-parents=3 | \
xargs -n1 -I '{}' bash -c "\
  git log -1 --format=medium --color=always '{}'; echo; \
  git stash show --color=always '{}'; echo; echo" | \
less -R

6

สิ่งที่ฉันชอบคือหนึ่งในสายการบิน:

git log --oneline  $( git fsck --no-reflogs | awk '/dangling commit/ {print $3}' )

นี่เป็นแนวคิดเดียวกันกับคำตอบนี้แต่สั้นกว่ามาก แน่นอนคุณยังสามารถเพิ่ม--graphเพื่อรับการแสดงผลเหมือนต้นไม้

เมื่อคุณพบคำมั่นสัญญาในรายการแล้ว

git stash apply THE_COMMIT_HASH_FOUND

สำหรับฉันแล้วการใช้--no-reflogsไม่เปิดเผยรายการที่เก็บที่หายไป แต่--unreachable(ตามที่พบในคำตอบอื่น ๆ ) ไม่ได้

รันบน git bash เมื่อคุณใช้ Windows

เครดิต: รายละเอียดของคำสั่งดังกล่าวมาจากhttps://gist.github.com/joseluisq/7f0f1402f05c45bac10814a9e38f81bf


5

กู้คืนได้โดยใช้ขั้นตอนต่อไปนี้:

  1. ระบุรหัสแฮชที่ลบ:

    gitk - ทั้งหมด $ (git fsck - ไม่ - reflog | awk '/ ห้อยกระทำ / {พิมพ์ $ 3}')

  2. Cherry Pick the Stash:

    git cherry-pick -m 1 $ stash_hash_code

  3. แก้ไขข้อขัดแย้งหากใช้:

    คอมไพล์ mergetool

นอกจากนี้คุณอาจมีปัญหากับข้อความยืนยันหากคุณใช้ gerrit โปรดสะสมการเปลี่ยนแปลงของคุณก่อนที่จะติดตามทางเลือกถัดไป:

  1. ใช้ฮาร์ดรีเซ็ตเป็นคอมมิชชันก่อนหน้าจากนั้นแนะนำการเปลี่ยนแปลงนี้
  2. นอกจากนี้คุณยังสามารถซ่อนการเปลี่ยนแปลงรีบูตและการแนะนำ

@ miva2 การแก้ไขของคุณลบลิงก์ไปยังคำตอบที่ถูกต้องที่สุดในคำถามนี้ การเพิ่มลิงค์กลับในข้อคิดเห็นstackoverflow.com/questions/89332/…
Abhijeet

4

สิ่งที่ฉันมาที่นี่กำลังมองหาคือวิธีการซ่อนตัวจริง ๆ โดยไม่คำนึงถึงสิ่งที่ฉันได้เช็คเอาท์ โดยเฉพาะอย่างยิ่งฉันทำอะไรบางอย่างแล้วตรวจสอบรุ่นที่เก่ากว่าแล้วเปิดมัน แต่ที่ซ่อนคือไม่มี op ที่จุดเวลาก่อนหน้านี้ดังนั้นสะสมจึงหายไป; ฉันไม่git stashสามารถผลักมันกลับไปที่กองซ้อนได้ สิ่งนี้ใช้ได้กับฉัน:

$ git checkout somethingOld
$ git stash pop
...
nothing added to commit but untracked files present (use "git add" to track)
Dropped refs/stash@{0} (27f6bd8ba3c4a34f134e12fe69bf69c192f71179)
$ git checkout 27f6bd8ba3c
$ git reset HEAD^    # Make the working tree differ from the parent.
$ git stash # Put the stash back in the stack.
Saved working directory and index state WIP on (no branch): c2be516 Some message.
HEAD is now at c2be516 Some message.
$ git checkout somethingOld # Now we are back where we were.

ในการหวนกลับฉันควรจะได้รับการใช้ไม่ได้git stash apply git stash popฉันกำลังทำbisectและมีแพตช์เล็ก ๆ น้อย ๆ ที่ฉันต้องการใช้ในทุกbisectขั้นตอน ตอนนี้ฉันกำลังทำสิ่งนี้:

$ git reset --hard; git bisect good; git stash apply
$ # Run tests
$ git reset --hard; git bisect bad; git stash apply
etc.

นี่คือคำตอบหรือความต่อเนื่องของคำถาม?
Alex Brown

บิตของทั้งสอง ฉันพบหน้านี้เพราะฉันสูญเสียการสะสมและพยายามคืนมัน กรณีการใช้งานสำหรับฉันกำลังทำการแบ่งส่วนที่ฉันต้องการใช้การเปลี่ยนแปลงก่อนการทดสอบในแต่ละขั้นตอน ผมได้เรียนรู้วิธีที่ยากที่คุณไม่สามารถเพียง pop ทดสอบซ่อน, stash applyแบ่งครึ่งเพราะที่สามารถแสดงความแตกต่างกันในการกระทำที่ซ่อนจึง
Ben
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.