หัวหน้าคืออะไรในคอมไพล์?


232

ดูเหมือนว่าจะมีความแตกต่างระหว่างการส่งครั้งล่าสุด HEAD และสถานะของไฟล์ที่ฉันเห็นในไดเรกทอรีของฉัน

HEAD คืออะไรฉันควรทำอะไรกับมันและฉันควรหลีกเลี่ยงความผิดพลาดอะไรบ้าง



1
เริ่มต้นด้วย Git v1.8.4 คำตอบด้านล่างทั้งหมดที่ใช้HEADหรือheadสามารถใช้@ในสถานที่ของHEADแทน ดูคำตอบนี้ (ส่วนสุดท้าย)เพื่อเรียนรู้ว่าทำไมคุณสามารถทำเช่นนั้น

3
จาก git-scm : HEAD in Git เป็นตัวชี้ไปยังการอ้างอิงสาขาปัจจุบันซึ่งจะเปลี่ยนเป็นตัวชี้ไปยังการส่งข้อมูลล่าสุดที่คุณทำหรือการส่งข้อมูลครั้งล่าสุดที่ถูกตรวจสอบในไดเรกทอรีการทำงานของคุณ นั่นก็หมายความว่ามันจะเป็นพาเรนต์ของการกระทำครั้งต่อไปที่คุณทำ โดยทั่วไปจะคิดได้ง่ายที่สุดเนื่องจาก HEAD เป็นภาพรวมของการคอมมิทครั้งล่าสุดของคุณ
Quazi Irfan

3
ซ้ำซ้อนที่เป็น
Buts

คำตอบ:


185

HEAD เป็นการอ้างอิงถึงการกระทำครั้งสุดท้ายในสาขาที่เช็คเอาท์ในปัจจุบัน


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


1
เหตุใดคุณจึงมีสองหัว
E-satis

1
@ E-satis: บางครั้งคุณจะเห็นสาขาเรียกว่าหัว - refs/headsพวกเขากำลังเก็บไว้ใน หัวตัวพิมพ์เล็กแตกต่างจากHEADแม้ว่า คำตอบของฉันชี้แจงนี้เล็กน้อย
Cascabel

7
@ e-Satisfaction: นั่นไม่ใช่ regex นี่^เป็นเพียงสัญลักษณ์ของคอมไพล์สำหรับ "การกระทำก่อนหน้า" - นั่นคือการกระทำก่อนที่ปัจจุบัน (หากปัจจุบันเป็นการผสานจะใช้พาเรนต์แรก)
Cascabel

1
@ e-Satisfaction: ดูส่วนการแก้ไขที่ระบุไว้ใน man page สำหรับ git-rev-list สำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีการทั้งหมดที่ระบุคอมมิท - นี่เป็นเพียงชิ้นเล็ก ๆ kernel.org/pub/software/scm/git/docs/…
Cascabel

1
ไม่เมื่อ rev และ HEAD ชี้ไปที่การคอมมิชชันเดียวกันจะไม่มีความแตกต่าง และคุณยังสามารถเขียนรหัสการกระทำ (ค่า SHA-1) แทน rev หรือ HEAD และไม่ต้องกังวลคุณไม่รบกวนเราด้วยคำถาม :) (อย่างน้อยฉัน: P)
poke

87

HEAD คือการอ้างอิง (การอ้างอิง) ถึงการกระทำที่ชำระเงินแล้วในปัจจุบัน

ในสถานะปกติจริงๆแล้วมันเป็นสัญลักษณ์อ้างอิงถึงสาขาที่คุณเช็คเอาท์ - ถ้าคุณดูเนื้อหาของ. git / HEAD คุณจะเห็นบางอย่างเช่น "ref: refs / heads / master" สาขานั้นเป็นการอ้างอิงถึงการกระทำที่ส่วนปลายของสาขา ดังนั้นในสภาวะปกติHEADหมายถึงการคอมมิทที่ปลายของสาขาปัจจุบันอย่างมีประสิทธิภาพ

นอกจากนี้ยังเป็นไปได้ที่จะมี "HEAD แฝด" สิ่งนี้จะเกิดขึ้นเมื่อคุณตรวจสอบบางอย่างนอกเหนือจากสาขา (ท้องถิ่น) เช่นสาขาระยะไกลการส่งหรือแท็ก สถานที่ที่พบเห็นได้บ่อยที่สุดคือช่วงรีบูตแบบโต้ตอบเมื่อคุณเลือกแก้ไขคอมมิชชัน ในสถานะ HEAD เดี่ยว HEAD ของคุณเป็นการอ้างอิงโดยตรงไปยังคอมมิท - เนื้อหาของ. git / HEAD จะเป็นแฮช SHA1

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


6
นี่คือสิ่งที่ฉันไม่เข้าใจ หากคุณชำระเงินที่สาขาระยะไกลทำไมคุณถึงลงเอยด้วย "เฮดเดอเฮด" ทำไมคุณไม่กระโดดในสาขาโดยอัตโนมัติใน repo ท้องถิ่นของคุณที่สอดคล้องกับระยะไกลของคุณ?
E-satis

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

1
ตกลงนั่นคือสิ่งที่ฉันไม่ได้รับ: การมีสาขาในพื้นที่ที่มีชื่อไม่ได้หมายความว่ามันเหมือนกับสาขาระยะไกล ยากมากที่จะเริ่มต้นเพราะฉันมาจากพื้นหลังของ SVN :-) ขอบคุณมาก BTW คุณจะย้าย HEAD HEAD HEAD ไปที่สาขาท้องถิ่นเพื่อส่งมันได้อย่างไร
E-satis

3
@ E-satis: git rebase <branch> HEADคำตอบทั่วไปคือ นี้จะได้พบกับบรรพบุรุษร่วมกันล่าสุด<branch>และHEADแล้วจะกระทำทั้งหมดจากที่นั่นไปHEADและใช้พวกเขา (rebase พวกเขา) <branch>ไปยัง มันทำสิ่งนี้เป็นหลักโดยการใช้พวกมันเป็นแพตช์ดังนั้นถ้าทั้งสองกิ่งแตกต่างกันจริงๆอาจมีความขัดแย้งได้ แต่ถ้า<branch>เป็นบรรพบุรุษของHEAD(เช่นคุณอยู่ในสถานที่ที่ถูกต้องเพียงแค่คุณลืมที่จะถอดออกHEAD) การปฏิเสธเป็นเพียงการผสานที่รวดเร็ว
Cascabel

3
นี่เป็นหนึ่งในคำอธิบายที่ชัดเจนและถูกต้องที่สุดของ Git HEAD ที่ฉันได้เห็นหลังจากค้นหาไปสักพัก
LarsH

21

ฉันมักจะคิดว่าHEAD~5หมายถึง GO ถึง 5 กระทำก่อนหน้านี้ แต่มันไม่ได้ดำเนินการส่วน GO ของคำสั่ง มันจะดำเนินการอ้างอิง / 'ที่ไหน' ส่วนหนึ่งของคำสั่ง

ในแง่คนธรรมดาก็ใช้ในการตอบคำถามของ: WHEREฉันควรจะไป? สิ่งที่กระทำ?

  • HEAD หมายถึง (อ้างอิงถึง) กระทำปัจจุบัน
  • HEAD~1 หมายถึง (อ้างอิงถึง) 1 กระทำก่อน
  • HEAD~ ALSO หมายถึง (การอ้างอิงถึง) 1 กระทำก่อนหน้านี้
  • HEAD~87 หมายถึง (อ้างอิงถึง) 87 กระทำก่อนหน้านี้

การใช้งาน:

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

3
กลับมาที่คำตอบของฉันเอง :)
น้ำผึ้ง

15

ตัวชี้ HEAD ใน Git

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

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

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

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


0

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

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

คุณสามารถดูว่า HEAD ชี้ไปที่ใดโดยทำดังนี้

cat .git/HEAD

เป็นไปได้ที่ HEAD จะอ้างถึงการแก้ไขเฉพาะที่ไม่เกี่ยวข้องกับชื่อสาขา สถานการณ์นี้เรียกว่า HEAD แฝด

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