Tôi chỉ muốn hoàn nguyên các thay đổi được thực hiện bởi một cam kết cụ thể đối với một tệp nhất định.
Tôi có thể sử dụng lệnh git revert cho việc đó không?
Bất kỳ cách đơn giản nào khác để làm điều đó?
Tôi chỉ muốn hoàn nguyên các thay đổi được thực hiện bởi một cam kết cụ thể đối với một tệp nhất định.
Tôi có thể sử dụng lệnh git revert cho việc đó không?
Bất kỳ cách đơn giản nào khác để làm điều đó?
Câu trả lời:
Cách sạch sẽ nhất mà tôi từng thấy để làm việc này được mô tả ở đây
git show some_commit_sha1 -- some_file.c | git apply -R
Tương tự như phản hồi của VonC nhưng sử dụng git show
và git apply
.
fatal: unrecognized input
-3
cờ để git áp dụng cho hợp nhất ba chiều khi bản vá không thành công, vì tôi thường sửa một chút thay đổi theo thời gian.
some_file.c
bao gồm các con đường đến tập tin nếu có một nếu không bạn sẽ âm thầm vá gì :)
Giả sử có thể thay đổi lịch sử cam kết, đây là quy trình làm việc để hoàn nguyên các thay đổi trong một tệp trong một cam kết trước đó:
Ví dụ: bạn muốn hoàn nguyên các thay đổi trong 1 tệp ( badfile.txt
) trong cam kết aaa222
:
aaa333 Good commit
aaa222 Problem commit containing badfile.txt
aaa111 Base commit
Căn cứ vào cam kết cơ sở, sửa đổi cam kết vấn đề và tiếp tục.
1) Bắt đầu rebase tương tác:
git rebase -i aaa111
2) Đánh dấu cam kết vấn đề để chỉnh sửa trong trình chỉnh sửa bằng cách thay đổi pick
thành e
(để chỉnh sửa):
e aaa222
pick aaa333
3) Hoàn nguyên các thay đổi đối với tệp xấu:
git show -- badfile.txt | git apply -R
4) Thêm các thay đổi và sửa đổi cam kết:
git add badfile.txt
git commit --amend
5) Hoàn thành rebase:
git rebase --continue
edit
không hiển thị như đã thay đổi. Tuy nhiên, git show -- badfile.txt | git apply -R
đã đưa ra câu trả lời tôi cần <3
git revert
là cho tất cả nội dung tệp trong một cam kết.
Đối với một tệp duy nhất, bạn có thể tập lệnh cho nó :
#!/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
(Từ các tiện ích git-shell-scripts từ smtlaissezfaire )
Ghi chú:
một cách khác được mô tả ở đây nếu bạn vẫn chưa thực hiện sửa đổi hiện tại của mình.
git checkout -- filename
git checkout
có một số tùy chọn cho tệp, sửa đổi tệp từ HEAD, ghi đè thay đổi của bạn.
Dropped.on.Caprica đề cập trong các bình luận :
Bạn có thể thêm bí danh vào git để có thể thực hiện
git revert-file <hash> <file-loc>
và yêu cầu hoàn nguyên tệp cụ thể đó.
Xem ý chính này .
[alias]
revert-file = !sh /home/some-user/git-file-revert.sh
git revert-file <hash> <file-loc>
và yêu cầu hoàn nguyên tệp cụ thể đó. Tôi đã loại bỏ câu trả lời này (mặc dù tôi đã phải thực hiện một vài chỉnh sửa để hoạt động chính xác). Bạn có thể tìm bản sao .gitconfig
tập lệnh của tôi và đã chỉnh sửa tại đây: gist.github.com/droppedoncaprica/5b67ec0021371a0ad438
Tôi chỉ cần sử dụng --no-commit
tùy chọn để git-revert
và sau đó xóa các tệp bạn không muốn hoàn nguyên khỏi chỉ mục trước khi cuối cùng cam kết nó. Dưới đây là một ví dụ cho thấy cách dễ dàng hoàn nguyên các thay đổi đối với foo.c trong lần cam kết gần đây nhất thứ hai:
$ 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
Đầu tiên git-reset
"loại bỏ" tất cả các tệp, để sau đó chúng tôi có thể thêm lại chỉ một tệp mà chúng tôi muốn hoàn nguyên. Cuối cùng git-reset --hard
loại bỏ các hoàn nguyên tệp còn lại mà chúng tôi không muốn giữ lại.
Đơn giản hơn nhiều:
git reset HEAD^ path/to/file/to/revert
sau đó
git commit --amend
và sau đó
git push -f
tệp đã biến mất và cam kết băm, thông báo, v.v. vẫn như cũ.
git checkout -- path/to/file/to/revert
bước? Ngoài ra, việc băm sau đó cũng không đúng, đúng không? Câu cuối cùng có thể tốt hơn như: "Kết quả là cam kết cuối cùng được thay thế bằng một cam kết mới chỉ khác ở chỗ nó không chứa các thay đổi đối với tệp được hoàn nguyên."
git reset HEAD^ path/to/file/to/revert/in/commit
Lệnh trên sẽ đưa tệp ra khỏi cam kết, nhưng nó sẽ phản ánh trong git status
.
git checkout path/to/file/to/revert/in/commit
Lệnh trên sẽ hoàn nguyên các thay đổi (kết quả là bạn nhận được tệp giống như HEAD).
git commit
(Vượt qua --amend
để sửa đổi cam kết.)
git push
Với điều này, tệp đã có trong cam kết sẽ bị xóa và hoàn nguyên.
Các bước trên phải được thực hiện từ nhánh nơi thực hiện cam kết.
Bạn có thể làm theo quy trình sau:
git revert -n <*commit*>
( -n
hoàn nguyên tất cả các thay đổi nhưng sẽ không thực hiện chúng)git add <*filename*>
(tên của / các tệp bạn muốn hoàn nguyên và cam kết)git commit -m 'reverted message'
(thêm tin nhắn để hoàn nguyên)