ย้ายงานที่ไม่มีอยู่แล้วไปยังสาขาใหม่ใน Git


3125

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

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

ฉันต้องการรีเซ็ตสาขาปัจจุบันของฉันในขณะที่รักษางานที่มีอยู่ในคุณสมบัติใหม่


เช่นเดียวกับเรื่องที่น่าสนใจstackoverflow.com/q/556923/269514 ?
Gilberto

คำตอบ:


3640

ใช้สิ่งต่อไปนี้:

git checkout -b <new-branch>

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

git add <files>

และมอบหมายให้สาขาใหม่ของคุณด้วย:

git commit -m "<Brief description of this commit>"

การเปลี่ยนแปลงในไดเรกทอรีการทำงานและการเปลี่ยนแปลงที่เกิดขึ้นในดัชนีไม่ได้เป็นของสาขาใด ๆ สิ่งนี้จะเปลี่ยนสาขาที่การแก้ไขเหล่านั้นจะสิ้นสุดลง

คุณไม่รีเซ็ตสาขาเดิมของคุณก็ยังคงอยู่ตามที่มันเป็น การส่งมอบครั้งสุดท้าย<old-branch>จะยังคงเหมือนเดิม ดังนั้นคุณcheckout -bแล้วกระทำ


อัปเดต 2020 / Git 2.23

Git 2.23 เพิ่มคำswitchสั่งย่อยใหม่ในความพยายามที่จะล้างความสับสนบางส่วนที่มาจากการใช้งานที่มากเกินไปของcheckout(สลับสาขา, การกู้คืนไฟล์, การถอด HEAD เป็นต้น)

เริ่มต้นด้วย Git รุ่นนี้แทนที่คำสั่งด้านบนด้วย:

git switch -c <new-branch>

พฤติกรรมที่เหมือนกันและยังคงไม่เปลี่ยนแปลง


15
เพียงเพื่อให้แน่ใจว่าฉันต้องยอมรับคุณสมบัติที่ยังไม่เสร็จก่อนที่ฉันจะรีเซ็ตสาขาเดิมของฉัน หรือไฟล์ที่ไม่มีข้อผูกมัดเหล่านั้นจะถูกเก็บรักษาไว้โดยไม่คำนึงถึงการกระทำ?
Dane O'Connor

192
FYI: การเปลี่ยนแปลงในไดเรกทอรีการทำงานและการเปลี่ยนแปลงที่เกิดขึ้นในดัชนีไม่ได้อยู่ในสาขา git checkout -b <new branch>การเปลี่ยนแปลงที่มีการเปลี่ยนแปลงเหล่านั้นจะจบลงใน.
ยาคุบบNarębski

152
หากคุณมีสาขาอยู่แล้วและต้องการย้ายการเปลี่ยนแปลงของคุณไปยังสาขาที่มีอยู่ให้เช็คเอาต์stackoverflow.com/questions/556923/…
Chirantan

14
หากคุณต้องการที่จะผลักดันสาขาใหม่ของคุณไปยังพื้นที่เก็บข้อมูลระยะไกล: stackoverflow.com/questions/2765421/…
Dewayne

10
@JDSmith: การเปลี่ยนแปลงที่ไม่ธรรมดาไม่ได้เป็นของสาขาใด ๆ พวกเขาอาศัยอยู่ในไดเรกทอรีการทำงานgit checkout ./ git reset --hardunrecoverably จะเอาพวกเขา
knittl

329

อีกวิธีหนึ่งคือ:

  1. บันทึกการเปลี่ยนแปลงในปัจจุบันเพื่อซ่อนอุณหภูมิ:

    $ git stash

  2. สร้างสาขาใหม่บนพื้นฐานของการสะสมนี้และสลับไปยังสาขาใหม่:

    $ git stash branch <new-branch> stash@{0}

เคล็ดลับ: ใช้ปุ่มแท็บเพื่อลดการพิมพ์ชื่อที่เก็บ


51
หากสาขาอื่น ๆ git stash applyที่มีอยู่แล้วคุณก็สามารถสลับไปกับเช็คเอาต์แล้ว
Archonic

6
ฉันไม่เข้าใจคำแนะนำ "เคล็ดลับ: ใช้ปุ่มแท็บเพื่อลดการพิมพ์ชื่อที่เก็บ" ไม่ใช่ "stash @ {0}" ชื่อใช่หรือไม่ ฉันไม่สามารถรันได้สำเร็จ
เฮอร์เบิร์ต

7
ทำไมจึงดีกว่าคำตอบstackoverflow.com/a/1394804/754997 ที่ยอมรับ?
Chris หน้า

10
ฉันไม่เข้าใจว่าทำไมจึงดีกว่าคำตอบที่ได้รับการยอมรับgit checkout -b <new branch name>
Noitidart

6
คุณไม่จำเป็นต้องไปgit add -Aก่อน stashing
vichle

48

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

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

    git checkout -b <new-feature-branch>
    
  2. ตอนนี้บังคับเดิม "ยุ่ง" สาขาที่จะย้อนกลับ (โดยไม่ต้องเปลี่ยนไป)

    git branch -f <previous-branch> <earlier-commit-id>
    

    ตัวอย่างเช่น:

    git branch -f master origin/master
    

    หรือถ้าคุณได้ทำ 4 มุ่งมั่น:

    git branch -f master HEAD~4
    

คำเตือน: git branch -f master origin/masterจะรีเซ็ตข้อมูลการติดตามสำหรับสาขานั้น ดังนั้นหากคุณกำหนดค่าให้masterสาขาของคุณดันไปที่อื่นนอกจากorigin/masterการกำหนดค่านั้นจะหายไป

คำเตือน:นอกจากนี้ยังมีอันตรายถ้าคุณ rebase หลังจากแยกทางซึ่งเป็นที่อธิบายไว้ที่นี่ วิธีเดียวที่จะหลีกเลี่ยงได้นั่นคือการสร้างประวัติศาสตร์ใหม่โดยใช้ cherry-pick การเชื่อมโยงที่อธิบายวิธีหลักฐานโง่ที่ปลอดภัยที่สุด หากคุณมีการเปลี่ยนแปลงที่ไม่มีข้อผูกมัดคุณอาจต้องการgit stashที่จุดเริ่มต้นและgit stash popตอนท้าย


6
นี่เป็นการตอบคำถามที่แตกต่างไปเล็กน้อยจากสิ่งที่ op ถาม ฉันตัดสินใจที่จะนำคำตอบนี้ที่นี่เพราะนี่คือที่ Google นำฉันเมื่อฉันถูกค้นหาคำตอบ คำถามที่เกิดขึ้นจริงที่เกี่ยวข้องกับสถานการณ์นี้อยู่ที่นี่
joeytwiddle

26

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

git stash 
git checkout master
git checkout -b "New_branch"
git stash apply

18

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

git cherry-pick <commitID>

มีจำนวนมากที่คุณสามารถทำกับเชอร์รี่เลือกตามที่อธิบายไว้ที่นี่แต่นี่อาจเป็นกรณีที่ใช้สำหรับคุณ


2
โซลูชันที่ดีกว่าสำหรับการย้ายการเปลี่ยนแปลงบางส่วนไปยังสาขาใหม่ ... เนื่องจากคุณสามารถกระทำสิ่งที่คุณต้องการในตอนนี้ซ่อนการเปลี่ยนแปลงอื่น ๆ ทั้งหมดตรวจสอบสาขาที่คุณต้องการสาขาจากเชอร์รี่เลือกที่กระทำบนสาขาใหม่กลับไป ไปที่สาขาดั้งเดิมรีเซ็ตฮาร์ดดิสต์การคอมมิทแล้วทำการป๊อปสะสมเพิ่มคอมมิทและร้องเพลงฮัลเลลูยา
เมเรดิ ธ

1
@ เมเรดิ ธ ฮ่า ๆ ๆ ๆ ๆ ๆ นี่เป็นสิ่งที่ดีมากเว้นแต่คุณจะวางแผนการเปลี่ยนแปลงในอนาคต ... และใครเป็นคนทำ;)
รหัสผ่าน

1

สิ่งนี้อาจเป็นประโยชน์สำหรับทุกคนที่ใช้เครื่องมือสำหรับ GIT

คำสั่ง

สลับสาขา - มันจะย้ายการเปลี่ยนแปลงของคุณไปยังสาขาใหม่ จากนั้นคุณสามารถกระทำการเปลี่ยนแปลง

 $ git checkout -b <new-branch>

TortoiseGIT

คลิกขวาที่ที่เก็บของคุณจากนั้นใช้ TortoiseGit-> Switch / Checkout

ป้อนคำอธิบายรูปภาพที่นี่ ป้อนคำอธิบายรูปภาพที่นี่

SourceTree

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

ป้อนคำอธิบายรูปภาพที่นี่


0

ฉันใช้@Robinตอบ & แสดงรายการทั้งหมดที่ฉันทำ

git status                               <-- review/list uncommitted changes
git stash                                <-- stash uncommitted changes
git stash branch <new-branch> stash@{1}  <-- create a branch from stash
git add .                                <-- add local changes
git status                               <-- review the status; ready to commit
git commit -m "local changes ..."        <-- commit the changes
git branch --list                        <-- see list of branches incl the one created above
git status                               <-- nothing to commit, working tree (new-branch) is clean
git checkout <old-branch>                <-- switch back

! หาก repo มีที่ซ่อนมากกว่าหนึ่งตัวให้ดูที่อันไหนที่จะนำไปใช้กับสาขาใหม่:

git stash list  
  stash@{0}: WIP on ...  
  stash@{1}: WIP on ...

และตรวจสอบที่ซ่อนของแต่ละคนโดย

git stash show stash@{1}

หรือตรวจสอบการหยุดทั้งหมดในครั้งเดียว:

git stash list -p

0

จริงๆแล้วมันมีวิธีง่ายๆในการทำเช่นนี้กับ GitHub Desktop ตอนนี้ฉันไม่เชื่อว่าเป็นคุณสมบัติก่อนหน้านี้

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

GitHub Desktop

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