วิธีสร้างสาขาจากการคอมมิตเฉพาะในสาขาต่างๆ


109

ฉันได้ทำการคอมมิตหลายครั้งในสาขาหลักแล้วรวมเข้ากับสาขา dev

ฉันต้องการสร้างสาขาจากการคอมมิตเฉพาะในสาขา dev ซึ่งถูกกำหนดครั้งแรกในสาขาหลัก

ฉันใช้คำสั่ง:

git checkout dev
git branch  <branch name> <commit id>

อย่างไรก็ตามสิ่งนี้จะสร้างสาขาจากสาขาหลักไม่ใช่สาขา dev ที่ฉันคาดไว้ รหัสการคอมมิตจะเหมือนกันในสาขาหลักและสาขาการพัฒนา ดังนั้นฉันจะแยกแยะรหัสคอมมิตเดียวกันในสาขาอื่นได้อย่างไร

PS: ฉันสร้างตัวอย่างใน github ที่นี่https://github.com/RolandXu/test_for_branch

ฉันใช้คำสั่ง:

git checkout dev
git branch test 07aeec983bfc17c25f0b0a7c1d47da8e35df7af8

สิ่งที่ฉันคาดหวังคือสาขาทดสอบมี aa.txt bb.txt cc.txt อย่างไรก็ตามสาขาการทดสอบประกอบด้วย aa.txt และ cc.txt เท่านั้น เป็นไปได้มากว่าจะสร้างสาขาจากสาขาหลัก

คำตอบ:


154

หากคุณใช้branchคำสั่งรูปแบบนี้(พร้อมจุดเริ่มต้น) ไม่สำคัญว่าคุณHEADจะอยู่ที่ไหน

คุณกำลังทำอะไรอยู่:

git checkout dev
git branch test 07aeec983bfc17c25f0b0a7c1d47da8e35df7af8
  • ครั้งแรกที่คุณตั้งค่าของคุณHEADไปยังสาขาdev,

  • 07aeec98ประการที่สองคุณเริ่มต้นสาขาใหม่ในการกระทำ ไม่มี bb.txt ที่คอมมิตนี้ (อ้างอิงจาก github repo ของคุณ)

หากคุณต้องการเริ่มสาขาใหม่ในสถานที่ที่คุณเพิ่งเช็คเอาต์คุณสามารถเรียกใช้สาขาโดยไม่มีจุดเริ่มต้น:

git branch test

หรือตามที่คนอื่นได้ตอบสาขาและชำระเงินที่นั่นในการดำเนินการเดียว:

git checkout -b test

ผมคิดว่าคุณอาจจะสับสนโดยความเป็นจริงว่าเป็นส่วนหนึ่งของสาขา07aeec98 devมันเป็นความจริงที่ว่านี้กระทำเป็นบรรพบุรุษของการเปลี่ยนแปลงของมันมีความจำเป็นที่จะไปถึงล่าสุดกระทำในdev devแต่พวกเขาจะกระทำอื่น ๆ ที่มีความจำเป็นในการเข้าถึงล่าสุดและสิ่งเหล่านี้ไม่จำเป็นต้องมีในประวัติศาสตร์ของdev07aeec98

8480e8ae(ที่คุณเพิ่ม bb.txt) เป็นตัวอย่างที่ไม่อยู่ในประวัติของ07aeec98. หากคุณสาขาจากคุณจะไม่ได้รับการเปลี่ยนแปลงที่นำโดย07aeec988480e8ae

กล่าวอีกนัยหนึ่ง: ถ้าคุณรวมสาขา A และสาขา B เข้ากับสาขา C จากนั้นสร้างสาขาใหม่โดยใช้ข้อตกลง A คุณจะไม่ได้รับการเปลี่ยนแปลงที่นำมาใช้ใน B

ที่นี่คุณมีสาขาหลักและ dev สองสาขาขนานกันซึ่งคุณรวมเข้ากับ dev การแยกสาขาออกจากการกระทำของต้นแบบ (เก่ากว่าการผสาน) จะไม่ทำให้คุณมีการเปลี่ยนแปลงของ dev


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

หากคุณไม่ได้รับการตีพิมพ์สาขาคุณลักษณะของคุณคุณยังสามารถ rebase git rebase master featureAพวกเขาในต้นแบบที่ปรับปรุง: เตรียมพร้อมที่จะแก้ปัญหาความขัดแย้งที่อาจเกิดขึ้น

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

  • ยึดทุกสาขาคุณลักษณะใหม่ตามการกระทำของต้นแบบ
  • สร้างdevสาขาบนความมุ่งมั่นของอาจารย์
  • เมื่อคุณต้องการดูว่าสาขาคุณลักษณะของคุณรวมเข้ากับการเปลี่ยนแปลงใหม่ในต้นแบบอย่างไรให้รวมทั้งหลักและสาขาคุณลักษณะเข้าdevด้วยกัน

อย่าผูกมัดdevโดยตรงใช้สำหรับการรวมสาขาอื่นเท่านั้น

ตัวอย่างเช่นหากคุณกำลังใช้งานคุณลักษณะ A และ B:

a---b---c---d---e---f---g -master
    \       \
     \       \-x -featureB
      \
       \-j---k -featureA

รวมสาขาเข้ากับdevสาขาเพื่อตรวจสอบว่าทำงานได้ดีกับต้นแบบใหม่หรือไม่:

a---b---c---d---e---f---g -master
    \       \            \
     \       \            \--x'---k' -dev
      \       \             /    /   
       \       \-x----------    /    -featureB
        \                      /
         \-j---k--------------- -featureA

คุณสามารถดำเนินการต่อในสาขาคุณลักษณะของคุณและทำการรวมการเปลี่ยนแปลงใหม่ ๆ จากทั้งสาขาหลักและสาขาคุณลักษณะเข้าdevด้วยกันเป็นประจำ

a---b---c---d---e---f---g---h---i----- -master
    \       \            \            \
     \       \            \--x'---k'---i'---l' -dev
      \       \             /    /         /
       \       \-x----------    /         /  -featureB
        \                      /         /  
         \-j---k-----------------l------ -featureA

เมื่อถึงเวลาที่จะรวมคุณสมบัติใหม่ให้รวมสาขาฟีเจอร์ (ไม่ใช่dev!) เข้ากับมาสเตอร์


ขอบคุณ. คุณตอบคำถามของฉัน ฉันเข้าใจผิดเกี่ยวกับโหมดสาขาคอมไพล์ และคุณมีข้อเสนอแนะสำหรับปัญหาของฉันหรือไม่ ฉันมีสาขาหลักที่มีการกระทำหลายครั้งจากผู้อื่น (ซิงค์กับ perforce) ฉันมีสาขา dev ฉันทำงานส่วนตัว ฉันต้องการสาขาที่มีคอมมิตทั้งหมดจากสาขาหลักและสาขาผู้พัฒนาจากนั้นฉันสามารถสร้างสาขาตามสาขานี้ได้อย่างง่ายดายจากนั้นจึงเริ่มทำงานเฉพาะ
RolandXu

ฉันไม่สามารถตอบในความคิดเห็นได้ดังนั้นฉันจึงอัปเดตคำตอบด้วยเวิร์กโฟลว์ที่แนะนำ
Gauthier

สวัสดี - ขอบคุณสำหรับคำตอบที่ยอดเยี่ยมและละเอียดถี่ถ้วน! แค่อยากรู้: ในท้ายที่สุดทำไมต้องเป็นเช่นนั้นmerge the feature branches (not dev!) into master?
cassi.lup

ไม่มีการพัฒนาใหม่จริงในdevสาขา คุณควรคงคุณลักษณะเฉพาะสาขาไว้ devมีเฉพาะการรวมคอมมิต การผสานคุณสมบัติใหม่ทั้งหมดmasterเข้าด้วยกันเป็นเรื่องที่สมเหตุสมผลมากกว่าการรวมคุณสมบัติเข้าด้วยกันแล้วรวมผลลัพธ์เข้าmasterด้วยกัน
Gauthier

@Gauthier คุณไม่ได้ตอบคำถามว่าทำไม สำหรับผมแล้วมันเสียงเหมือนการรวมdevที่มีคุณสมบัติเพียงA BและCผสานเข้ามันกลายmasterเป็นเหมือนการรวมเป็นรายบุคคลA Bและเข้าไปในC masterถ้าไม่นั่นท้าทายความเข้าใจของฉันว่าคอมไพล์ทำงานอย่างไรและฉันก็อยากรู้มากว่าทำไม!
Steven Lu

57

คุณมีข้อโต้แย้งในลำดับที่ไม่ถูกต้อง:

git branch <branch-name> <commit>

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

หากคุณต้องการตรวจสอบสาขาใหม่ในขณะที่คุณสร้าง:

git checkout -b <branch> <commit>

ด้วยพฤติกรรมเดียวกันหากคุณละเว้นอาร์กิวเมนต์กระทำ


27

คุณสามารถทำได้ในพื้นที่ตามที่ทุกคนกล่าวถึงโดยใช้

git checkout -b <branch-name> <sha1-of-commit>

หรือคุณสามารถทำได้ใน github เองโดยทำตามขั้นตอน:

1- ในที่เก็บคลิกที่ไฟล์Commits.

2- ในการคอมมิตที่คุณต้องการแตกแขนงให้คลิก<>เพื่อเรียกดูที่เก็บ ณ จุดนี้ในประวัติ

สร้างประวัติศาสตร์

3- คลิกtree: xxxxxxที่ด้านซ้ายบน เพียงพิมพ์ชื่อสาขาใหม่คลิกที่Create branch xxxรูปด้านล่าง

สร้างสาขาใหม่

ตอนนี้คุณสามารถดึงการเปลี่ยนแปลงจากสาขานั้นในเครื่องและดำเนินการต่อจากที่นั่น


นี่คือสิ่งที่ฉันต้องการ .. วิธีการทำในเว็บไซต์
eharo2

ฉันไม่เคยรู้เลย นี่ไง. สิ่งที่ GUI นั้นยอดเยี่ยมมากและฉันอยากจะห่างจาก CLI
Rohit Gupta

11

ลอง

git checkout <commit hash>
git checkout -b new_branch

การคอมมิตควรมีอยู่เพียงครั้งเดียวในทรีของคุณไม่ใช่ในสองสาขาที่แยกจากกัน

สิ่งนี้ช่วยให้คุณตรวจสอบการกระทำที่เฉพาะเจาะจงและตั้งชื่อสิ่งที่คุณต้องการ


สวัสดีฉันลอง git log dev และ git log master ฉันพบว่ารหัสแฮชคอมมิตนั้นเหมือนกันสำหรับการคอมมิตที่ฉันรวมกับสาขา dev จากสาขาหลัก
RolandXu

อาจช่วยได้ในการใช้บางอย่างเช่นgitkเพื่อให้เห็นภาพบันทึกของคุณ
ZMorek

ฉันเพิ่งเพิ่มตัวอย่างใน github และ Gauthier ตอบคำถามของฉันแล้วว่าฉันเข้าใจผิดเกี่ยวกับโหมดสาขาคอมไพล์ ขอบคุณ :)
RolandXu

นี่คือคำตอบที่ชัดเจนที่ฉันคิด ขอบคุณ
virusss8

9

คุณต้องทำ:

git branch <branch_name> <commit>

(คุณกำลังเปลี่ยนชื่อสาขาและยอมรับ)

หรือคุณสามารถทำได้:

git checkout -b <branch_name> <commit>

หากคุณใช้ชื่อสาขาแทนคุณจะได้กิ่งก้านออกจากปลายกิ่ง


นั่นไม่ใช่สิ่งที่HEADหมายถึง คุณสามารถพูดว่า "ปลายกิ่ง" หรือ "คอมมิตที่สาขาชี้ไป" แทน
Cascabel

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