รับรายการคอมไพล์ทั้งหมดรวมถึงรายการที่ 'เสียไป'


153

สมมติว่าฉันมีกราฟดังนี้:

A---B---C---D (master)
     \
      \-E---F (HEAD)

ถ้าฉันทำgit log --all --onelineฉันจะได้รับค่าคอมมิชชั่นทั้งหกอย่าง

แต่ถ้าเป็นกราฟ

A---B---C---D (master, HEAD)
     \
      \-E---F

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

ขอบคุณ

คำตอบ:


65

ไม่ง่ายอย่างยิ่งหากคุณทำเข็มชี้ไปที่ปลายกิ่งไม้หายไปก็เหมือนกับการหาเข็มในกองหญ้า คุณสามารถค้นหาการกระทำทั้งหมดที่ดูเหมือนจะไม่มีการอ้างอิงอีกต่อไป - git fsck --unreachableจะทำเพื่อคุณ - แต่จะรวมถึงความมุ่งมั่นที่คุณทิ้งไปหลังจากการgit commit --amendกระทำครั้งเก่ากับสาขาที่คุณลดลง ฯลฯ เป็นต้นดังนั้นการเห็นการกระทำทั้งหมดเหล่านี้ ในครั้งเดียวมีแนวโน้มที่จะมีข้อมูลมากเกินไปที่จะลุย

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


7
+1: ไม่มีความแตกต่างอย่างแน่นอนระหว่างการกระทำโดยเจตนาเป็นเด็กกำพร้าโดยcommit --amendหรือrebaseกับผู้ที่ถูกทอดทิ้งโดยบังเอิญโดยการทำงานกับ HEAD ที่แยกออกมาพูด
Cascabel

3
แน่นอน วิธีที่ง่ายที่สุดในการกู้คืนจากสถานการณ์นั้นคือการดูที่ reflog สำหรับ HEAD
araqnid

@Jefromi: จุดที่ยอดเยี่ยมเกี่ยวกับการgit commit --amendออกจากทางตันและการกระทำที่สูญหาย ฉันได้ทำการซ่อมแซมบางอย่างและอะไรก็ตามและลงเอยด้วยการกระทำบางอย่างที่ไม่สามารถเข้าถึงได้จากสาขาใด ๆ และรู้สึกสกปรกเล็กน้อยที่ทิ้งไว้ใน repo ตอนนี้ความคิดไม่สงบอีกต่อไป :)
Emil Lundberg

2
@araqnid ฉันมีของดองแบบเดียวกับโปสเตอร์ต้นฉบับและคำแนะนำของคุณในการดู reflog เป็นเพียงสิ่งที่ต้องทำ
Ignazio

8
ผมเห็นด้วยกับคำตอบนี้ แต่ในกรณีที่คนไม่จำเป็นต้องเห็นกระทำทั้งหมดรวมทั้งคนกำพร้าไม่ว่าจะโดยเจตนาหรือตั้งใจ git fsck --unreachableไม่ได้ให้การว่า ผมเพิ่งลองทำ วิธีการที่ดีขึ้นเป็น--reflogตัวเลือกสำหรับการgit logเป็นkenorb ตอบ สิ่งที่ดีอย่างยิ่งเกี่ยวกับเรื่องนี้คือเมื่อรวมกับ--graphคุณจะสามารถแยกวิเคราะห์บริบทภาพได้ง่ายเหมือนกับที่แสดงในคำถามเดิม ตัวอย่างเช่นลอง:git log --graph --all --oneline --reflog
Inigo

124

ลอง:

git log --reflog

ซึ่งรายการกระทำคอมไพล์โดยแสร้งทำเป็นว่าวัตถุทั้งหมดที่กล่าวถึงโดย reflogs ( git reflog) <commit>มีการระบุไว้ในบรรทัดคำสั่งเป็น


1
นี่คือสิ่งที่ฉันกำลังมองหา - การทำงานของอาร์กิวเมนต์ --reflog
ความผิดปกติ

3
Btw, gitk ยังรองรับ: gitk --reflog
ald.li

2
พิมพ์qเพื่อออกจากบันทึกคอมไพล์
Nuryagdy Mustapayev

ข้อความนี้ยังแสดงการกระทำในพื้นที่ "สูญหาย" เมื่อทำสิ่งgit reset origin/branchที่ไม่สามารถเข้าถึงได้จริงเพียง แต่ไม่แสดงในบันทึกอีกต่อไป
Sami Kuhmonen

52

เมื่อฉันแก้ไขปัญหานี้ฉันใช้คำสั่งต่อไปนี้:

git reflog |  awk '{ print $1 }' | xargs gitk

สิ่งนี้ช่วยให้ฉันเห็นภาพการกระทำล่าสุดซึ่งกลายเป็นเรื่องไร้หัว

~/bin/git-reflog-gitkฉันได้นี้ห่อขึ้นในผู้ช่วยสคริปต์ที่เรียกว่า


2
แค่นี้ก็ช่วยฉันได้ครั้งใหญ่แล้ว ... ขอบคุณ!
Bret Royster

นี่มันเจ๋งมาก! ขอบคุณ! มันทำให้เห็นส่วนสำคัญของต้นไม้จริงๆ
Mladen B.

เพียงเคล็ดลับ: สิ่งนี้จะใช้ได้กับงานในพื้นที่ของคุณเป็นบันทึกการwhen the tips of branches and other references were updated in the *local repository*อ้างอิงเท่านั้น คุณอาจต้องการใช้git log --reflogหากคุณต้องการทำสิ่งนี้สำหรับการเปลี่ยนแปลงอ้างอิงที่ไม่ใช่ในท้องถิ่น
กฤษณะคุปตะ

36

สิ่งที่ช่วยชีวิตฉันคือคำสั่งต่อไปนี้:

git reflog

คุณจะพบหน้าจอที่มีประวัติการกระทำเพื่อคอมไพล์แบบนี้:

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

ณ จุดนี้คุณจะต้องค้นหาสิ่งHEAD@{X}ที่คุณต้องการสร้างสาขาชั่วคราวและย้ายไปที่:

git checkout -b temp_branch HEAD@{X}

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

หวังว่านี่จะช่วยได้ ...


27

เช่นเดียวกับคำตอบของ @Kieran แต่สำหรับคอนโซล: git log --oneline --all --graph --decorate $(git reflog | awk '{print $1}')


คุณต้องใส่ส่วนสุดท้าย: $ (git reflog | awk '{print $ 1}') หรือไม่ สิ่งนี้ทำอะไร? หลังจากลองใช้โซลูชันของคุณดูเหมือนว่าจะให้ผลลัพธ์เดียวกันแม้ว่าจะไม่มีส่วนสุดท้ายก็ตาม
wmock

ถ้าคุณย้ายตัวชี้สาขาของคุณและปล่อยให้กระทำบางอย่างโดยไม่ต้องมีการอ้างอิง (เช่น OP ได้) git log --allพวกเขาจะไม่แสดงขึ้นใน ตัวอย่างสั้น ๆ : หลังจากการคอมgit reset --hard @^มิต HEAD @ {0} ของคุณจะอยู่ใน reflog เท่านั้นและเนื่องจากgit reflogไม่สนับสนุนให้--graphคุณส่งคอมมิตgit log --graphเพื่อรับการแสดงภาพ
Florian Fida

5
คุณสามารถใช้--reflogแทนได้ $(git reflog | awk '{print $1}')
Sild

ผมเทียบgit log --oneline --all --graph --decorate $(git reflog | awk '{print $1}')เพื่อgit log --oneline --all --graph --decorate --reflogที่พวกเขากำลังเกือบเหมือนกันยกเว้น --reflog รวมรายละเอียดต่างๆเช่นรายการ WIP
Script Wolf

@FlorianFida แทนreflogทำไมไม่ใช้log --reflogแทน?
Pacerier

9

ฉันจะแก้ปัญหานี้ได้อย่างไร? ใช้git fsckและบันทึก!

ขั้นแรกให้สร้างไฟล์ที่มีคอมมิตและ blobs ที่สูญหาย (ไม่สามารถเข้าถึงได้) (หมายเหตุ: หากคุณทำบางสิ่งบางอย่างเช่นgit gcนั้นขยะจะรวบรวมสิ่งที่พวกเขากระทำทั้งหมดและคุณจะไม่พบที่นี่!)

$git fsck --lost-found > lost_found.commits

ที่ให้ไฟล์แบบนี้:

ห้อยกระทำ dec2c5e72a81ef06963397a49c4b068540fc0dc3
ห้อยหยด f8c2579e6cbfe022f08345fa7553feb08d60a975
ห้อยหยด 0eb3e86dc112332ceadf9bc826c49bd371acc194
ห้อยหยด 11cbd8eba79e01f4fd7f496b1750953146a09502
ห้อยกระทำ 18733e44097d2c7a800650cea442febc5344f9b3
ห้อยหยด 1e53a5cdb3ecdde27081ec6e8b31e4070106ee05

จากนั้นคุณสามารถเปิดไฟล์นี้ด้วยโปรแกรมแก้ไขข้อความที่คุณชื่นชอบเพื่อคัดลอกแฮชคอมมิต / บล็อกจากที่นั่น (* ไอ * มาโครเป็นกลุ่มใช้งานได้ดีสำหรับไอ * นี้)

git log --oneline <commit hash>ตอนนี้คุณสามารถเข้าสู่ระบบกลับมาจากการกระทำนี้กับสิ่งที่ต้องการ อีกวิธีหนึ่งควรใช้ gitk, tig หรือโปรแกรมดู git อื่น ๆ

ในกรณีของคุณหากคุณพบแฮชสำหรับคอมมิต F บันทึกจะแสดงสิ่งนี้ให้คุณ

A---B---E---F

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

ป.ล. ใช่ฉันรู้ว่าโพสต์ช้า แต่ก็ดีใคร ๆ ก็เจอที่นี่และเห็นว่ามีประโยชน์ (ส่วนใหญ่น่าจะเป็นฉันใน 6 เดือนเมื่อฉันใช้ Google อีกครั้ง)


5

ฉันโชคดีในการกู้คืนคอมมิตโดยดูที่ reflog ซึ่งอยู่ที่ .git/logs/HEAD

จากนั้นฉันต้องเลื่อนลงไปที่ส่วนท้ายของไฟล์และฉันพบการกระทำที่ฉันเพิ่งทำหายไป


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

5

git logบางครั้งเราอาจจะไม่ได้รับรายละเอียดการกระทำทั้งหมดดังนั้นหากต้องการดูสิ่งนี้ ...

สำหรับ Mac: เข้าสู่ git project ของคุณแล้วพิมพ์:

$ nano .git/logs/HEAD

เพื่อดูการกระทำของคุณทั้งหมดในสิ่งนั้นหรือ:

$ gedit .git/logs/HEAD

เพื่อดูคุณทำสิ่งนั้นทั้งหมด

จากนั้นคุณสามารถแก้ไขได้ในเบราว์เซอร์ที่คุณชื่นชอบ


3

@bsimmons

git fsck --lost-found | grep commit

จากนั้นสร้างสาขาสำหรับแต่ละสาขา:

$ git fsck --lost-found | grep commit
Checking object directories: 100% (256/256), done.
dangling commit 2806a32af04d1bbd7803fb899071fcf247a2b9b0
dangling commit 6d0e49efd0c1a4b5bea1235c6286f0b64c4c8de1
dangling commit 91ca9b2482a96b20dc31d2af4818d69606a229d4

$ git branch  branch_2806a3 2806a3
$ git branch  branch_6d0e49 6d0e49
$ git branch  branch_91ca9b 91ca9b

ตอนนี้เครื่องมือมากมายจะแสดงให้คุณเห็นภาพกราฟิกของการกระทำที่สูญหายเหล่านั้น


3
git log --reflog

ช่วยฉันด้วย! ฉันทำหายในขณะที่รวม HEAD และไม่พบการกระทำของฉัน! ไม่แสดงในแผนผังแหล่งที่มา แต่git log --reflogแสดงการกระทำในพื้นที่ของฉัน


2

หากคุณใช้ Git Extensions GUI จะสามารถแสดงภาพกราฟิกของการคอมมิทแบบห้อยหากคุณเลือก "ดู -> แสดงการอ้างอิงอ้างอิง" สิ่งนี้จะแสดงการผูกมัดที่ห้อยอยู่ในต้นไม้เช่นเดียวกับการอ้างอิงอื่น ๆ ทั้งหมด วิธีนี้เป็นวิธีที่ง่ายกว่าในการค้นหาสิ่งที่คุณกำลังมองหา

ดูภาพนี้เพื่อสาธิต กำหนดให้ C2, C3, C4 และ C5 บนรูปภาพห้อยลง แต่ยังมองเห็นได้

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