ย้ายไฟล์ที่เปลี่ยนแปลงไปยังสาขาอื่นเพื่อเช็คอิน


422

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

คำตอบ:


751

git stash เป็นเพื่อนของคุณ.

git stashหากคุณยังไม่ได้กระทำยังทำงานเพียง นี่จะเป็นการบันทึกการเปลี่ยนแปลงทั้งหมดของคุณ

git stash popสลับไปยังสาขาที่คุณต้องการเปลี่ยนแปลงบนและเรียกใช้

มีประโยชน์มากมายสำหรับการสะสมคอมไพล์ นี่เป็นหนึ่งในเหตุผลที่มีประโยชน์มากขึ้นอย่างแน่นอน

ตัวอย่าง:

# work on some code
git stash
git checkout correct-branch
git stash pop

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

2
ฉันได้รับสิ่งนี้ ดังนั้นฉันต้องซ่อนสลับสาขาแล้วป๊อป C:\kf [develop +0 ~4 -0]> git checkout feature/customers<br/> error: Your local changes to the following files would be overwritten by checkout:<br/> AspWebApp.vNext/global.asa<br/> RestApi/Web.config<br/> Please, commit your changes or stash them before you can switch branches.<br/> Aborting
IsmailS

3
@Tekkub "การจัดเก็บสิ่งชั่วคราวในระยะยาว" ที่บอกว่ารู้สึกอึดอัดใจมากจุดอื่นที่ใช้ stash คือมันดันเข้าไปในสแต็กดังนั้นหากคุณไม่ต้องการให้มันพกติดตัวและทำงานอย่างอื่นมันมีประโยชน์ในทางนั้น . ใช่คุณไม่ต้องทำ แต่รู้สึกสะอาดและควบคุมได้มากกว่า
Atherion

ไชโยที่รัก! ควรผนวกสิ่งที่คุณควรทำถ้าคุณทำคอมมิชชัน
Ishan Srivastava

2
@Tekkub นั่นเป็นความจริงเฉพาะเมื่อสาขาที่คุณกำลังเปลี่ยนเป็นสาขาล่าสุดกับสาขาที่คุณเปิด ตัวอย่างเช่นหากคุณกำลังทำงานกับสาขาแยงโดยไม่ตั้งใจและจำเป็นต้องเปลี่ยนเป็นสาขาสเตจ แต่สเตจเปลี่ยนไปในช่วงเวลาเฉลี่ยเป็นวิธีเดียวในการสร้างสวิตช์
danielson317

248

หากคุณยังไม่ยืนยันการเปลี่ยนแปลงของคุณเพียงแค่ใช้git checkoutเพื่อย้ายไปยังสาขาใหม่จากนั้นให้คอมมิชชันตามปกติ - การเปลี่ยนแปลงไฟล์จะไม่เชื่อมโยงกับสาขาใดสาขาหนึ่งจนกว่าคุณจะยอมรับ

หากคุณมีความมุ่งมั่นแล้วการเปลี่ยนแปลงของคุณ:

  1. พิมพ์git logและจดจำ SHA ของการส่งข้อความที่คุณต้องการย้าย
  2. ตรวจสอบสาขาที่คุณต้องการย้ายการกระทำ
  3. พิมพ์การgit cherry-pick SHAแทนที่ SHA จากด้านบน
  4. เปลี่ยนกลับเป็นสาขาเดิมของคุณ
  5. ใช้git reset HEAD~1ในการรีเซ็ตกลับก่อนที่จะกระทำผิดสาขาของคุณ

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


9
คุณไม่ควรจะต้องเลือกเชอร์รี่ที่นี่ด้วยซ้ำ git reset HEAD~N --softและจากนั้นgit checkout -bจะย้ายทั้งหมดในขณะนี้รหัสปราศจากข้อผูกมัดกับสาขาใหม่
แอรอน

19
การเปลี่ยนแปลงในไฟล์จะไม่เชื่อมโยงกับสาขาใดสาขาหนึ่งจนกว่าคุณจะยอมรับ <- นี่ นี่เป็นการไขปริศนาให้ฉัน ขอบคุณ
Tschallacka

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

3
@Mischa มันไม่ทำงานหากคุณสลับระหว่างสองสาขาที่มีประวัติแตกต่างกัน
watashiSHUN

1
@Aaron นั้นดีกว่ามาก (สำหรับสถานการณ์หลังเกิดเหตุการณ์)! กรุณาตอบแยกต่างหาก
Jacktose

16

น่าเศร้าที่สิ่งนี้เกิดขึ้นกับฉันค่อนข้างสม่ำเสมอเช่นกันและฉันใช้git stashถ้าฉันตระหนักถึงความผิดพลาดของฉันก่อนหน้านี้git commitและใช้เป็นgit cherry-pickอย่างอื่นทั้งสองคำสั่งจะอธิบายได้ดีในคำตอบอื่น ๆ

ฉันต้องการเพิ่มความกระจ่างสำหรับgit checkout targetBranch: คำสั่งนี้จะเก็บรักษาไดเรกทอรีการทำงานของคุณและสแน็ปช็อตที่จัดฉากหาก targetBranch มีประวัติเดียวกับสาขาปัจจุบันของคุณ

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

@ คำสั่งของแอมเบอร์ไม่ได้เป็นเท็จเมื่อคุณย้ายไปยังnewBranch , git checkout -b newBranchตัวชี้ใหม่ถูกสร้างขึ้นและมันจะชี้ไปที่เดียวกันแน่นอนกระทำเป็นสาขาในปัจจุบันของคุณ
ในความเป็นจริงหากคุณมีสาขาอื่นที่แบ่งปันประวัติกับสาขาปัจจุบันของคุณ (ทั้งสองจุดที่กระทำเดียวกัน) คุณสามารถ "ย้ายการเปลี่ยนแปลง" โดยgit checkout targetBranch

อย่างไรก็ตามโดยทั่วไปแล้วสาขาที่แตกต่างหมายถึงประวัติที่แตกต่างกันและ Git จะไม่อนุญาตให้คุณสลับระหว่างสาขาเหล่านี้ด้วยไดเรกทอรีทำงานที่สกปรกหรือพื้นที่จัดเตรียม ในกรณีที่คุณสามารถทำได้git checkout -f targetBranch(การเปลี่ยนแปลงที่สะอาดและไม่ถูกโยนทิ้ง) หรือgit stage+ git checkout targetBranch(ทำความสะอาดและบันทึกการเปลี่ยนแปลง) เพียงแค่เรียกใช้git checkout targetBranchจะทำให้เกิดข้อผิดพลาด:

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


5

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

  1. git reset --soft <commit>

  2. git checkout <branch>

  3. git commit -m "Commit message goes here"

จากgit docs :

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

--softห้ามแตะไฟล์ดัชนีหรือแผนผังการทำงานเลย (แต่จะรีเซ็ตส่วนหัวเป็นเหมือนทุกโหมดที่ทำได้) สิ่งนี้จะทำให้ไฟล์ที่ถูกเปลี่ยนแปลงทั้งหมดของคุณ "การเปลี่ยนแปลงที่จะเกิดขึ้น" เนื่องจากสถานะคอมไพล์จะนำมาไว้

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