ฉันต้องการเปลี่ยนกลับการเปลี่ยนแปลงที่กระทำโดยการคอมมิตเฉพาะกับไฟล์ที่กำหนดเท่านั้น
ฉันสามารถใช้คำสั่ง git revert ได้หรือไม่
วิธีง่ายๆอื่น ๆ ที่จะทำ?
ฉันต้องการเปลี่ยนกลับการเปลี่ยนแปลงที่กระทำโดยการคอมมิตเฉพาะกับไฟล์ที่กำหนดเท่านั้น
ฉันสามารถใช้คำสั่ง git revert ได้หรือไม่
วิธีง่ายๆอื่น ๆ ที่จะทำ?
คำตอบ:
วิธีที่สะอาดที่สุดที่ฉันเคยเห็นมีอธิบายไว้ที่นี่
git show some_commit_sha1 -- some_file.c | git apply -R
คล้ายกับการตอบสนองของ VonC แต่ใช้git show
และgit apply
.
fatal: unrecognized input
-3
แฟล็กเพื่อคอมไพล์ใช้สำหรับการผสานสามทางเมื่อแพตช์ล้มเหลวเนื่องจากฉันมักจะแก้ไขการเปลี่ยนแปลงย้อนเวลาเล็กน้อย
some_file.c
มีพา ธไปยังไฟล์หากมีอย่างอื่นคุณจะไม่ทำการแก้ไขอะไรเลย :)
สมมติว่าสามารถเปลี่ยนประวัติการคอมมิตได้นี่คือเวิร์กโฟลว์เพื่อเปลี่ยนกลับการเปลี่ยนแปลงในไฟล์เดียวในคอมมิตก่อนหน้านี้:
ตัวอย่างเช่นคุณต้องการยกเลิกการเปลี่ยนแปลงใน 1 ไฟล์ ( badfile.txt
) ในการกระทำaaa222
:
aaa333 Good commit
aaa222 Problem commit containing badfile.txt
aaa111 Base commit
สร้างฐานใหม่บนฐานการกระทำแก้ไขปัญหาและดำเนินการต่อ
1) เริ่ม rebase แบบโต้ตอบ:
git rebase -i aaa111
2) ทำเครื่องหมายที่ปัญหาเพื่อแก้ไขในตัวแก้ไขโดยเปลี่ยนpick
เป็นe
(สำหรับแก้ไข):
e aaa222
pick aaa333
3) ยกเลิกการเปลี่ยนแปลงไปยังไฟล์ที่ไม่ถูกต้อง:
git show -- badfile.txt | git apply -R
4) เพิ่มการเปลี่ยนแปลงและแก้ไขการกระทำ:
git add badfile.txt
git commit --amend
5) เสร็จสิ้น rebase:
git rebase --continue
edit
ไม่ได้แสดงว่ามีการเปลี่ยนแปลง แต่git show -- badfile.txt | git apply -R
คำตอบที่ฉันต้องการ <3
git revert
มีไว้สำหรับเนื้อหาไฟล์ทั้งหมดภายในคอมมิต
สำหรับไฟล์เดียวคุณสามารถเขียนสคริปต์ได้ :
#!/bin/bash
function output_help {
echo "usage: git-revert-single-file <sha1> <file>"
}
sha1=$1
file=$2
if [[ $sha1 ]]; then
git diff $sha1..$sha1^ -- $file | patch -p1
else
output_help
fi
(จากยูทิลิตี้git-shell-scriptsจากsmtlaissezfaire )
บันทึก:
มีการอธิบายวิธีอื่นไว้ที่นี่หากคุณยังไม่ได้ทำการแก้ไขปัจจุบัน
git checkout -- filename
git checkout
มีตัวเลือกบางอย่างสำหรับไฟล์การแก้ไขไฟล์จาก HEAD เขียนทับการเปลี่ยนแปลงของคุณ
Drop On Capricaกล่าวถึงในความคิดเห็น :
คุณสามารถเพิ่มนามแฝงในคอมไพล์เพื่อให้คุณสามารถทำ
git revert-file <hash> <file-loc>
และเปลี่ยนไฟล์นั้นได้
ดูส่วนสำคัญนี้
[alias]
revert-file = !sh /home/some-user/git-file-revert.sh
git revert-file <hash> <file-loc>
และเปลี่ยนไฟล์นั้นได้ ฉันยกจากคำตอบนี้ (แม้ว่าฉันจะต้องทำการแก้ไขสองสามครั้งเพื่อให้ทำงานได้อย่างถูกต้อง) คุณสามารถค้นหาสำเนาของ.gitconfig
สคริปต์ของฉันและแก้ไขได้ที่นี่: gist.github.com/droppedoncaprica/5b67ec0021371a0ad438
ฉันจะใช้--no-commit
ตัวเลือกในการgit-revert
แล้วลบไฟล์ที่คุณไม่ต้องการเปลี่ยนกลับจากดัชนีก่อนที่จะดำเนินการในที่สุด นี่คือตัวอย่างที่แสดงวิธีการเปลี่ยนกลับเฉพาะการเปลี่ยนแปลงของ foo.c อย่างง่ายดายในการกระทำล่าสุดอันดับสอง:
$ git revert --no-commit HEAD~1
$ git reset HEAD
$ git add foo.c
$ git commit -m "Reverting recent change to foo.c"
$ git reset --hard HEAD
git-reset
"unstages" ไฟล์แรกทั้งหมดเพื่อให้เราสามารถเพิ่มกลับเพียงไฟล์เดียวที่เราต้องการเปลี่ยนกลับ ขั้นสุดท้ายgit-reset --hard
จะกำจัดไฟล์ที่เหลือซึ่งเราไม่ต้องการเก็บไว้
ง่ายกว่ามาก:
git reset HEAD^ path/to/file/to/revert
แล้วก็
git commit --amend
แล้ว
git push -f
ไฟล์หายไปและคอมมิตแฮชข้อความและอื่น ๆ เหมือนกัน
git checkout -- path/to/file/to/revert
ขั้นตอนหรือไม่? นอกจากนี้มันไม่จริงที่แฮชจะเหมือนกันในภายหลังใช่มั้ย? ประโยคสุดท้ายอาจจะดีกว่าเช่น: "ผลลัพธ์คือการกระทำสุดท้ายจะถูกแทนที่ด้วยอันใหม่ที่แตกต่างกันเฉพาะที่ไม่มีการเปลี่ยนแปลงในไฟล์ที่กลับด้าน"
git reset HEAD^ path/to/file/to/revert/in/commit
คำสั่งดังกล่าวจะนำไฟล์ออกจากการกระทำ git status
แต่มันจะสะท้อนให้เห็นถึง
git checkout path/to/file/to/revert/in/commit
คำสั่งดังกล่าวจะย้อนกลับการเปลี่ยนแปลง (ด้วยเหตุนี้คุณจึงได้ไฟล์เหมือนกับ HEAD)
git commit
(ผ่าน--amend
เพื่อแก้ไขข้อผูกพัน)
git push
ด้วยวิธีนี้ไฟล์ที่อยู่ในคอมมิตจะถูกลบออกและเปลี่ยนกลับ
ควรปฏิบัติตามขั้นตอนข้างต้นจากสาขาที่มีการคอมมิต
คุณสามารถทำตามขั้นตอนนี้:
git revert -n <*commit*>
( -n
เปลี่ยนกลับการเปลี่ยนแปลงทั้งหมด แต่จะไม่คอมมิต)git add <*filename*>
(ชื่อไฟล์ที่คุณต้องการเปลี่ยนกลับและคอมมิต)git commit -m 'reverted message'
(เพิ่มข้อความสำหรับการเปลี่ยนกลับ)หากคุณต้องการรีเซ็ตการเปลี่ยนแปลงในไฟล์จากคอมมิตล่าสุดของคุณนี่คือสิ่งที่ฉันมักจะใช้ ฉันคิดว่านี่เป็นวิธีแก้ปัญหาที่ง่ายที่สุด
โปรดสังเกตว่าไฟล์จะถูกเพิ่มลงในพื้นที่จัดเตรียม
git checkout <prev_commit_hash> -- <path_to_your_file>
หวังว่าจะช่วยได้ :)