เปลี่ยน Git remote HEAD ให้ชี้ไปที่สิ่งอื่นนอกเหนือจาก master


124

ฉันจะตั้งค่าการอ้างอิง HEAD ของรีโมต Git ให้ชี้ไปที่บางสิ่งนอกเหนือจาก "master" ได้อย่างไร

โครงการของฉันมีนโยบายที่จะไม่ใช้สาขา "หลัก" (ทุกสาขาจะต้องมีชื่อที่มีความหมาย) นอกจากนี้ที่เก็บหลักมาตรฐานสามารถเข้าถึงได้ผ่าน ssh: // เท่านั้นโดยไม่มีการเข้าถึงเชลล์ (เช่น GitHub หรือ Unfuddle)

ปัญหาของฉันคือที่เก็บข้อมูลระยะไกลยังคงมีการอ้างอิง HEAD ไปยัง refs / head / master แต่ฉันต้องการให้ชี้ไปที่สาขาอื่น สิ่งนี้ทำให้เกิดปัญหาสองประการ:

  1. เมื่อโคลน repo มีสิ่งนี้

    คำเตือน: remote HEAD หมายถึงการอ้างอิงที่ไม่มีอยู่จริงไม่สามารถชำระเงินได้

    ที่สับสนและไม่สะดวก

  2. เบราว์เซอร์โค้ดบนเว็บขึ้นอยู่กับ HEAD เป็นพื้นฐานในการเรียกดูต้นไม้ ฉันต้องการ HEAD เพื่อชี้ไปที่สาขาที่ถูกต้องแล้ว


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

เคล็ดลับ "no-common-บรรพบุรุษ": น่าสนใจ คุณสามารถโพสต์เป็นคำตอบโดยละเอียดและเลือกเป็นคำตอบอย่างเป็นทางการหากพบว่าใช้งานได้
VonC

12
FWIW เนื่องจากคุณกล่าวถึง GitHub ในคำถาม - หากคุณต้องการเปลี่ยน HEAD ref บน GitHub เพียงไปที่หน้าจอ "Admin" ของที่เก็บแล้วเปลี่ยนรายการแบบเลื่อนลง "Default Branch" เป็นสาขาที่คุณต้องการให้ HEAD ชี้ไป
โจ


คำตอบ:


63

เกือบจะมีคำถามเดียวกันใน GitHubเมื่อปีที่แล้ว

แนวคิดคือการเปลี่ยนชื่อสาขาหลัก:

git branch -m master development
git branch -m published master
git push -f origin master 

การทำให้อาจารย์มีสิ่งที่คุณต้องการให้ผู้คนใช้และทำงานอื่น ๆ ทั้งหมดในสาขา

(a " git-symbolic-ref HEAD refs/head/published" จะไม่ถูกเผยแพร่ไปยัง repo ระยะไกล)

จะคล้ายกับ " ฉันจะลบต้นทาง / ต้นแบบใน Git ได้อย่างไร "


ตามที่กล่าวไว้ในหัวข้อนี้ : (เน้นของฉัน)

" git clone" สร้างเฉพาะสาขาท้องถิ่นเดียว
ในการทำเช่นนั้นให้ดูที่HEAD refrepo ระยะไกลและสร้างสาขาภายในที่มีชื่อเดียวกับสาขาระยะไกลที่อ้างถึง

ดังนั้นเพื่อสรุปสิ่งนี้คุณมี repo A และโคลนมัน:

  • HEADการอ้างอิงrefs/heads/masterและที่มีอยู่
    -> คุณจะได้รับสาขาท้องถิ่นที่เรียกว่า master โดยเริ่มจากต้นกำเนิด / ต้นแบบ

  • การอ้างอิง HEAD refs/heads/anotherBranchและที่มีอยู่
    -> คุณได้รับสาขาท้องถิ่นที่เรียกว่าanotherBranchเริ่มต้นจากorigin/anotherBranch

  • การอ้างอิง HEAD refs/heads/masterและไม่มีอยู่
    -> "git clone" บ่น

ไม่แน่ใจว่ามีวิธีใดที่จะปรับเปลี่ยนโดยตรงHEADเตะใน repo

(ซึ่งเป็นประเด็นทั้งหมดของคำถามของคุณฉันรู้;))


อาจจะเป็นวิธีเดียวที่จะเป็น"สิ่งพิมพ์สำหรับคนจน"ซึ่งคุณ:

 $ git-symbolic-ref HEAD refs/head/published
 $ git-update-server-info
 $ rsync -az .git/* server:/local_path_to/git/myRepo.git/

แต่นั่นจะเกี่ยวข้องกับการเข้าถึงการเขียนไปยังเซิร์ฟเวอร์ซึ่งไม่สามารถทำได้เสมอไป


ตามที่ฉันอธิบายใน " Git: วิธีที่ถูกต้องในการเปลี่ยน Active Branch ในที่เก็บเปล่า " git remote set-headจะไม่เปลี่ยนแปลงอะไรใน repo ระยะไกล

มันจะเปลี่ยนสาขาการติดตามระยะไกลที่จัดเก็บไว้ใน repo ในพื้นที่ของคุณเท่านั้นในremotes/<name>/HEAD.


ขอบคุณ VonC ฉันอ่านก่อนที่จะโพสต์ที่นี่ แต่อย่างที่คุณเห็นสาขาที่เรียกว่า "master" ไม่เป็นที่พอใจในโครงการนี้ด้วยเหตุผลด้านเทคนิคและนโยบาย
JasonSmith

จากนั้นคุณสามารถบังคับใช้นโยบายดังกล่าวได้โดยไม่อนุญาตให้อัปเดตใด ๆ ในสาขาหลักผ่านเบ็ดก่อนคอมมิต
VonC

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

ขอบคุณสำหรับการอัพเดท. ในขณะนี้ฉันใช้เคล็ดลับ "ไม่มีบรรพบุรุษร่วมกัน" เพื่อสร้างสาขาหลักด้วยการคอมมิตเพียงครั้งเดียว (เช่น: git branch -D master; echo ref: refs / head / master> .git / HEAD; rm *) จากนั้นฉันก็แตะไฟล์ชื่อ GO_AWAY และส่งข้อความอธิบายสถานการณ์ ที่จะใช้ได้ในตอนนี้ ฉันอาจตรวจสอบแหล่งที่มาและติดตามว่าฝ่ายรับตั้งค่า HEAD สำหรับคำตอบสุดท้าย
JasonSmith

1
@ctn นั่นเป็นเพราะฉันลืมตัวเลือก-f( --force) ฉันได้แก้ไขคำตอบตามนั้น จากนั้นคำตอบที่คุณอ้างอิงจะใช้ตัวเลือกเดียวกันนั้น
VonC

42

อัปเดต:ใช้ได้เฉพาะกับสำเนาภายในของที่เก็บ ("ไคลเอนต์") โปรดดูความคิดเห็นของผู้อื่นด้านล่าง

ด้วย git เวอร์ชันล่าสุด (กุมภาพันธ์ 2014) ขั้นตอนที่ถูกต้องคือ:

git remote set-head $REMOTE_NAME $BRANCH

ตัวอย่างเช่นการเปลี่ยนหัวบนรีโมตoriginเป็นสาขาdevelopจะเป็น:

git remote set-head origin develop


คุณลักษณะนี้จำเป็นต้องมี git เวอร์ชันล่าสุดบนเซิร์ฟเวอร์หรือเพียงพอหรือไม่หากเครื่องไคลเอนต์ได้ติดตั้งคอมไพล์ล่าสุด
Mikko Rantalainen

3
@Totor สั้น แต่ถูก; คำตอบนี้ควรถูกลงคะแนน Git มีแนวคิดที่ค่อนข้างสับสนเกี่ยวกับ "สาขาภายในเครื่องสำหรับรีโมต" ซึ่งช่วยให้คุณพิมพ์ "ต้นกำเนิด" แทน "แหล่งกำเนิด / defaultbranch" และเป็นฝั่งไคลเอ็นต์บริสุทธิ์สิ่ง เรื่องยาวที่git-scm.com/docs/git-remote # set-head
MarcH

1
เพื่อยืนยันว่า @MarchH พูดถึงอะไร: run git checkout -b default; git push origin HEAD; git remote set-head origin default. จากนั้นคุณสามารถตรวจสอบการเปลี่ยนแปลงภายในเครื่องด้วยcat .git/refs/remotes/origin/HEAD(ควรจะเป็นref: refs/remotes/origin/default) และการขาดการเปลี่ยนแปลงระยะไกลด้วยgit remote show origin(จะยังคงเป็นอะไรก็ได้ก่อนที่คุณจะเพิ่มสาขาเริ่มต้น)
De Novo

37

เนื่องจากคุณพูดถึง GitHub หากต้องการทำบนไซต์ของพวกเขาเพียงเข้าไปในโครงการของคุณจากนั้น ...

admin > Default Branch > (choose something)

เสร็จสิ้น


1
ยอดเยี่ยม นั่นคือบิตสุดท้ายที่หายไป
berkus

จุดเริ่มต้น / HEAD ของฉันชี้ไปที่สาขาคุณลักษณะแทนต้นแบบแล้ว ฉันลองเปลี่ยน "สาขาหลัก" ไปมา แต่ก็ไม่มีผลกับ HEAD ... มีคำแนะนำไหม
Daniil Shevelev

3
การตั้งค่า> สาขา> สาขาเริ่มต้น
Chun Yang

12

ดู: http://www.kernel.org/pub/software/scm/git/docs/git-symbolic-ref.html

สิ่งนี้ตั้งค่าสาขาเริ่มต้นในที่เก็บ git คุณสามารถเรียกใช้สิ่งนี้ในที่เก็บเปล่าหรือมิเรอร์

การใช้งาน:

$ git symbolic-ref HEAD refs/heads/<branch name>

6
$ git symbolic-ref HEAD refs / head / name-of-branch
Lamy

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

10

(โดยพื้นฐานแล้วมีคำถามเดียวกัน " create a git symbolic ref in remote repository " ซึ่งไม่ได้รับคำตอบที่เป็นสากล)

แต่มีคำตอบเฉพาะสำหรับ "ฟาร์ม" git ต่างๆ (ที่ผู้ใช้หลายคนสามารถจัดการ git repos ผ่านอินเทอร์เฟซที่ จำกัด : ผ่าน http และ ssh): http://Github.com , http://Gitorious.org , http: / /repo.or.cz , Girar ( http://git.altlinux.org )

คำตอบเฉพาะเหล่านี้อาจเป็นประโยชน์สำหรับผู้ที่อ่านหน้านี้และคิดถึงบริการเฉพาะเหล่านี้


4
ตอนนี้พวกเขามีเมนูแบบเลื่อนลงสำหรับเลือกสาขา HEAD ที่repo.or.cz (ตัวอย่าง: repo.or.cz/editproj.cgi?name=for-me-and-for-all_imz.git ) และgitorious.orgเช่นกัน ที่ดี!
imz - Ivan Zakharyaschev

7

หากคุณสามารถเข้าถึง repo ระยะไกลจากเชลล์เพียงเข้าไปที่. git (หรือ dir หลักถ้าเป็น repo เปล่า) แล้วเปลี่ยนไฟล์ HEAD ให้ชี้ไปที่ส่วนหัวที่ถูกต้อง ตัวอย่างเช่นโดยค่าเริ่มต้นจะมี 'refs: refs / head / master' เสมอ แต่ถ้าคุณต้องการให้ foo เป็น HEAD แทนให้แก้ไขไฟล์ HEAD และเปลี่ยนเนื้อหาเป็น 'refs: refs / head / foo'


ฉันมีสิทธิ์ผู้ดูแลระบบบนเซิร์ฟเวอร์ Git และฉันก็ทำเช่นเดียวกัน เราใช้ Gitolite และฉันไปที่ที่เก็บที่ฉันสร้างขึ้น ชื่อไดเร็กทอรีคือmyrepo.git. เนื้อหาของไฟล์ HEAD ในไดเร็กทอรีที่กำหนดถูกเปลี่ยนจากref: refs/heads/masterเป็นref: refs/heads/mainline. ตอนนี้เมื่อฉันพยายามโคลนที่เก็บบนกล่องในเครื่องของฉันมันยังคงชี้ให้เห็นถึงความเชี่ยวชาญ ฉันรันgit clone ssh://gitolite@git.server/myrepoคำสั่ง มีความคิดเกี่ยวกับพฤติกรรมดังกล่าวหรือไม่?
Technext

เวอร์ชันเซิร์ฟเวอร์ Git: git version 1.7.1& เวอร์ชันไคลเอนต์ Git:git version 1.9.4.msysgit.2
Technext

5

คุณสามารถสร้างสาขาหลักแยกได้โดยใช้คำสั่ง porcelain Git เท่านั้น:

git init
touch GO_AWAY
git add GO_AWAY
git commit -m "GO AWAY - this branch is detached from reality"

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

git checkout -b trunk
git rm GO_AWAY
git commit --amend --allow-empty -m "initial commit on detached trunk"

เฮ้โอมเพี้ยง! gitk - ทั้งหมดจะแสดงmasterและtrunkโดยไม่มีการเชื่อมโยงระหว่างกัน

"เวทมนตร์" ในที่นี้คือ - ทำให้คอมมิตคอมมิตสร้างคอมมิตใหม่โดยใช้พาเรนต์เดียวกับ HEAD ปัจจุบันจากนั้นให้ HEAD ชี้ไปที่มัน แต่ HEAD ปัจจุบันไม่มีพาเรนต์เนื่องจากเป็นการคอมมิตเริ่มต้นในที่เก็บดังนั้น HEAD ใหม่จึงไม่ได้รับอย่างใดอย่างหนึ่งทำให้แยกออกจากกัน

คอมมิต HEAD เก่าจะไม่ถูกลบโดยgit-gcเนื่องจาก refs / head / master ยังคงชี้ไปที่มัน

--allow ว่างธงจำเป็นเท่านั้นเพราะเรากำลังกระทำต้นไม้ที่ว่างเปล่า หากมีการเพิ่มคอมไพล์หลังจากgit rmก็ไม่จำเป็น

ในความเป็นจริงคุณสามารถสร้างสาขาแฝดตลอดเวลาโดยการแตกแขนงเริ่มต้นกระทำในพื้นที่เก็บข้อมูลการลบต้นไม้ที่เพิ่มต้นไม้แฝดของคุณแล้วทำคอมไพล์กระทำ --amend

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


1
คุณสามารถสร้างสาขาแยกได้ง่ายขึ้นโดยดึงสาขาที่ไม่เกี่ยวข้องจาก repo อื่นและตั้งชื่อ ยกตัวอย่างเช่นgit fetch git:user@example.com:foo remote-branch-name && git checkout -b detached-branch FETCH_HEADจะเพิ่มสาขาใหม่detached-branchที่ตรงกับสาขาที่อยู่ห่างไกลremote-branch-name git:user@example.com:fooแน่นอนว่า "รีโมต" สามารถเป็นที่เก็บในระบบไฟล์โลคัลที่คุณเตรียมไว้ก่อนหน้านี้
Mikko Rantalainen

2

ขั้นแรกให้สร้างสาขาใหม่ที่คุณต้องการตั้งเป็นค่าเริ่มต้นตัวอย่างเช่น:

$>git branch main

จากนั้นดันสาขานั้นไปยังจุดเริ่มต้น :

$>git push origin main

ตอนนี้เมื่อคุณลงชื่อเข้าใช้บัญชี GitHub ของคุณคุณสามารถไปที่ที่เก็บของคุณแล้วเลือกการตั้งค่า> สาขาเริ่มต้นและเลือก " หลัก "

จากนั้นหากคุณเลือกคุณสามารถลบสาขาหลัก:

$>git push origin :master


ประเด็นสำคัญที่ต้องเข้าใจก็คือหากคุณให้บริการโฮสติ้ง (GitHub ในตัวอย่างนี้) ไม่มีวิธีการแก้ไขสาขาเริ่มต้นคุณก็โชคไม่ดี โปรโตคอล Git ไม่มีคุณลักษณะในการปรับเปลี่ยนสาขาเริ่มต้นระยะไกล คุณจะต้องสามารถรันgit symbolic-refบนรีโมตเชลล์หรือมิฉะนั้นสามารถแก้ไขไฟล์ข้อความที่เรียกHEADในไดเร็กทอรีรูทที่เก็บรีโมต
Mikko Rantalainen

2

เกี่ยวข้องกับคำถามฉันลงเอยที่นี่เมื่อค้นหา:

ฉันจะทำให้ repo ในพื้นที่ทราบถึงสาขาเริ่มต้นที่เปลี่ยนแปลงบน GitHub ได้อย่างไร

เพื่อความสมบูรณ์ให้เพิ่มคำตอบ:

git remote set-head origin -a

0

สำหรับคน gitolite, gitolite สนับสนุนคำสั่งที่เรียกว่า - รอมัน symbolic-ref- อนุญาตให้คุณรันคำสั่งนั้นจากระยะไกลหากคุณมีสิทธิ์ W (เขียน) ไปยัง repo


-1

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


1
แม้ว่าจะแสดงสาขาใหม่เป็นค่าเริ่มต้นในอินเทอร์เฟซ GitHub แต่เมื่อทำการโคลน git [repo] ฉันไม่ได้รับสาขานั้น เช่น. git / HEAD มีการอ้างอิงที่ไม่ถูกต้อง
Joseph Sheedy
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.