Hoàn nguyên hoặc kiểm tra có chọn lọc các thay đổi đối với tệp trong Git?


88

Có lệnh nào cho phép bạn hoàn tác một phần các thay đổi đối với tệp (hoặc các tệp) trong thư mục làm việc không?

Giả sử bạn đã chỉnh sửa nhiều tệp nhưng bạn nhận ra rằng bạn muốn hoàn tác một số thay đổi trở lại trạng thái đã cam kết, chứ không phải các thay đổi khác.

Tôi đang hình dung một tùy chọn git checkouthoạt động tương tự git add -p, tức là nó đi qua tệp từng tệp và hỏi bạn có muốn giữ nó hay không.

Câu trả lời:


85

Bạn đã có thể sử dụng

git add -p <path>

để phân chia các phần mà bạn muốn giữ trong một tệp cụ thể, sau đó

git checkout -- <path>

để loại bỏ các thay đổi cây làm việc mà bạn không muốn giữ lại, bằng cách kiểm tra phiên bản theo giai đoạn của tệp.

Cuối cùng, bạn có thể sử dụng

git reset -- <path>

để hoàn nguyên phiên bản theo giai đoạn của tệp về phiên bản được cam kết gần đây nhất của tệp để bạn bỏ qua các thay đổi của mình.


Đối với trường hợp sử dụng đơn giản này, mà mọi hệ thống điều khiển phiên bản khác chỉ gọi "hoàn nguyên", tại sao lệnh Git lại tối nghĩa?
Jan Hettich

5
@Jan revertLệnh của hệ thống kiểm soát phiên bản khác có cho phép bạn chọn những thay đổi nào trong tệp được hoàn nguyên không? Thực sự hỏi, vì tôi chỉ có kinh nghiệm với CVS và Git. Trong Git, git checkout -- path/to/filelà một lệnh duy nhất hoàn nguyên tất cả các thay đổi trong tệp đó, nhưng điều này không giống như ở trên.
michiakig

3
Ngoài ra còn có git checkout --patchgit reset --patchhoạt động giống như git add --patchtrong git mới nhất.
Matt Connolly

2
@Rudie, --thường chỉ ra sự kết thúc của phân tích cú pháp tùy chọn và bất kỳ đối số nào đứng sau nó đều được hiểu theo nghĩa đen. Điều này có nghĩa là bạn sẽ không phải thêm ./trước bất kỳ tên tệp nào bắt đầu bằng dấu trừ, nếu tên tệp đứng sau --.
zrajm

khi tôi sử dụng, git checkout --patchsự khác biệt dường như bị ngược. Các biểu tượng dấu trừ là THÊM văn bản vào bản sao đang làm việc của tôi và các biểu tượng dấu cộng là XÓA các dòng khỏi bản sao đang làm việc của tôi.
Felipe Alvarez,

115

Với phiên bản git> = 1.7.1 tôi có thể

git checkout -p

Tôi không chắc khi nào tính năng này được giới thiệu.


11
Điều đáng nói là bạn cũng có thể làm git reset -pđể loại bỏ các thay đổi có chọn lọc khỏi khu vực / chỉ mục dàn dựng. Tôi cũng không biết phiên bản Git này đã được giới thiệu.

Đây là câu trả lời chính xác, tại sao nó không được chấp nhận.
wukong

1
@wukong vì câu trả lời này đã được đăng 2 năm sau câu hỏi. Tại thời điểm này (2009), câu trả lời của Charles là giải pháp tốt nhất
pomeh

8

git checkout $filechuyển trạng thái của tệp $filevề trạng thái được cam kết cuối cùng. Tôi nghĩ bạn có thể sử dụng git checkout SHA-1 -- $fileđể hoàn nguyên tệp về cam kết được xác định bởi SHA-1.


1
yeah, không chính xác những gì tôi muốn, vì tôi muốn giữ lại một số các thay đổi mà tôi đã thực hiện trong các tập tin và phục hồi các người khác
1800 INFORMATION

1

Bạn cần quay lại và chọn bao nhiêu cam kết? Nếu nó chỉ là một, có thể lấy một nhánh ngay trước nó, kiểm tra tệp bạn đã cam kết và sau đó sử dụng git add -pđể thêm nó theo cách bạn muốn. Sau đó, bạn có thể quay lại vị trí của mình và kiểm tra tệp từ nhánh tạm thời của bạn.

đó là:

git checkout -b temp troublesome-commit^
git checkout troublesome-commit -- path/to/file
git add -p path/to/file
git commit -c troublesome-commit
git checkout @{-1}
git checkout temp -- path/to/file
git commit path/to/file
git branch -D temp

Các lựa chọn thay thế khác bao gồm quay lại và chỉnh sửa cam kết bằng git rebase -i(đánh dấu cam kết là edit, sau đó thực hiện git reset HEAD^và thực hiện lại cam kết khi được thả trở lại trình bao).

Nếu những thay đổi bạn cần chọn nằm trong một loạt các cam kết, tốt hơn là bạn nên trích xuất chúng dưới dạng các bản vá (hoặc một bản vá bao gồm tất cả chúng) và chỉnh sửa thủ công bản vá, lấy ra những thay đổi bạn muốn giữ lại, và đưa phần còn lại vào git apply --reverse.


Tôi thực sự không muốn hoàn nguyên bất cứ điều gì đã cam kết, tôi muốn hoàn tác các thay đổi chỉ có trong bản sao làm việc của tôi
1800 INFORMATION
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.