HEAD และ ORIG_HEAD ใน Git


253

สัญลักษณ์เหล่านี้หมายถึงอะไรและหมายความว่าอย่างไร

(ฉันไม่พบคำอธิบายใด ๆ ในเอกสารประกอบอย่างเป็นทางการ)


4
หมายเหตุ: HEADตอนนี้ (กำลังจะมาถึง git1.8.4) ' @'! ดูคำตอบที่แก้ไขของฉันด้านล่าง
VonC

หมายเหตุทวิ: ' @' (ต่อHEAD) จะยังคงมา แต่ไม่ได้สำหรับ 1.8.4 คำตอบแก้ไขและที่แก้ไขเพิ่มเติม
VonC

1
หมายเหตุ: ' @' สำหรับHEADกลับมาเป็น git 1.8.5 / 1.9 คำตอบแก้ไขอีกครั้ง
VonC

21
HEADและORIG_HEADใน Git ก็เหมือน$PWDและ$OLDPWDใน Bash :)
musiphil

คำตอบ:


324

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

และ@เพียงอย่างเดียวคือทางลัดสำหรับHEADเนื่องจาก Git 1.8.5

ORIG_HEADเป็นสถานะก่อนหน้าของHEADกำหนดโดยคำสั่งที่อาจมีพฤติกรรมที่เป็นอันตรายและง่ายต่อการเปลี่ยนกลับ มันจะมีประโยชน์น้อยในขณะนี้ว่า Git มี reflog: HEAD@{1}เทียบเท่าประมาณไปORIG_HEAD( HEAD@{1}อยู่เสมอค่าสุดท้ายของHEAD, ORIG_HEADคุ้มค่าล่าสุดของHEADก่อนที่จะดำเนินอันตราย)

สำหรับข้อมูลเพิ่มเติมอ่านmanit git (1) , คู่มือผู้ใช้ Git , Git Community BookและGit อภิธานศัพท์


2
สวัสดีจาคุบ +1 สำหรับคำอธิบาย คุณช่วยรายละเอียดส่วน "เทียบเท่าประมาณ" ของ HEAD @ {1} ได้ไหม ฉันอ้างถึงคำตอบของฉันในเธรดthread.gmane.org/gmane.comp.version-control.git/38379 (คุณอยู่ในนั้นย้อนกลับไปเมื่อเดือนกุมภาพันธ์ 2550) และฉันไม่เข้าใจการสนทนาที่คุณมี ไวยากรณ์ @ {... }
VonC

19
ORIG_HEAD ถูกตั้งค่า (ฉันคิดว่า) โดยคำสั่ง 'อันตราย' เท่านั้นซึ่งจะย้าย HEAD มากกว่าหนึ่งการกระทำ ดังนั้น ORIG_HEAD จึงไม่ได้ตั้งค่าไว้เสมอในขณะที่ HEAD @ {1} จะถูกตั้งค่าไว้เสมอ @ {1} คือ $ (git symbolic-ref HEAD) @ {1} คือมันใช้ reflog สำหรับสาขาปัจจุบันไม่ใช่ HEAD reflog
Jakub Narębski

Riiight ... ฉันเข้าใจแล้วตอนนี้ :) ขอบคุณสำหรับคำอธิบาย สำหรับสิ่งที่คุ้มค่าฉันก็สนับสนุนความคิดเห็นของคุณด้วย!
VonC

1
"และ HEAD เป็นความมุ่งมั่นที่" git commit "จะสร้างใหม่" - ดีที่ต้องจำขอบคุณ! นอกจากนี้จาก @VonC 'มันเป็นคอมมิท "git commit" ที่สร้างขึ้นและ "git diff --cached" และ "สถานะ git" เปรียบเทียบกับ'
Minqi Pan

1
การแก้ไขความช่วยเหลือของ git จะแสดงgit-scm.com/docs/gitrevisionsซึ่งจะอธิบายวิธีการอ้างอิงการกระทำทั้งหมด (รวมถึงHEADและORIG_HEAD)
dahlbyk

104

จากการรีเซ็ตคอมไพล์

"pull" หรือ "merge" ออกจากส่วนปลายเดิมของสาขาปัจจุบันORIG_HEADเสมอ

git reset --hard ORIG_HEAD

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

git reset --merge ORIG_HEAD

หลังจากตรวจสอบผลลัพธ์ของการผสานคุณอาจพบว่าการเปลี่ยนแปลงในสาขาอื่นไม่เป็นที่น่าพอใจ การเรียกใช้ " git reset --hard ORIG_HEAD" จะช่วยให้คุณย้อนกลับไปยังตำแหน่งเดิม แต่จะเป็นการยกเลิกการเปลี่ยนแปลงในเครื่องที่คุณไม่ต้องการ " git reset --merge" เก็บการเปลี่ยนแปลงในเครื่องของคุณ


ก่อนที่จะมีการใช้โปรแกรมแก้ไขใด ๆ ORIG_HEAD จะถูกตั้งค่าไว้ที่ส่วนปลายของสาขาปัจจุบัน
สิ่งนี้มีประโยชน์หากคุณมีปัญหากับการกระทำหลายอย่างเช่นการเรียกใช้ ' git am' ในสาขาที่ไม่ถูกต้องหรือข้อผิดพลาดในการกระทำที่แก้ไขได้ง่ายขึ้นโดยการเปลี่ยนกล่องจดหมาย (เช่น + ข้อผิดพลาดในบรรทัด "จาก:")

นอกจากนี้การผสานจะตั้งค่า ' .git/ORIG_HEAD' เป็นสถานะเริ่มต้นของ HEAD เสมอเพื่อให้การลบที่มีปัญหาสามารถทำได้โดยใช้ ' git reset ORIG_HEAD'


หมายเหตุ: จากที่นี่

HEAD เป็นตัวชี้การเคลื่อนที่ บางครั้งมันหมายถึงสาขาปัจจุบันบางครั้งก็ไม่ได้

ดังนั้น HEAD จึงไม่ใช่คำพ้องความหมายสำหรับ "สาขาปัจจุบัน" ทุกที่แล้ว

HEAD หมายถึง"ปัจจุบัน" ทุกที่ในคอมไพล์ แต่ไม่ได้แปลว่า "สาขาปัจจุบัน" (เช่น HEAD ที่แยกออกมา)

แต่มันก็มักจะหมายถึง "การกระทำในปัจจุบัน"
มันคือการคอมมิชชันที่git commitสร้าง " git diff --cached" เหนือและgit statusเปรียบเทียบกับ" " และ " "
มันหมายถึงสาขาปัจจุบันในบริบทที่ จำกัด มากเท่านั้น (เมื่อเราต้องการให้ชื่อสาขาดำเนินการ --- รีเซ็ตและขยายเคล็ดลับสาขาผ่านทาง commit / rebase / etc)

Reflog เป็นยานพาหนะที่สามารถย้อนเวลากลับไปและเครื่องจักรมีปฏิสัมพันธ์ที่น่าสนใจกับแนวคิดของ "ปัจจุบัน"

HEAD@{5.minutes.ago}อาจหมายถึง "การเลิกอ้างสิทธิ์ HEAD symref เพื่อค้นหาว่าสาขาใดที่เราอยู่ในตอนนี้และจากนั้นหาที่ปลายของสาขานั้นเมื่อ 5 นาทีก่อน"
อีกวิธีหนึ่งก็อาจหมายถึง "ความมุ่งมั่นที่ฉันจะเรียกว่า HEAD 5 นาทีก่อนคืออะไรถ้าฉันทำ" git show HEAD "ย้อนกลับไปแล้ว"


git1.8.4 (กรกฎาคม 2013) แนะนำ แนะนำสัญลักษณ์ใหม่!
(อันที่จริงมันจะเป็น 1.8.5 หรือ 1.9, Q4 2013: แนะนำใหม่ด้วยcommit 9ba89f4 )

แทนที่จะพิมพ์อักษรตัวใหญ่สี่ตัว " HEAD" คุณสามารถพูดว่า " @" ตอนนี้
เช่น " git log @"

ดูคอมมิท cdfd948

การพิมพ์ ' HEAD' น่าเบื่อโดยเฉพาะเมื่อเราสามารถใช้ ' @' แทน

เหตุผลในการเลือก 'The @' ก็คือว่ามันเป็นไปตามธรรมชาติจากref@opไวยากรณ์ (เช่นHEAD@{u}) ยกเว้นเราไม่มีโทษและไม่มีการดำเนินการและเมื่อเราไม่ได้มีเหล่านั้นก็ทำให้ Sens จะถือว่า ' HEAD'

ดังนั้นตอนนี้เราสามารถใช้ ' git show @~1' และความดีงามทั้งหมดนั้น

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


การโพสต์บล็อกในช่วงระยะเวลา 1.8.4-rc3 (14 สิงหาคม 2013) ประกาศว่าคุณลักษณะนี้ถูกเปลี่ยนกลับและล่าช้า (ขอขอบคุณCupcakeสำหรับการเฮดขึ้น )
อีกครั้งจะเปิดตัวอีกครั้งด้วยการ กระทำ 9ba89f4 (กันยายน 2013)

ดูคอมมิชชัน 2c2b664 :

ย้อนกลับ "เพิ่ม@ทางลัดใหม่สำหรับHEAD"

การย้อนกลับเป็นการกระทำcdfd948เนื่องจากมันไม่ได้ใช้กับ " @" (และแบบฟอร์มที่มีตัวดัดแปลงเช่นเดียว@{u}กับมัน) แต่ยังส่งผลกระทบเช่น " refs/heads/@/foo" ซึ่งไม่ควร

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


หลังจากรัน git แล้ว ORIG_HEAD จะทำการรีเซ็ต ORIG_HEAD ยังคงอยู่ภายใต้การอ้างอิงถัดจาก HEAD เหตุใดจึงไม่ถูกลบออกจากมุมมอง
powder366

@ powder366 แต่จะสร้างgit reset ORIG_HEADดังนั้นคุณต้องไปrmด้วยตนเอง ดูstackoverflow.com/a/12418078/6309เป็นตัวอย่าง
VonC

1
@VonC @นามแฝงที่HEADจะถูกเปลี่ยน (ชั่วคราว?) สำหรับ Git 1.8.4 release ! เพิ่งประกาศออกมาวันนี้!

ชอบความคิดเห็น "หัวขึ้น"!
Robino

2

ความเข้าใจของฉันคือ HEAD ชี้ไปที่สาขาปัจจุบันในขณะที่ ORIG_HEAD ใช้เพื่อจัดเก็บ HEAD ก่อนหน้านี้ก่อนที่จะทำการดำเนินการ "อันตราย"

ตัวอย่างเช่น git-rebase และ git-am บันทึกส่วนปลายของกิ่งก่อนที่จะใช้การเปลี่ยนแปลงใด ๆ


4
HEAD ไม่ได้ชี้ไปที่สาขาปัจจุบันเสมอไป (สามารถถอดออกได้)
VonC

1
ดังนั้น "สาขาปัจจุบัน" คืออะไรเมื่อ HEAD "ไม่ได้ถูกแยกออก"
cjs

@ CurtJ.Sampson นั่นคือ "ไม่มีสาขา" นั่นเป็นเหตุผลที่เมื่อคุณอยู่ในหัวเดี่ยวคุณจะทำgit branch foo -bเพื่อ "สร้าง" สาขาสำหรับเด็กกำพร้าที่มุ่งมั่น
Royi Namir

1

จากman 7 gitrevisions:

HEAD ตั้งชื่อการกระทำที่คุณยึดตามการเปลี่ยนแปลงในแผนผังการทำงาน FETCH_HEAD บันทึกสาขาที่คุณดึงข้อมูลจากที่เก็บระยะไกลด้วยการเรียกการเรียก git ครั้งสุดท้ายของคุณ ORIG_HEAD ถูกสร้างขึ้นโดยคำสั่งที่ย้ายหัวของคุณอย่างรุนแรงเพื่อบันทึกตำแหน่งของ HEAD ก่อนการใช้งานเพื่อให้คุณสามารถเปลี่ยนส่วนปลายของสาขากลับสู่สถานะก่อนที่คุณจะวิ่งได้อย่างง่ายดาย MERGE_HEAD บันทึกการกระทำที่คุณกำลังรวมเข้าไปในสาขาของคุณเมื่อคุณเรียกใช้คอมไพล์ผสาน CHERRY_PICK_HEAD บันทึกการกระทำที่คุณกำลังเก็บผลเชอร์รี่เมื่อคุณเรียกใช้ git cherry-pick

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