ความแตกต่างระหว่างการอ้างอิง git และการบันทึกคืออะไร?


158

หน้าคนบอกว่าบันทึกนั้นแสดงบันทึกการกระทำและ reflog จัดการข้อมูล reflog ข้อมูล reflog คืออะไรและมีบันทึกอะไรบ้าง บันทึกดูเหมือนว่าจะมีรายละเอียดมากกว่านี้

คำตอบ:


221

git logแสดง HEAD ปัจจุบันและบรรพบุรุษของมัน นั่นคือมันพิมพ์พ้อยท์ HEAD points ไปที่จากนั้นพาเรนต์พาเรนต์เป็นต้น มันย้อนกลับไปยังบรรพบุรุษของ repo โดยค้นหาผู้ปกครองของแต่ละกระทำซ้ำ ๆ

(ในทางปฏิบัติคอมมิชชันบางรายการมีพาเรนต์มากกว่าหนึ่งพาเรนต์หากต้องการดูบันทึกการทำงานเพิ่มเติมให้ใช้คำสั่งเช่นgit log --oneline --graph --decorate)

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

นอกเหนือจาก: การทำความเข้าใจ reflog หมายความว่าคุณจะไม่สามารถสูญเสียข้อมูลจาก repo ของคุณได้จริง ๆ เมื่อมีการส่งข้อมูลแล้ว หากคุณรีเซ็ตการกระทำที่เก่ากว่าโดยไม่ตั้งใจหรือปฏิเสธอย่างไม่ตั้งใจหรือการดำเนินการอื่น ๆ ที่ "ลบ" การกระทำด้วยสายตาคุณสามารถใช้ reflog เพื่อดูว่าคุณอยู่ที่ไหนมาก่อนและgit reset --hardกลับไปที่สถานะอ้างอิงก่อนหน้า โปรดจำไว้ว่าการอ้างอิงไม่ได้หมายถึงเพียงการกระทำ แต่ประวัติศาสตร์ทั้งหมดที่อยู่เบื้องหลัง


26
คำเตือน: บางครั้งคุณอาจสูญเสียข้อมูลได้เนื่องจากรายการ reflog ไม่คงอยู่ชั่วนิรันดร์ข้อมูลเหล่านั้นจะถูกล้างตามเงื่อนไขบางประการ ดูคำตอบนี้และเอกสารสำหรับ-git reflogและGit-GC โดยทั่วไปหากการดำเนินการทำลายไม่เกิน 2 สัปดาห์ที่ผ่านมาคุณอาจปลอดภัยที่สุด
mcmlxxxvi

@mcmlxxxvi ฉันมีสองโฟลเดอร์ในเครื่องสำหรับ repo เดียวกันฉันสามารถรวม reflogs สำหรับสองโฟลเดอร์ได้หรือไม่
Tmx

@Tmx ผมไม่เข้าใจกรณีของคุณ - สิ่งที่คุณหมายถึงโฟลเดอร์ภายในสอง repo เดียวกัน ? หากคุณมีสองโคลนของธุรกรรมซื้อคืนเดียวกันซึ่งมีถึงวันที่และคุณต้องการที่จะ "ผสาน" ประวัติการแก้ไขของพวกเขา, รายการที่มีรูปแบบ.git/logs/refs/<branch> <old_rev> <new_rev> [...] <timestamp> [...]คุณสามารถลองเรียงต่อกันและเรียงลำดับตามการประทับเวลา อย่างไรก็ตามบางบรรทัดnew_revอาจไม่ตรงกับบรรทัดถัดไปold_revซึ่งในกรณีนี้ฉันสงสัยว่าการอ้างถึงจะไม่ถูกต้อง จากนั้นคุณสามารถลองแทรกรายการปลอมเพื่อ "แก้ไข" ลำดับ แต่ดูเหมือนจะยุ่งยากเกินไปสำหรับฉัน
mcmlxxxvi

62
  • git log แสดงบันทึกการกระทำที่สามารถเข้าถึงได้จากการอ้างอิง (หัวแท็กรีโมท)
  • git reflogเป็นบันทึกการกระทำทั้งหมดที่อ้างอิงหรืออ้างอิงใน repo ของคุณได้ตลอดเวลา

นั่นคือเหตุผลที่git reflog(ใช้การบันทึกแบบท้องถิ่นซึ่งตัดหลังจาก 90 วันโดยค่าเริ่มต้น) จะใช้เมื่อคุณทำการ "ทำลาย" (เช่นการลบสาขา) เพื่อกลับ SHA1 ที่อ้างอิงจากสาขานั้น
ดูgit config:

gc.reflogexpire
gc.<pattern>.reflogexpire

git reflogหมดอายุลบรายการ reflog ที่เก่ากว่าเวลานี้ ค่าเริ่มต้นถึง 90 วัน
ด้วย " <pattern>" (เช่น " refs/stash") ในช่วงกลางการตั้งค่าที่ใช้เฉพาะกับ refs <pattern>ที่ตรงกับ

ตาข่ายนิรภัย

git reflogมักจะอ้างอิงว่า " เครือข่ายความปลอดภัยของคุณ "

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

" รักษาความสงบและใช้git reflog "

ใจเย็น

อีกครั้งการอ้างอิงคือการบันทึก SHA1 ในเครื่องของคุณ
เมื่อเทียบกับgit log: ถ้าคุณผลักดัน repo ของคุณไปยังrepo ต้นน้ำคุณจะเห็นเหมือนกันแต่ไม่จำเป็นต้องเหมือนกันgit loggit reflog


14

นี่คือคำอธิบายของreflogหนังสือ Pro Git :

สิ่งหนึ่งที่ Git ทำในพื้นหลังในขณะที่คุณกำลังออกกำลังกายอยู่นั้นคือการอ้างอิงใหม่ - บันทึกการที่การอ้างอิง HEAD และสาขาของคุณในช่วงสองสามเดือนที่ผ่านมา

คุณสามารถดู reflog ของคุณโดยใช้git reflog:

$ git reflog
734713b... HEAD@{0}: commit: fixed refs handling, added gc auto, updated
d921970... HEAD@{1}: merge phedders/rdocs: Merge made by recursive.
1c002dd... HEAD@{2}: commit: added some blame and merge stuff
1c36188... HEAD@{3}: rebase -i (squash): updating HEAD
95df984... HEAD@{4}: commit: # This is a combination of two commits.
1c36188... HEAD@{5}: rebase -i (squash): updating HEAD
7e05da5... HEAD@{6}: rebase -i (pick): updating HEAD

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

reflogคำสั่งนอกจากนี้ยังสามารถใช้ในการลบรายการหรือหมดอายุรายการจาก reflog ที่เก่าเกินไป จากเอกสาร Linux Kernel Git อย่างเป็นทางการสำหรับreflog :

คำสั่งย่อยexpireถูกใช้เพื่อตัดรายการ reflog ที่เก่ากว่า

ในการลบรายการเดียวจาก reflog ใช้คำสั่งย่อยdeleteและระบุรายการที่แน่นอน (เช่นgit reflog delete master@{2})


แต่ไม่ได้git logให้ข้อมูลเดียวกันกับคุณใช่หรือไม่ ขออภัยหากดูเหมือนชัดเจนฉันใหม่กับ GIT และต้องการได้รับพื้นฐานบางอย่างก่อน OMG แรกของฉัน
Noich

2
เข้าสู่ระบบ Git เป็นบันทึกของคุณกระทำ การอ้างอิงในฐานะรัฐหนังสือ Pro Git นั้นเป็นบันทึกการอ้างอิงของคุณ(โดยพื้นฐานแล้วตัวชี้สาขาและHEADตัวชี้ของคุณ) และการกระทำที่พวกเขาได้ชี้ไปที่ มันสมเหตุสมผลไหม สังเกตด้านบน, logนอกจากนี้ยังสามารถแสดงให้คุณ reflog ข้อมูล --walk-reflogsแต่ต้องผ่านธงเลือกพิเศษเป็นอาร์กิวเมนต์มัน,

3
นอกจากนี้เนื่องจากคุณเป็นผู้เริ่มต้น Git ฉันขอแนะนำให้คุณอ่านหนังสือ Pro Git มันเป็นวิธีที่ฉันเรียนรู้มากที่สุดจากสิ่งที่ฉันเรียนรู้เกี่ยวกับ Git ฉันแนะนำบทที่ 1-3 และ 6-6.5 ฉันขอแนะนำให้คุณเรียนรู้วิธีการรีบูตทั้งแบบโต้ตอบและแบบไม่โต้ตอบ

8

ฉันอยากรู้เกี่ยวกับสิ่งนี้เช่นกันและเพียงแค่ต้องการทำอย่างละเอียดและสรุปเล็กน้อย:

  1. git logแสดงประวัติของการกระทำทั้งหมดของสาขาที่คุณเปิด ชำระเงินที่ต่างสาขาและคุณจะเห็นประวัติการกระทำที่แตกต่าง git log --allหากคุณต้องการที่จะเห็นคุณกระทำประวัติศาสตร์สำหรับทุกสาขาประเภท

  2. git reflogแสดงบันทึกการอ้างอิงของคุณดังที่ Cupcake กล่าว มีรายการทุกครั้งที่มีการส่งมอบหรือชำระเงิน ลองสลับไปมาระหว่างสองสาขาสองสามครั้งโดยใช้git checkoutและเรียกใช้git reflogหลังจากเช็คเอาต์แต่ละครั้ง คุณจะเห็นรายการยอดนิยมที่ได้รับการอัปเดตในแต่ละครั้งเป็นรายการ "ชำระเงิน" git logคุณไม่เห็นเหล่านี้ประเภทของรายการใน

ข้อมูลอ้างอิง: http://www.lornajane.net/posts/2014/git-log-all-branches


1

ฉันชอบคิดถึงความแตกต่างระหว่างบันทึกการคอมไพล์และการอ้างอิงว่าเป็นความแตกต่างระหว่างบันทึกส่วนตัวและบันทึกสาธารณะ

ส่วนตัวเทียบกับสาธารณะ

ด้วย reflog คอมไพล์มันติดตามทุกสิ่งที่คุณทำในท้องถิ่น คุณยอมรับไหม? Reflog ติดตามมัน คุณทำการฮาร์ดรีเซ็ตหรือไม่ Reflog ติดตามมัน คุณแก้ไขความมุ่งมั่นหรือไม่? Reflog ติดตามมัน ทุกสิ่งที่คุณทำในท้องถิ่นมีรายการไว้ใน reflog

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

บันทึกเป็นเงา reflog เป็นสิ่งที่ไม่น่าไว้วางใจ

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

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

เข้าสู่ระบบขัดมัน  Reflog เป็นสิ่งที่ไม่มีสาระ

กลับไปที่แนวคิด 'เครือข่ายความปลอดภัย'

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


-6

ที่จริงแล้วการอ้างอิงเป็นชื่อแทน

 git log -g --abbrev-commit --pretty=oneline

ดังนั้นคำตอบควรเป็น: มันเป็นกรณีเฉพาะ


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