ฉันต้องการใช้การเปลี่ยนแปลงที่เกิดขึ้นในสาขาหนึ่งกับอีกสาขาหนึ่ง ฉันสามารถใช้เชอร์รี่เลือกเพื่อทำสิ่งนั้นได้ อย่างไรก็ตามในกรณีของฉันฉันต้องการใช้การเปลี่ยนแปลงที่เกี่ยวข้องกับไฟล์เดียวเท่านั้นฉันไม่จำเป็นต้องเลือกคอมมิตทั้งหมด ต้องทำอย่างไร?
ฉันต้องการใช้การเปลี่ยนแปลงที่เกิดขึ้นในสาขาหนึ่งกับอีกสาขาหนึ่ง ฉันสามารถใช้เชอร์รี่เลือกเพื่อทำสิ่งนั้นได้ อย่างไรก็ตามในกรณีของฉันฉันต้องการใช้การเปลี่ยนแปลงที่เกี่ยวข้องกับไฟล์เดียวเท่านั้นฉันไม่จำเป็นต้องเลือกคอมมิตทั้งหมด ต้องทำอย่างไร?
คำตอบ:
คุณมีตัวเลือกต่างๆตามสิ่งที่คุณต้องการบรรลุ:
หากคุณต้องการให้เนื้อหาของไฟล์เหมือนกับสาขาเป้าหมายคุณสามารถใช้git checkout <branch> -- <filename>ไฟล์. อย่างไรก็ตามสิ่งนี้จะไม่ "เลือกเชอร์รี่" การเปลี่ยนแปลงที่เกิดขึ้นในคอมมิตเดียว แต่ใช้สถานะผลลัพธ์ของไฟล์ดังกล่าวเท่านั้น ดังนั้นหากคุณเพิ่มบรรทัดในการคอมมิต แต่การคอมมิตก่อนหน้านั้นเปลี่ยนแปลงมากขึ้นและคุณต้องการเพิ่มบรรทัดนั้นโดยไม่มีการเปลี่ยนแปลงอื่น ๆ การชำระเงินก็ไม่ใช่สิ่งที่คุณต้องการ
มิฉะนั้นหากคุณต้องการใช้โปรแกรมแก้ไขที่แนะนำในการคอมมิตกับไฟล์เดียวคุณมีหลายตัวเลือก คุณสามารถเรียกใช้git cherry-pick -nงานได้เช่นโดยไม่ต้องคอมมิตแก้ไขคอมมิต (ตัวอย่างเช่นรีเซ็ตไฟล์ทั้งหมดโดยใช้git reset -- .และเพิ่มเฉพาะไฟล์ที่คุณต้องการเปลี่ยนโดยใช้git add <filename>เท่านั้น) หรือคุณสามารถสร้างความแตกต่างสำหรับไฟล์และใช้ความแตกต่างจากนั้น:
git diff <branch>^..<branch> -- <filename> | git apply
สร้างpatch fileและนำไปใช้
git diff branchname -- filename > patchfile
git apply patchfile
แก้ไข:
เนื่องจากคุณต้องทำการเปลี่ยนแปลงจากคอมมิตให้สร้างแพตช์ดังนี้:
git show sha1 -- filename > patchfile
git diff sha1(หรือgit diff branch- ก็เหมือนกันถ้าสาขาชี้ไปที่แฮชเดียวกัน) จะสร้างความแตกต่างของไดเร็กทอรีการทำงานปัจจุบันที่สัมพันธ์กับแฮชนั้นเท่านั้น แต่ไม่ใช่สิ่งที่เปลี่ยนแปลงคอมมิตที่แนะนำด้วยตัวมันเอง
git checkoutมีชื่อไฟล์เป็นค้อนที่เหมาะสมสำหรับตะปูนี้ ทั้งสองตัวเลือกเหล่านี้มีความซับซ้อนโดยไม่จำเป็น
checkoutจะไม่ทำงานเนื่องจากอาจเกี่ยวข้องกับการเปลี่ยนแปลงก่อนหน้าอื่น ๆ ที่ไม่ต้องการและอาจไม่มีการเปลี่ยนแปลงที่เกิดขึ้นในสาขาปัจจุบัน
สิ่งที่สะดวกอีกอย่างที่ต้องทำคือรับโปรแกรมแก้ไขในเครื่องจากนั้นใช้:
git checkout {<name_of_branch>, commit's SHA} <path to the file>
นั่นไม่ใช่การเก็บเชอร์รี่
Git มีทุกอย่างพร้อม :)
เพียงแค่ใช้
git checkout <sha> <path-to-file>
git checkout the_branch_with_the_change the/path/to/the/file/you/want.extension
วิธีนี้ใช้งานได้ถ้าคุณต้องการให้ไฟล์เดียวจากสาขาอื่นถูกคัดลอกไปยังสาขาการทำงานปัจจุบัน
นี่คือสิ่งที่คุณกำลังมองหา:
git checkout target-branch sha1 path/to/file
sha1 เป็นทางเลือก
สิ่งที่ฉันมักจะทำคือการใช้ git ls-tree
แค่ทำ:
git ls-tree -r <commit-id> |grep 'your filename'
# there will be output that shows a SHA1 of your file
git show ${SHA1 of your file} > 'your filename'
สิ่งนี้จะพิมพ์ชื่อไฟล์ทั้งหมดที่ตรงกับ grep ของคุณและให้คีย์ SHA1 ของไฟล์ในคอมมิต
Git show สามารถใช้กับไฟล์ภายนอกสาขาของคุณได้เช่นกัน การใช้>จากเชลล์ของคุณเพื่อไพพ์เอาต์พุตลงในไฟล์ทำให้คุณได้ผลลัพธ์ที่คุณต้องการ
คุณสามารถลองทำสิ่งนี้:
git show COMMIT_ID -- path/to/specific-file | git apply
ตัวอย่างเช่น:
git show 3feaf20 -- app/views/home/index.html | git apply
git reset HEAD~1
ย้ายไฟล์ไปไว้ในขั้นตอนก่อนคอมมิต
git stash
ลบออกจากหน่วยความจำ
ตอนนี้สาขาของคุณค่อนข้างสะอาด (เปลี่ยนกลับเป็นคอมมิตก่อนหน้า)