Khôi phục tập tin từ cam kết cũ trong git


Câu trả lời:


218
git checkout 'master@{7 days ago}' -- path/to/file.txt

Điều này sẽ không thay đổi CHÍNH, nó sẽ ghi đè lên tệp cục bộ path/to/file.txt

Xem người đàn ông git-rev-parse để biết các thông số sửa đổi có thể có ở đó (tất nhiên một hàm băm đơn giản (như dd9bacb) sẽ làm tốt

Đừng quên cam kết thay đổi (sau khi đánh giá ...)


15
Wow, @heneryville và sehe, tôi thực sự đã nghĩ rằng '7 ngày trước' là meta cho bạn sẽ tìm ra những gì cam kết. ty!
AnneTheAgile

7
Phần 2 Khi muốn chọn một cam kết cụ thể, định dạng trên không hoạt động. Thay vào đó, hãy sử dụng những gì Urs hiển thị bên dưới, git checkout commitShaNumber - path / to / file.txt trên stackoverflow.com/questions/215718/
Kẻ

2
@AnneTheAgile trên thực tế vẫn chính xác cùng một cú pháp, tôi chỉ tình cờ đưa ra một ví dụ "phức tạp" revision-specificationvì đó là những gì OP yêu cầu :)
sehe

1
Nếu cam kết của bạn đã được sử dụng để xóa tệp bạn đang cố khôi phục, chỉ cần sử dụng shacommit~1(ví dụ git checkout 0f4bbdcd~1 -- path/to/file.txt:) để nhận cam kết ngay trước đó.
sdlins

89
  1. Kiểm tra các tập tin từ cam kết cũ của bạn thông qua git checkout [Revision_Key] -- path/to/file.
  2. Thêm, cam kết, đẩy khi thích hợp.

3
git checkoutcó thể xử lý các tập tin đơn lẻ (xem câu trả lời của sehe), không cần sao chép và dán.
Koraktor

1
Các khóa sửa đổi luôn là SHA1 cho cam kết?
IslandCow

1
Chúng là, nhưng thông thường 6 đến 8 ký tự đầu tiên của SHA1 là đủ để xác định sửa đổi.
Urs Reupke

2
@IslandCow không, họ có thể sha1 mà còn chi nhánh, tag, hoặc bất cứ điều gì khác mà điểm đến một cam kết, ví dụ HEAD, ORIG_HEADhoặc bất kỳ của những kết hợp với ^/ ~/ @ký hiệu kiểu.
Alois Mahdal

2
Bạn chỉ ra rằng một người có nghĩa vụ "thêm" tệp sau đó. Nhưng điều đó là không chính xác. Các tập tin không được đặt trong khu vực tổ chức. Nó đã được thêm vào.
xApple

8

Tôi cần khôi phục một tập tin gần đây đã cam kết vào git. Vì vậy, chỉ cần nhắc lại và đưa ra một viễn cảnh khác, bạn cần thực hiện điều này bằng cách chạy hai bước sau:

  1. git log -3
    Điều này cho thấy ba lần xác nhận gần đây nhất. Đọc các bình luận và tên của tác giả để bạn thu hẹp phiên bản chính xác mà bạn muốn. Viết xuống id cam kết dài (tức là b6b94f2c19c456336d60b9409fb1e373036d3d71) cho phiên bản cam kết bạn muốn.

  2. kiểm tra git b6b94f2c19c456336d60b9409fb1e373036d3d71 - myfile.java Truyền
    id xác nhận VÀ tên tệp bạn muốn khôi phục. Hãy chắc chắn rằng bạn có một khoảng trắng trước và sau dấu gạch nối kép.

Có nhiều cách khác để làm điều đó. Nhưng cái này là cái đơn giản hơn tôi có thể nhớ. Mong rằng sẽ giúp.

LƯU Ý: Nếu bạn ở trong đường dẫn / thư mục dự án thì không cần thiết phải nhập đường dẫn của tệp đầy đủ trong lệnh thanh toán.


Nhận xét tốt nhất từ ​​trước tới giờ. Bởi vì câu trả lời được chấp nhận, giả sử rằng tệp phải tìm nạp được đẩy ngược dòng, tuy nhiên lệnh này tìm nạp / khôi phục tệp chỉ tồn tại cục bộ.
ot0

1
Chỉ cần thử điều này trong thư mục gốc của repo git cục bộ của tôi. Tôi vẫn cần cung cấp đường dẫn tương đối đến tập tin. Chỉ cung cấp - [tên tệp] trên chính nó đã không hoạt động.
dùng2784627

@ ot0 Không, nó không cho rằng. Họ chính xác là cùng một câu trả lời.
matt

4

Tất cả các câu trả lời đề cập git checkout <tree-ish> -- <pathspec>. Kể từ git v2.23.0, có một phương pháp khôi phục git mới được cho là đảm nhận một phần git checkouttrách nhiệm. Xem những điểm nổi bật của những thay đổi trên blog github .

Hành vi mặc định của lệnh này là khôi phục trạng thái của cây làm việc với nội dung đến từ sourcetham số (trong trường hợp của bạn sẽ là hàm băm cam kết).

Giả sử hàm băm cam kết là abcdeflệnh sẽ như thế này:

git restore --source=abcdef file_name

mà (theo mặc định) đặt nó trong cây làm việc. Nếu bạn muốn đặt thay đổi trực tiếp trong chỉ mục để có thể cam kết ngay lập tức:

git restore --source=abcdef --worktree --staged file_name

hoặc với tên tùy chọn ngắn:

git restore -s=abcdef -W -S file_name
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.