Làm thế nào để hoàn nguyên một git rm -r .r?


378

Tôi vô tình nói git rm -r .. Làm thế nào để tôi phục hồi từ điều này?

Tôi đã không cam kết.

Tôi nghĩ rằng tất cả các tệp đã được đánh dấu để xóa và cũng bị xóa khỏi kiểm tra cục bộ của tôi.

EDIT: Tôi có thể (nếu tôi biết lệnh) trở lại cam kết cuối cùng. Nhưng nó sẽ tốt hơn rất nhiều nếu tôi có thể hoàn tác git rm -r .. Bởi vì tôi không thực sự chắc chắn những gì tôi đã làm sau lần cam kết cuối cùng và trước khi git rm -r ..


3
Đối với câu hỏi cụ thể này, đặt lại - có một giải pháp tốt ... nó đã được liệt kê vì vậy tôi sẽ chỉ đề cập trong bình luận này rằng bạn có thể muốn kiểm tra tài liệu cho git-reflog.
William Pursell

8
Lưu ý rằng vì bạn không cung cấp -fcho git rmgit nên sẽ không xóa bất kỳ tệp nào đã thay đổi theo giai đoạn hoặc không theo giai đoạn git reset; git checkout .nên sẽ phục hồi mọi thứ.
CB Bailey

Chỉ cần xem ra - kiểm tra git. sẽ xóa sạch tất cả những thay đổi không có căn cứ.
PeterB

1
Tôi vừa mới làm một cái gì đó như thế này và tôi không hiểu tại sao các tệp cục bộ của mình bị xóa (và, giống như OP, tôi chưa cam kết.)
Xonatron

Với Git 2.23+ (tháng 8 năm 2019), bạn sẽ khôi phục các tệp bằng git restore: git restore -s@ -SW -- .. Xem câu trả lời của tôi dưới đây .
VonC

Câu trả lời:


468
git reset HEAD

Hãy làm nó. Nếu bạn không có bất kỳ thay đổi không cam kết nào mà bạn quan tâm, thì

git reset --hard HEAD

nên buộc thiết lập lại mọi thứ để cam kết cuối cùng của bạn. Nếu bạn có các thay đổi không được cam kết, nhưng lệnh đầu tiên không hoạt động, thì hãy lưu các thay đổi không được cam kết của bạn với git stash:

git stash
git reset --hard HEAD
git stash pop

22
Lưu ý rằng git reset --hard HEADsẽ phá hủy mọi thay đổi hữu ích mà bạn đã thực hiện trong các thư mục mẹ của thư mục làm việc hiện tại.
Alex Brown

10
@Mild: Tôi vẫn đang đổ mồ hôi lạnh!
hoipolloi

6
Tôi đã không bỏ phiếu, nhưng tôi chỉ thử stash, thiết lập lại cứng, bật và mất tất cả các thay đổi gần đây của tôi. Có lẽ tôi đã đọc sai câu trả lời.
Greg M. Krsak

1
Điều này hiếm khi làm việc cho tôi và tôi rất vui vì tôi làm việc trong thư mục Dropbox. Hình thức kém, nhưng lại cứu tôi mọi lúc ...
Nuby

3
Khi tôi thực hiện git stash pop, nó chỉ xóa các tệp một lần nữa, tất nhiên vì nó làm mất thực tế là tôi (vô tình) đã xóa một số tệp. Câu trả lời này không hoạt động nếu bạn có những thay đổi không được cam kết mà bạn muốn giữ.
sudo

252

Tôi git-rm'd một vài tệp và tiếp tục thay đổi trước khi cam kết tiếp theo của tôi khi tôi nhận ra rằng tôi cần một số các tệp đó trở lại. Thay vì stash và thiết lập lại, bạn chỉ cần kiểm tra các tệp riêng lẻ mà bạn đã bỏ lỡ / xóa nếu muốn:

git checkout HEAD path/to/file path/to/another_file

Điều này khiến cho những thay đổi không được cam kết khác của bạn nguyên vẹn không có cách giải quyết.


6
Điều này giúp vì tôi có những thay đổi không được cam kết khác.
Dan

4
Câu trả lời này giúp cho những người trong chúng ta vấp phải câu hỏi này đang tìm cách hoàn nguyên một git rmthay vì toàn bộ đệ quy git rm -r. Để xóa đệ quy đầy đủ, các giải pháp khác có thể tốt hơn, tùy thuộc vào số lượng tệp bị xóa.
tresf 15/03/2016

Bạn, người đàn ông của tôi, xứng đáng một giải thưởng.
Salamit

Nếu tôi có thể tôi sẽ nhấp vào nó 100 lần.
Wagner Braga

57

Để lấy lại một số tệp hoặc thư mục, người ta có thể sử dụng các mục sau

git reset -- path/to/file
git checkout -- path/to/file

Điều này trước tiên sẽ tạo lại các mục chỉ mục cho path/to/filevà tạo lại tệp như trong cam kết cuối cùng, tức là HEAD.

Gợi ý: người ta có thể chuyển một hàm băm cam kết cho cả hai lệnh để tạo lại các tệp từ một cam kết cũ hơn. Xem git reset --helpgit checkout --helpđể biết chi tiết.


Câu trả lời tốt nhất. Phẫu thuật dễ dàng 'hoàn tác' một git rmthao tác duy nhất mà không xóa sạch các thay đổi không được cam kết khác.
dâu

Giúp tôi ra! câu trả lời tốt nhất.
Akram

28

Cập nhật:

git rm .xóa tất cả các tệp trong thư mục này và thư mục con trong thanh toán hoạt động cũng như trong chỉ mục, bạn cần hoàn tác từng thay đổi sau:

git reset HEAD . # This undoes the index changes
git checkout .   # This checks out files in this and child directories from the HEAD

Điều này nên làm những gì bạn muốn. Nó không ảnh hưởng đến các thư mục mẹ của mã hoặc chỉ mục đã thanh toán của bạn.


Câu trả lời cũ không phải là:

reset HEAD

sẽ thực hiện thủ thuật và sẽ không xóa bất kỳ thay đổi không được cam kết nào bạn đã thực hiện đối với các tệp của mình.

sau đó bạn cần lặp lại bất kỳ git addlệnh nào bạn đã xếp hàng.


1
xin lỗi, tôi luôn luôn thiết lập git alias.co="checkout"để git cokiểm tra.
Alex Brown

25

Nếu bạn không có cách nào ở trên hoạt động, bạn có thể truy xuất dữ liệu bằng đề xuất từ ​​đây: http://www.spinics.net/lists/git/msg62499.html

git prune -n
git cat-file -p <blob #>

4 năm sau, vẫn là phao cứu sinh!
ThiefSix

Tôi đã viết một chương trình c ++ để ghép các kết quả (tôi có khoảng 100 đối tượng lơ lửng trong repo của mình, làm cho điều này là cần thiết). Chỉ cần biên dịch và chạy, sau đó chuyển vào thư mục địa phương git repo của bạn. raw.githubusercontent.com/bluuman/git-recover-files/master/iêu
James biện pháp

15

hoàn tác git rm

git rm file             # delete file & update index
git checkout HEAD file  # restore file & index from HEAD

hoàn tác git rm -r

git rm -r dir          # delete tracked files in dir & update index
git checkout HEAD dir  # restore file & index from HEAD

hoàn tác git rm -rf

git rm -r dir          # delete tracked files & delete uncommitted changes
not possible           # `uncommitted changes` can not be restored.

Uncommitted changesbao gồm not staged changes, staged changes but not committed.


Tất nhiên, không có gì có thể hoàn tác git rm -rf, vì điều đó cũng có thể xóa các tập tin không bị theo dõi hoặc dàn dựng (chỉ).
jpaugh

git rm -rf filegit rm -rf dirsẽ không xóa bất kỳ tập tin chưa được theo dõi.
bài hát xu

10

Nếu bạn đã cam kết và thúc đẩy các thay đổi, bạn có thể làm điều này để lấy lại tệp

// Replace 2 with the # of commits back before the file was deleted.
git checkout HEAD~2 path/to/file

Điều này hoạt động với 'Thay đổi được cam kết:' trong đó một tệp đã bị xóa khỏi git cherry-pick cũ mà tôi vẫn cần. Tôi đã thử git reset HEAD ~ <number> <file> không hoạt động.
purcraft

7

Đã có một số câu trả lời hay, nhưng tôi có thể đề xuất một cú pháp ít được sử dụng không chỉ hoạt động tuyệt vời mà còn rất rõ ràng trong những gì bạn muốn (không đáng sợ hay bí ẩn)

git checkout <branch>@{"20 minutes ago"} <filename>

3

Nhận danh sách cam kết

git log  --oneline

Ví dụ: Cam kết ổn định có hàm băm: 45ff319c360cd7bd5442c0fbbe14202d20ccdf81

git reset --hard 45ff319c360cd7bd5442c0fbbe14202d20ccdf81
git push -ff origin master

1

Tôi đã có một tình huống giống hệt nhau. Trong trường hợp của tôi, giải pháp là:

git checkout -- .

0

Với Git 2.23+ (tháng 8 năm 2019), lệnh thích hợp để khôi phục các tệp (và chỉ mục) sẽ được sử dụng ... git restore(không phải reset --hardhoặc lệnh khó hiểugit checkout )

Đó là:

git restore -s=HEAD --staged --worktree -- .

Hoặc dạng viết tắt của nó:

git restore -s@ -SW -- .

-1

Tôi có cùng một vấn đề: đã dọn dẹp các thư mục của mình, sắp xếp lại và di chuyển các tập tin. Tôi vào: git rm . và nhấn enter; và sau đó cảm thấy ruột của tôi nới lỏng một chút. May mắn thay, tôi đã không gõ git commit -m "" ngay lập tức.

Tuy nhiên, lệnh sau

git checkout .

khôi phục lại mọi thứ, và cứu mạng tôi.

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.