สร้างสาขา Git ด้วยการเปลี่ยนแปลงปัจจุบัน


848

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

ฉันจะสร้างสาขาใหม่และรับการเปลี่ยนแปลงทั้งหมดเหล่านี้กับฉันได้อย่างไรโดยไม่ต้องมีเจ้านายที่สกปรก


12
ซ้ำซ้อนที่เป็นไปได้ของการย้ายที่มีอยู่แล้วงานที่ไม่
ธรรมดา

2
ทวีคูณของstackoverflow.com/questions/2569459/…
andrej

4
ใช่เหล่านี้เป็นคำถามที่ซ้ำกัน แต่การใช้ถ้อยคำแตกต่างกันมากจนฉันคิดว่ามันมีประโยชน์ในการรักษา หมายเหตุ: คำหลักที่นี่: VSbranch current changes existing uncommited branchทุกคนที่พูดภาษาอังกฤษจะเห็นทันทีว่าพวกเขาเหมือนกัน แต่เครื่องมือค้นหาอาจจะไม่ เก็บคำถามนี้ไว้
Scott Biggs

คำตอบ:


691

หากคุณยังไม่ได้ทำอะไรเลยเพียง (1: สาขา) และ (3: เช็คเอาต์) จะเพียงพอ
หรือในหนึ่งคำสั่ง:git checkout -b newBranch

ดังที่ได้กล่าวไว้ในgit resetman page :

$ git branch topic/wip     # (1)
$ git reset --hard HEAD~3  # (2)  NOTE: use $git reset --soft HEAD~3 (explanation below)
$ git checkout topic/wip   # (3)
  1. คุณได้ทำอะไรบางอย่าง แต่รู้ตัวว่ามันเร็วmasterเกินไปที่จะอยู่ในสาขา "" คุณต้องการที่จะดำเนินการต่อไปขัดพวกเขาในสาขาหัวข้อเพื่อสร้าง " topic/wipสาขา" HEADออกจากปัจจุบัน
  2. กรอกลับmasterสาขาเพื่อกำจัดการกระทำทั้งสาม
  3. สลับไปที่topic/wipสาขา "" และทำงานต่อไป

หมายเหตุ: เนื่องจากผลกระทบของ "การทำลายล้าง" ของgit reset --hardคำสั่ง (จะรีเซ็ตดัชนีและแผนผังการทำงานการเปลี่ยนแปลงใด ๆ กับไฟล์ที่ถูกติดตามในแผนผังการทำงานตั้งแต่<commit>ถูกทิ้ง) ฉันอยากจะไปกับ:

$ git reset --soft HEAD~3  # (2)

สิ่งนี้จะทำให้แน่ใจว่าฉันจะไม่สูญเสียไฟล์ส่วนตัวใด ๆ (ไม่ได้เพิ่มไว้ในดัชนี) ตัวเลือกที่จะไม่สัมผัสแฟ้มดัชนีมิได้ต้นทำงานเลย ( แต่รีเซ็ตหัวเช่นเดียวกับทุกโหมดทำ)
--soft<commit>


ด้วยGit 2.23+ที่คำสั่งใหม่git switchจะสร้างสาขาในหนึ่งบรรทัด (ที่มีชนิดเดียวกันreset --hardดังนั้นจงระวังของผลกระทบของมัน):

git switch -f -c topic/wip HEAD~3

6
อาจเป็นเรื่องที่น่าสังเกตว่านี่จะไม่เป็นความคิดที่ดีหากคุณกำหนดเนื้อหาหัวข้อให้กับสาขาหลักของคุณในที่เก็บข้อมูลที่คนอื่นดึงมา หรืออย่างน้อยถ้าคุณจำเป็นต้องทำการรีเซ็ตคุณจะต้องบอกผู้คนว่านั่นคือสิ่งที่คุณกำลังทำอยู่ดังนั้นคำเตือนจากการดึงครั้งต่อไปของพวกเขาจะไม่ทำให้ตกใจจนเกินไป
Andrew Walker

39
หมายเหตุถึงผู้อ่านในอนาคต: อ่านจากล่างขึ้นบน (หรืออ่านทั้งหมด) git reset --hardจะทำการเปลี่ยนแปลงของคุณและหากพวกเขายังไม่ได้ยืนยันพวกเขาจะไม่สามารถกู้คืนได้! คุณอาจต้องการgit checkout -b …
Conrad Meyer

3
@ConradMeyer เป็นจุดที่ดี ฉันได้แก้ไขคำตอบและใส่คำตอบgit checkout -bแรก
VonC

5
ทำไมต้องเป็นหัวข้อ / สาขา? ทำไมไม่เพียง branchname มีเหตุผลพิเศษสำหรับการตั้งชื่อนี้หรือไม่? เพียงแค่สงสัย.
Sam Stoelinga

1
@It เป็นเพียงการประชุม namespace ตั้งชื่อ (วิธีการสาขาประเภทได้อย่างง่ายดายโดยใช้ลำดับชั้นชื่อสาขาที่จะกำหนด namespaces): stackoverflow.com/a/2527436/6309 ยกตัวอย่างเช่นสำหรับปัญหา: randyfay.com/content/... คุณไม่ต้องใช้ลำดับชั้นเมื่อทำการแยกสาขาของคุณ topic_wipจะทำงานด้วย;)
VonC

269

เช่นเดียวกับที่ระบุไว้ในคำถามนี้: Git: สร้างสาขาจากการเปลี่ยนแปลงแบบไม่มีการสแต็ก / ไม่มีข้อผูกมัดบนต้นแบบ : ไม่จำเป็นต้องมีการซ่อน

เพียงใช้:

git checkout -b topic/newbranch

งานที่ไม่มีข้อผูกมัดใด ๆ จะถูกนำไปที่สาขาใหม่

หากคุณพยายามที่จะผลักดันคุณจะได้รับข้อความต่อไปนี้

ร้ายแรง: คุณลักษณะสาขาปัจจุบัน / NEWBRANCH ไม่มีสาขาอัปสตรีม เพื่อผลักดันสาขาปัจจุบันและตั้งค่ารีโมตเป็นอัปสตรีมใช้

git push --set-upstream origin feature/feature/NEWBRANCH

ทำตามคำแนะนำเพื่อสร้างสาขาจากระยะไกล:

git push --set-upstream origin feature/feature/NEWBRANCH


3
คุณจะได้รับข้อผิดพลาด 'ไม่มีสาขาต้นน้ำ' เฉพาะเมื่อคุณผลักสาขาใหม่ไม่ใช่เมื่อคุณส่งงานใหม่
แซม

2
@ Sam ฉันได้แก้ไขคำตอบแล้ว
Nick Kennedy

73

ทำตามขั้นตอนเหล่านี้:

  1. สร้างสาขาใหม่:

    git branch newfeature
    
  2. ชำระเงินที่สาขาใหม่: (สิ่งนี้จะไม่รีเซ็ตงานของคุณ)

    git checkout newfeature
    
  3. ตอนนี้ทำงานของคุณในสาขาใหม่นี้:

    git commit -s
    

การใช้ขั้นตอนข้างต้นจะทำให้สาขาเดิมของคุณสะอาดและคุณไม่จำเป็นต้องทำ 'รีเซ็ต git - ฮาร์ด'


3
'-s' ทำอะไรในขั้นตอนที่ 3
Scott Biggs

12
@ScottBiggs มันไม่จำเป็น แต่เป็นการฝึกที่บางคนติดตาม มันสั้นสำหรับ "--signoff"และเพิ่มชื่อผู้ใช้ของคุณเพื่อกระทำสำหรับคนในอนาคตที่ดูบันทึกเพื่อทราบว่าคุณได้ยกเลิกการกระทำนี้
Frank Bryce

5
คำตอบที่ดี แต่ไม่จำเป็นต้องทำ-sในขั้นตอนที่ 3
Mohammed Ali

ฉันเรียนรู้สิ่งใหม่จากความคิดเห็นขอบคุณ @FrankBryce
Kasparov92

30

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

git stash  # save local modifications to new stash
git checkout -b topic/newbranch
git stash pop  # apply stash and remove it from the stash list

9
หรือตามที่ VonC ชี้ให้เห็น 'การชำระเงิน git -b newbranch' และข้าม stash
willcodejavaforfood

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

1
ฉันลองแล้วมันใช้งานได้ดีคอมไพล์คิดอย่างมากและไม่เขียนทับการเปลี่ยนแปลงในท้องถิ่นใด ๆ
willcodejavaforfood

2
ฉันคิดว่ามันเป็นตัวพิมพ์ผิด แต่หัวขึ้นเท่านั้นที่git stash pushไม่ใช่คำสั่ง คุณคงจะต้องการใช้หรือgit stash git stash saveหากคุณต้องการรวมไฟล์ที่ไม่ได้ติดตามในที่เก็บของให้ใช้--include-untrackedตัวเลือก ในทำนองเดียวกันหากคุณต้องการรวมไฟล์ที่ไม่ได้ติดตามและไม่สนใจในที่เก็บของให้ใช้--addตัวเลือกแทน
หก

ในกรณีที่คุณสร้างสาขาแล้วสิ่งนี้จะเป็นประโยชน์
แน่นอน

13

หากต้องการเพิ่มการเปลี่ยนแปลงใหม่ในสาขาใหม่และกดไปที่รีโมต:

git branch branch/name
git checkout branch/name
git push origin branch/name

บ่อยครั้งที่ฉันลืมเพิ่มส่วนต้นกำเนิดเพื่อผลักดันและสับสนว่าทำไมฉันไม่เห็นสาขาใหม่ / กระทำใน bitbucket

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