Git: วิธีที่ถูกต้องในการเปลี่ยน Active Branch ในที่เก็บเปลือยหรือไม่


195

ฉันมีที่เก็บเปลือยที่ใช้เป็นร้านค้าส่วนกลางสำหรับโครงการของฉัน นักพัฒนาทั้งหมดทำgit clone <repo>เพื่อแบ่งปันกับมัน เมื่อพวกเขาทำโคลนพวกเขาได้รับเช็คเอาท์สาขาต้นแบบ (ยกเว้นกรณีที่พวกเขาทำgit clone -n) เพราะrepo.git/HEADมีref: refs/heads/masterนี้ทำให้ใช้งานสาขา

คำถามคือฉันจะเปลี่ยนสาขาที่ใช้งานได้อย่างถูกต้องได้อย่างไร? ฉันสามารถแฮ็คrepo.git/HEADไฟล์ได้โดยตรง แต่มันดูน่ารังเกียจและแฮ็คก็ดี

ฉันพยายามทำgit checkout <otherbranch>ใน.gitไดเรกทอรีrepo แต่นั่นล้มเหลวเพราะฉันไม่ได้อยู่ในแผนผังการทำงาน

ฉันพยายามgit update-ref HEAD refs/heads/otherbranchแต่ที่เพิ่งปรับปรุง refs / heads / master ให้เหมือนกับ refs / heads / otherbranch (โอเคฉันทำอันนั้นใน repository dummy ไม่ใช่ Production ของฉัน!)

ฉันพยายามgit update-ref --no-deref HEAD refs/heads/otherbranchและมันก็เกือบจะได้ผล มันปรับปรุงHEADไฟล์ แต่มันตั้งค่าให้ SHA1 refs/heads/otherbranchของกระทำชี้ไปตาม

1.7.0.2.msysgit.0ผมทดสอบกับรุ่นคอมไพล์

ฉันเดาว่าไม่มีวิธีที่จะทำเช่นนี้git pushเพราะการอนุญาตให้ใครต่อใครเปลี่ยนสาขาเริ่มต้นของคุณดูเหมือนจะไม่ปลอดภัย (!) แต่แน่นอนว่ามีวิธีที่ดีกว่าในการทำ.gitไดเรกทอรีrepo มากกว่าแฮ็คHEADไฟล์โดยตรง


IMO คุณเป็นเพียงแค่พยายามทำสิ่งที่ผิดที่นี่ หากคุณต้องการให้สาขาเริ่มต้นเป็นอย่างอื่นนอกเหนือจากหลักดังนั้นสาขานั้นจำเป็นต้องเป็นสาขาหลัก หรือใช้ที่เก็บอื่นสองแห่ง
Nicholas Knight

12
นี่เป็นวิธีพื้นฐานพยายามที่จะทำสิ่งที่ผิดที่นี่? พื้นที่เก็บข้อมูลเปล่ารองรับหลายสาขา ฉันใช้พื้นที่เก็บข้อมูลเปล่าเป็นสำรองไปยังพื้นที่เก็บข้อมูลในท้องถิ่นของฉันและเป็นเช่นสะท้อนสาขา ฉันมีต้นแบบทั้งในและสาขาการพัฒนาทั้ง ถ้าฉันต้องการที่จะเห็นบันทึกของสาขาการพัฒนาบนพื้นที่เก็บข้อมูลเปลือยฉันต้องแฮ็คไฟล์ - ดูเหมือนว่า git นั้นผิดปกติที่นี่เกี่ยวกับการสนับสนุนที่เก็บเปลือย
Cthutu

15
@NicholasKnight IMHO คุณผิดที่นี่ ไม่มีอะไรพิเศษเกี่ยวกับ "master" เป็นชื่อสาขาเป็นเพียงค่าเริ่มต้น ใน respositories ที่ดูแลเราไม่มีสาขาหลักเนื่องจาก "master" ไม่มีความหมายต่อ บริษัท เมื่อใดก็ตามที่เราทำรีลีสเราจะสร้างสาขาการบำรุงรักษาใหม่ด้วยหมายเลขรีลีสใหม่และกำหนดให้เป็นสาขาที่ใช้งานอยู่
Spacemoose

@NicholasKnight ในขณะที่ฉันซาบซึ้งที่คุณมาจากนี้นี่เป็น SO Q / A แรกที่บอกวิธีการเปลี่ยนไปใช้อาจารย์! ฉันมี repo เริ่มต้นในสาขาฟีเจอร์เมื่อฉันทำโคลนเปล่าของฉันและโคลนที่ตามมาจาก repo เปลือยนั้นเริ่มต้นกับสาขานั้นแทนที่จะเป็นต้นแบบ
Warbo

1
ว้าว - คำถามนี้เพิ่งจะเริ่มต้นและดำเนินการ - มันเป็นผู้ทำคะแนนชื่อเสียงอันดับ 1 ของฉัน สิ่งที่เกี่ยวกับ "master" นั้นเป็นเพียงชื่อและถ้าไม่เหมาะสมกับองค์กรทีมโครงการระยะเวลาอะไรก็ตามให้เลือกสิ่งที่เหมาะสมเพื่อที่ว่าเมื่อคุณร่วมมือกันลอกแบบ repo ของคุณทันที ไปยังสาขาที่คุณในฐานะเครื่องมือจัดการการกำหนดค่าต้องการให้พวกเขาเปิด ฉันเคยทำงานกับ ClearCase (bletch!) ดังนั้นตัวเลือกของคุณคือ "main", "main" หรือ "main" จุ๊บ
kbro

คำตอบ:


280

หากคุณมีการเข้าถึง repo เปล่าระยะไกลบทความนี้แนะนำ :

git symbolic-ref HEAD refs/heads/mybranch

ซึ่งจะอัปเดตไฟล์ HEAD ในที่เก็บของคุณเพื่อให้มี:

ref: refs/heads/mybranch

ตามที่ระบุไว้ใน git-symbolic-ref


หากคุณไม่มีสิทธิ์เข้าถึง repo ระยะไกลให้ดู คำตอบก่อนหน้าของฉัน


จำไว้ว่าคำสั่งเช่น git remote set-head :

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

  • ไม่เปลี่ยนแปลงHEADตัวเอง (อีกครั้งเท่านั้นrefs/remotes/<name>/HEAD) git symbolic-refจึงจำเป็นที่จะต้อง

ดังนั้นgit remote set-head ไม่ใช่คำตอบที่นี่
git symbolic-ref HEADคือถ้าคุณเข้าถึง repo ระยะไกลโดยตรง


3
ขอบคุณ! ฉันมีการเข้าถึงโดยตรงไปยัง repo เปลือยระยะไกลดังนั้น git-symbolic-ref จะทำงาน ฉันชอบเคล็ดลับที่ไม่ธรรมดาบรรพบุรุษกล่าวถึงในหัวข้ออื่น ๆ - แน่นอนหนึ่งสำหรับลิ้นชักด้านล่าง ฉันใช้เวลากับ Googling มานานสำหรับสิ่งนี้ แต่ไม่สามารถหาคำตอบก่อนหน้าของคุณได้ แต่ "หัวหน้าหัวหน้า git จากระยะไกล" พบว่ามันเป็นเพลงยอดนิยมอันดับที่สองรองลงมาคือ git-remote (1) แปลกประหลาด เพียงไปเพื่อแสดงว่ามันยากที่จะหาบางสิ่งบางอย่างเมื่อคุณไม่ทราบว่าสิ่งที่คุณกำลังมองหา
kbro

git symbolic-ref HEAD refs/heads/mybranchทำงานได้ดีสำหรับฉัน! ขอขอบคุณ! ;)
vinzenzweber

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

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

@ Magnus ที่จะเป็นคำถามที่ดีของตัวเองถามในหน้าใหม่
VonC

3

ในการเปลี่ยนสาขาคุณจำเป็นต้องเปลี่ยน HEAD อ้างอิงถึงสาขาที่คุณต้องการใช้

รายการแรกการอ้างอิงทั้งหมดในพื้นที่เก็บข้อมูลเปลือยโดยทำ

$find ref

refs/heads/<my_branch>แล้วหาอ้างอิงสำหรับสาขาของรูปแบบจะเป็นดังนี้ ดังนั้นขั้นตอนต่อไปคือการตรวจสอบการอ้างอิงปัจจุบันเพียงพิมพ์:

$git symbolic-ref HEAD

เพื่อให้คุณทราบว่าเป็นสาขาใดในปัจจุบันจากนั้นอัปเดตตามต้องการ

$git sumbolic-ref HEAD ref/heads/<my_branch>

มันเป็นของ สนุก.


2

วิธีการเปลี่ยนสาขาที่ใช้งานถูกต้องหรือไม่

  • สถานะ: การชำระเงิน git ในไดเรกทอรี repo .git ส่งคืนถึงแก่ชีวิต: การดำเนินการนี้ต้องทำงานในแผนผังการทำงาน

  • เคล็ดลับ: เพียงเพิ่มอาร์กิวเมนต์ --work-tree

ตัวอย่างโดยละเอียด: สมมติฐาน: bare git บนรีโมตเซิร์ฟเวอร์:

~ / bare_git_repository.git ต้นไม้งานเดี่ยว: / var / www / myappremote

บนเซิร์ฟเวอร์ภายใน: สร้างสาขาเวอร์ชั่น 1.7 (สาขาอื่นของเรา)

git branch เวอร์ชัน.7.7

git push กำเนิด version.1.7

บนเซิร์ฟเวอร์ระยะไกลที่มี repo เปล่า git:

$ cd ~ / bare_git_repository.git

สาขา $ git


  • เวอร์ชันหลัก1.7

ตามที่ระบุไว้คำสั่งดังต่อไปนี้

git checkout version.1.7

กลับ

ร้ายแรง: การดำเนินการนี้ต้องทำงานในแผนผังการทำงาน

ใช้คำสั่งดังต่อไปนี้

git --work-tree = / var / www / myappremote เช็คเอาต์รุ่น 1.7

เปลี่ยนสาขาได้อย่างคล่องแคล่ว

สาขา $ git

เจ้านาย

  • version.1.7

ตรวจสอบผลลัพธ์ดังต่อไปนี้

ll / var / www / myappremote

หวังว่ามันจะช่วย


โซลูชันที่เรียบง่ายนี้ใช้งานได้สำหรับฉันขอบคุณ! One note: ฉันต้องสร้างไดเรกทอรีต้นไม้ว่างด้วยมือเพื่อให้คำสั่งดำเนินการสำเร็จ
Joël Esponde

-1

นอกจากนี้หากคุณไม่สามารถเข้าถึงที่เก็บเปลือยได้โดยการทำ git remote set-headและทำ

ดูคำตอบก่อนหน้านี้


-3

ฉันยังมี repo เปล่าบนเซิร์ฟเวอร์ของเราและสามารถดึงไฟล์ได้สำเร็จโดยใช้

git clone //server/repo/directory -b branch_name

ลงในที่เก็บโลคัลใหม่แม้ว่า manpage จะบอกว่านี่เป็นเพียงที่เก็บที่ไม่ได้เปลือยเท่านั้น


1
ในขณะที่สิ่งที่คุณพูดนั้นเป็นความจริงความจริงที่ว่าคุณกำลังใช้ -b เพื่อเลือกสาขาเฉพาะแบ่งคำตอบของคุณในบริบทของคำถามของฉันซึ่งเป็นวิธีที่คุณตั้งสาขา DEFAULT
kbro

-4

ฉันเปรียบเทียบสองไดเรกทอรีก่อนและหลังใช้

git symbolic-ref HEAD refs/heads/mybranch

และปรากฏว่ามีการเปลี่ยนแปลงเฉพาะไฟล์ repo.git / HEAD ดังนั้นจึงค่อนข้างปลอดภัยที่จะ "แฮ็ก" ไฟล์


2
มีปัญหาการแตกย่อยที่สามารถแก้ไขได้โดยการแก้ไขไฟล์อ้างอิง Git โดยตรง ฉันขอแนะนำว่า คำสั่งการวางท่อนั้นง่ายกว่าและปลอดภัยกว่าการแก้ไขการอ้างอิงโดยตรง
Alain O'Dea

2
ข้อดีของ @boryn นี้คืออะไร
อเล็กซ์แชมเบอร์เลน

2
Git ติดตามสิ่งต่าง ๆ มากมายในพื้นหลังเหมือนประวัติการอ้างอิง หากคุณเปลี่ยนไฟล์ด้วยตนเองมันจะไม่ถูกบันทึก มันเป็นความจริงที่มันอาจจะไม่สำคัญ แต่ถ้าคุณไม่ทำตามคำมั่นสัญญาและต้องการค้นหาพวกเขาคุณจะมีความสุขมากขึ้นถ้าคุณไม่เพียงแค่ "แฮ็ค" ไฟล์
qwerty9967

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