เหตุใดจึงมี "แหล่งกำเนิด / หัวหน้า" ปรากฏขึ้นเมื่อเรียกใช้ "git branch -r"


160

เมื่อคุณเรียกgit branch -rว่าทำไมไม่พ้นมันรายการorigin/HEAD? ตัวอย่างเช่นมี repo ระยะไกลบน GitHub พูดด้วยสองสาขา: ต้นแบบและคุณสมบัติที่ยอดเยี่ยม ถ้าฉันทำgit cloneเพื่อคว้ามันและจากนั้นเข้าไปในไดเรกทอรีใหม่ของฉันและแสดงรายการสาขาฉันเห็นสิ่งนี้:

$ git branch -r
origin/HEAD
origin/master
origin/awesome-feature

หรือลำดับอะไรก็ตามที่มันจะอยู่ใน (อัลฟาฉันแกล้งทำตัวอย่างนี้เพื่อรักษาตัวตนของความลับ repo ผู้บริสุทธิ์) ดังนั้นHEADธุรกิจคืออะไร มันเป็นสิ่งที่คนสุดท้ายที่จะpushมีการHEADชี้เมื่อพวกเขาผลักดัน? นั่นจะไม่เป็นสิ่งที่พวกเขาpushแก้ไขหรือไม่ HEADย้ายไปรอบ ๆ ... ทำไมฉันถึงสนใจว่ามีใครบางคนHEADชี้ไปที่เครื่องอื่นหรือไม่?

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

แก้ไข: ฉันอยู่ภายใต้ความประทับใจที่ repos ระยะไกลโดยเฉพาะ (เช่น GitHub ที่ไม่มีใครจะ ssh และทำงานกับรหัสนั้น แต่เพียงดึงหรือผลักดัน ฯลฯ ) ไม่ได้และไม่ควรมี HEAD เพราะมีโดยทั่วไป ไม่มีสำเนาทำงาน ไม่ใช่เหรอ


เกี่ยวข้อง: stackoverflow.com/questions/8839958/…
leonbloy

คำตอบ:


140

@robinstถูกต้อง

ในคอมไพล์คุณสามารถเลือกสาขาที่เช็คเอาท์โดยค่าเริ่มต้น (เช่นเมื่อคุณโคลน) โดยค่าเริ่มต้นorigin/HEADจะชี้ไปที่

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

git remote set-head origin trunk

หรือลบโดยสิ้นเชิงผ่าน

git remote set-head origin -d

ตัวอย่าง ดูรายการแบบเลื่อนลง 'เปลี่ยนสาขา' trunkมีการตรวจสอบเพื่อให้เป็นไปตามorigin/HEADtrunk


ฉันเปลี่ยนชื่อรีโมตอื่นให้เป็นoriginและฉันotherremote/HEAD -> masterก็กวนใจฉัน การรันคำสั่งของคุณคงที่สำหรับฉัน
เฟลิเป้อัลวาเรซ

59

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

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


2
เนื่องจากเป็นไปได้ที่จะลบการอ้างอิงนี้โดยไม่ต้องกดorigin/HEADการอ้างอิงในเครื่องถูกต้องหรือไม่ การลบออกมีผลกระทบoriginหรือไม่?
Zach Posten

@zposten: ไม่แบบเดียวกับที่การลบorigin/masterไม่มีผลกับรีโมต
robinst

นั่นหมายความว่าหลังจากการโคลนการอ้างอิงเป็นเพียงข้อมูลที่ไร้ประโยชน์
Bachsau

@Bachsau การอ้างอิงไม่ได้รับการโคลน
robinst

27

ฉันอยู่ภายใต้ความประทับใจที่รีโมตรีโมตเฉพาะ (เช่น GitHub ที่ไม่มีใครจะ ssh และทำงานกับรหัสนั้น แต่เพียงดึงหรือดัน ฯลฯ ) ไม่ได้และไม่ควรมี HEAD เพราะมีโดยทั่วไปไม่ทำงาน สำเนา. ไม่ใช่เหรอ

ฉันมีความประทับใจแบบเดียวกับที่คุณพูด

และฉันยังไม่สามารถลบที่สาขาต้นกำเนิด / หัวติดตามระยะไกลที่โคลนจาก GitHub ด้วยการทำ

git branch -d -r origin/HEAD

สิ่งนี้ไม่มีผลกระทบ

บางคนสามารถบอกฉันได้ว่าฉันจะลบต้นกำเนิด / สาขาการติดตามระยะไกล HEAD ได้อย่างไร

ปรับปรุง

แม้ว่าฉันจะไม่พบว่าทำไมมีต้นกำเนิด / หัวสร้างขึ้นเมื่อโคลนจาก GitHub ฉันก็หาวิธีที่จะลบมัน

Git เวอร์ชันใหม่ให้

git remote set-head <name> -d

เพื่อลบตัวชี้ HEAD ที่ไร้ประโยชน์ของสาขาการติดตามระยะไกล

และเรายังสามารถเปลี่ยนชื่อเริ่มต้นที่เป็นใบ้ว่าอะไรก็ได้ที่เราต้องการโดยใช้

git remote rename origin <new_name>

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


ฉันมีปัญหาเดียวกัน (บน GitHub ด้วยซ้ำ) และหัวหน้าไม่ทำงาน ฉันควรจะใช้งาน 'git head set-head HEAD -d' ระยะไกลหรือไม่
Joost Schuur

5
@Joost: มันgit remote set-head origin -d
znq

13

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

HEAD เป็นส่วนหนึ่งของข้อกำหนดสำหรับที่เก็บข้อมูลที่ถูกต้อง Git Repository Layoutพูดว่าส่วนหนึ่ง:

HEAD

A symref (see glossary) to the refs/heads/ namespace describing the currently active  
branch. It does not mean much if the repository is not associated with any working tree  
(i.e. a bare repository), but a valid git repository must have the HEAD file; some  
porcelains may use it to guess the designated "default" branch of the repository  
(usually master). It is legal if the named branch name does not (yet) exist.

ดังนั้นคุณจะเห็น HEAD เป็นส่วนหนึ่งของรายการสาขาแม้ว่า "มันไม่ได้มีความหมายมาก ... "


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

@geoidesic ที่เก็บอาจเปลือยแม้ว่าคุณจะผลักมัน mkdir foobar; cd foobar; git init --bare; cd ..; git clone foobar foobar_clone; cd foobar_clone; touch file; git add file; git config --global user.email "you@example.com"; git config --global user.name "Your Name"; git commit -m "test"; git push origin master; cd ..; cd foobar; git config core.bareผลลัพธ์ต่อไปนี้เป็นจริง นอกจากนี้ยังไม่มีสำเนาการทำงานของไฟล์พุชใน foobar repo ตามคำสั่งเหล่านั้น
Anders Lindén

@geoidesic ที่เก็บอาจเปลือยแม้ว่าคุณจะผลักมัน mkdir foobar; cd foobar; git init --bare; cd ..; git clone foobar foobar_clone; cd foobar_clone; touch file; git add file; git config user.email "you@example.com"; git config user.name "Your Name"; git commit -m "test"; git push origin master; cd ..; cd foobar; git config core.bareผลลัพธ์ต่อไปนี้เป็นจริง นอกจากนี้ยังไม่มีสำเนาการทำงานของไฟล์ผลักใน foobar repo ตามคำสั่งเหล่านั้น
Anders Lindén

@geoidesic A - repo git เพียงแค่หมายถึง repo ที่ไม่มีแผนผังการทำงานนั่นคือ repo ที่มีเฉพาะไดเรกทอรี. git เท่านั้น แต่ไม่สามารถตรวจสอบไฟล์ใด ๆ ได้เลย เนื่องจากมันไม่สามารถตรวจสอบไฟล์ใด ๆ ได้จริง ๆ แล้วมันไม่ได้มีไดเรกทอรี. git เลยเพียงแค่วางไฟล์. git ทั้งหมดลงในไดเรกทอรีหลักโดยตรง สร้างหนึ่งแล้วคุณจะเห็น!
00prometheus

5

หาก "origin" เป็นที่เก็บแบบรีโมตดังนั้น origin / HEAD จะระบุสาขาเริ่มต้นบนที่เก็บแบบรีโมตนั้น

ตัวอย่าง:

$ git remote show
origin
$ git remote show origin
* remote origin
  Fetch URL: git@github.com:walkerh/pipe-o-matic.git
  Push  URL: git@github.com:walkerh/pipe-o-matic.git
  HEAD branch: master
  Remote branch:
    master tracked
  Local branch configured for 'git pull':
    master merges with remote master
  Local ref configured for 'git push':
    master pushes to master (fast-forwardable)

สังเกตบรรทัดที่ระบุว่า "HEAD branch: master" นี่คือที่เก็บระยะไกลช่วยให้ลูกค้าทราบว่าสาขาที่จะชำระเงินโดยค่าเริ่มต้น


1

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


2
repos GitHub ไม่ได้ตรวจสอบสาขา ฉันไม่เห็นสาเหตุที่จะนำไปใช้
ดัสติน

ที่เก็บข้อมูลระยะไกลไม่ควรมีไดเรกทอรีทำงาน ที่เก็บข้อมูลระยะไกลควรเป็น - ไม่เปิดเผยและอาจไม่มีสาขาที่ตรวจสอบอยู่ในขณะนี้
n4rzul

-14

ฉันเดาว่ามีคนผลักสาขาและเรียกมันว่า HEAD:

git push origin HEAD

ฉันขอความคิดเห็นเกี่ยวกับสิ่งนี้ได้ไหม หากคุณต้องการต้นกำเนิด / หัวบน github นั่นเป็นวิธีเดียวที่ฉันรู้ว่าจะไปที่นั่น
ดัสติน

HEAD แบบรีโมตคือการอ้างอิงแบบสัญลักษณ์ (โดยปกติจะเป็น refs / heads / master) คุณจะแทนที่การอ้างอิงสัญลักษณ์ด้วยรหัสแฮชของการกระทำของสาขาปัจจุบันของคุณ
Daniel Fanjul

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