Khôi phục từ thiết lập lại git - hả?


457

Có cách nào để phục hồi các thay đổi không được cam kết cho thư mục làm việc từ a git reset --hard HEADkhông?


49
Tôi khuyên bạn nên bỏ học git reset. Bạn không cần lệnh đó và nó nguy hiểm, vì vậy đừng sử dụng nó. Để trả lại nhánh cho cam kết trước đó git rebase -ivà bỏ các cam kết bạn không muốn hoặc git checkout(tách đầu) theo sau git branch -Mđể di chuyển đầu nhánh. Cái đầu tiên sẽ từ chối chạy với các thay đổi cục bộ và cái sau sẽ chỉ chạy nếu các tệp được sửa đổi cục bộ không khác nhau giữa các bản sửa đổi.
Jan Hudec

11
@ Tôi không tin điều đó. Có những lý do hoàn toàn chính đáng để sử dụng thiết lập lại.
spaaarky21

4
@ spaaarky21: Vâng, có. Nhưng git reset --hard somewherelà một trong số ít các lệnh git thực sự nguy hiểm.
Jan Hudec

5
@Jan Tôi đồng ý nhưng nó nguy hiểm không có nghĩa là bạn không nên sử dụng nó. Chỉ cần biết những gì bạn đang làm và cẩn thận. :)
spaaarky21

3
Không liên quan đến Hoàn tác thiết lập lại git - HÃY ĐẦU TIÊN ~ 1 , bởi vì ở đây người đăng ban đầu đang cố gắng khôi phục các thay đổi không được cam kết.

Câu trả lời:


475

Bạn không thể lấy lại những thay đổi không được cam kết nói chung.

Các thay đổi được tổ chức trước đó ( git add) nên có thể được phục hồi từ các đối tượng chỉ mục, vì vậy nếu bạn đã làm, hãy sử dụng git fsck --lost-foundđể định vị các đối tượng liên quan đến nó. (Điều này ghi các đối tượng vào .git/lost-found/thư mục; từ đó bạn có thể sử dụng git show <filename>để xem nội dung của từng tệp.)

Nếu không, câu trả lời ở đây sẽ là: nhìn vào bản sao lưu của bạn. Có lẽ trình soạn thảo / IDE của bạn lưu trữ các bản sao tạm thời trong / tmp hoặc C: \ TEMP và những thứ tương tự. [1]

git reset HEAD@{1}

Điều này sẽ khôi phục lại TRƯỚC trước

[1] vim ví dụ: tùy chọn lưu trữ liên tục hoàn tác, nhật thực IDE lưu trữ lịch sử địa phương ; các tính năng như vậy có thể cứu ** của bạn


18
Lịch sử địa phương của Eclipse - và ngoài ra, vì một số thay đổi đã cũ hơn 6 ngày, bản sao lưu Time Machine của tôi về lịch sử địa phương của Eclipse! Vì một số lý do, bản sao lưu Time Machine của thư mục do git quản lý không chứa các thay đổi trước đó của tôi.
christianbrodbeck

2
Bạn là một người nghiêm túc tiết kiệm cuộc sống trên gợi ý! TextWrangler đã có một bản sao lưu các tập tin. Cảm ơn bạn
Vivek Sampara

6
IDE (IntelliJ) đã lưu trữ các thay đổi cục bộ đã lưu trong ngày. Cảm ơn vì tiền hỗ trợ!
progonkpa

1
Ôi thật là tuyệt vời. Nó hoạt động ngay cả khi bạn chưa bao giờ thực hiện một cam kết.
Boudewijn Aasman

2
Thật vậy, lịch sử địa phương trong Eclipse (Intellij trong trường hợp của tôi) tiết kiệm một ngày của tôi trong việc phục hồi các thay đổi không đáng tin cậy, tài liệu ở đây cho Intellij: blog.jetbrains.com/idea/2008/01/ Lỗi
Richard

449

câu trả lời từ SO này

$ git reflog show
93567ad HEAD@{0}: reset: moving to HEAD@{6}    
203e84e HEAD@{1}: reset: moving to HEAD@{1}    
9937a76 HEAD@{2}: reset: moving to HEAD@{2}
203e84e HEAD@{3}: checkout: moving from master to master
203e84e HEAD@{4}: reset: moving to HEAD~1
9937a76 HEAD@{5}: reset: moving to HEAD~1
d5bb59f HEAD@{6}: reset: moving to HEAD~1
9300f9d HEAD@{7}: commit: fix-bug

# said the commit to be recovered back is on 9300f9d (with commit message fix-bug)
$ git reset HEAD@{7}

Bạn đã có ngày trở lại! :)


24
Chỉ cần thêm vào câu trả lời này, điều này sẽ giúp những người thực sự đã thực hiện các thay đổi bị vứt bỏ thông qua thiết lập lại cứng.
murki

9
Tuyệt vời - nhưng trong trường hợp của tôi các tập tin đã biến mất hoàn toàn. Sử dụng git checkout HEAD@{19}cho phép tôi kiểm tra các tập tin bị mất trong trạng thái tách rời. Sau đó được sử dụng git checkout -b new-branch-nameđể thêm chúng trở lại repo ở trạng thái "đính kèm".
NightOwl888

@ NightOwl888: Git newbie ở đây và tôi gặp vấn đề tương tự là các tệp của tôi vẫn bị mất. Bạn có thể giải thích chi tiết hơn về cách bạn đã khôi phục các tệp của mình về trạng thái "đính kèm" (hoặc bạn có thể giải thích điều đó thực sự có nghĩa là gì không)? Cảm ơn bạn rất nhiều!
OhDaeSu

3
@ user3385759 - Trong Git, khi bạn sử dụng lệnh thanh toán trên bất kỳ thứ gì không phải là một nhánh, nó sẽ chuyển sang chế độ "tách rời" đặc biệt. Điều này có nghĩa là bạn không thực sự chỉ vào một chi nhánh, nhưng bạn có thể xem những gì đã được kiểm tra ở trạng thái của thực thể (trong trường hợp này là một mục nhập lại). Từ trạng thái đó, bạn có thể biến nó thành một nhánh "thực" mà bạn có thể quay lại lần nữa bằng cách sử dụng git checkout -b new-branch-name. Cuốn sách Kiểm soát phiên bản thực dụng sử dụng Git rất tốt trong việc giải thích Git bằng những thuật ngữ đơn giản.
NightOwl888

2
Vâng, những gì NomNomCameron và Jesse Adelman nói. Tôi đã nhầm tưởng thiết lập lại sẽ thiết lập lại cam kết cuối cùng của tôi. Không. Nó xóa sạch mọi thứ. Câu trả lời này đã cứu tôi sau một hoặc hai ngày tạo lại tác phẩm của mình.
Cựu chiến binh

308

Tôi đã vô tình chạy git reset --hardtrên repo của tôi ngày hôm nay trong khi có những thay đổi không được cam kết quá ngày hôm nay. Để lấy lại, tôi đã chạy git fsck --lost-found, trong đó viết tất cả các đốm màu không được ước tính <path to repo>/.git/lost-found/. Vì các tệp không được cam kết, tôi tìm thấy chúng trong otherthư mục bên trong <path to repo>/.git/lost-found/. Từ đó, tôi có thể thấy các tệp không được cam kết sử dụng git show <filename>, sao chép các đốm màu và đổi tên chúng.

Lưu ý: Điều này chỉ hoạt động nếu bạn đã thêm các tệp bạn muốn lưu vào chỉ mục (sử dụng git add .). Nếu các tệp không có trong chỉ mục, chúng sẽ bị mất.


4
Tôi chỉ nhận được các tập tin với các tham chiếu cam kết trong lost-found. Nhưng sau đó tôi có thể làm git showđể có được nội dung.
Mitar

6
Chỉ để tiết kiệm thời gian của bất cứ ai#!/bin/bash cd PATH_TO_PROJECT/.git/lost-found/other FILES=* COUNTER = 0 for f in $FILES do echo "Processing $f file..." git show $f > "PATH_TO_RECOVERY_DIRECTORY/$COUNTER.m" let COUNTER=COUNTER+1 done
rwolst

209

Có, BẠN CÓ THỂ PHỤC HỒI từ một thiết lập lại cứng trong git.

Sử dụng:

git reflog

để có được định danh của cam kết của bạn. Sau đó sử dụng:

git reset --hard <commit-id-retrieved-using-reflog>

Thủ thuật này đã cứu mạng tôi một vài lần.

Bạn có thể tìm tài liệu giới thiệu TẠI ĐÂY .


9
Cho đến nay, tôi nghĩ rằng đây là câu trả lời tốt nhất và ngắn gọn nhất. Có vẻ như phản tác dụng trực quan khi git reset --hardsử dụng một công cụ khác git reset --hardnhưng nếu bạn không sử dụng công --hardtắc, bạn sẽ bị bỏ lại với các mục trong không gian làm việc của bạn sẽ hoàn nguyên hiệu quả công việc bạn vừa phục hồi.
Ryan H.

2
Hoạt động như một lá bùa! Câu trả lời trước đó ( stackoverflow.com/questions/5788037/recover-from-git-reset-hard/ gợi ) không hoạt động với tôi.
codemax

3
Câu trả lời này không đúng. Cách tiếp cận này chỉ phục hồi những thay đổi đã cam kết trước đó . Nó sẽ không thể khôi phục các thay đổi không được cam kết (đó là những gì câu hỏi này là về).
Alderath

2
Giải pháp này hiệu quả với tôi. Tôi đã thiết lập lại cứng và sau đó khi tôi sử dụng, git logtôi không thấy id của cam kết. Với git reflogtôi có thể thấy ID cam kết
dboscanv

2
cái này hiệu quả với tôi cảm ơn!!!!!!
RedEyed

60

Trong khi tôi đang làm việc trên một dự án địa phương, tôi muốn chuyển nó sang GitHub và sau đó tạo một kho lưu trữ mới. Trong khi tôi đang cố gắng thêm tất cả các tệp này vào kho lưu trữ mới bằng .gitignore, tôi đã vô tình thêm một tệp sai và sau đó cố gắng xóa nó.

Tôi đã chạy git reset --hard origin/master: P

Sau đó, tất cả các tệp cục bộ của tôi đã bị xóa vì repo trống. Tôi nghĩ mọi thứ đã biến mất.

Điều này đã cứu cuộc đời tôi:

git reflog show
git reset HEAD@{1} 
git push 

Hy vọng nó sẽ cứu một cuộc sống khác.


Đối với tôi, đó là git reset HEAD@\{27\} , Cảm ơn bạn!
4oby

1
Tôi có 7 cam kết để thiết lập lại, tôi sử dụng git reflog showđể kiểm tra và từ lần cam kết đầu tiên tôi sử dụnggit reset HEAD@{number}
Vishwas Nahar

38

Nếu bạn sử dụng một cái gì đó như IntelliJ:

Trên menu ngữ cảnh, chọn Lịch sử cục bộ và bấm Hiện lịch sử trên menu con:

Chế độ xem lịch sử cục bộ cho một dự án hoặc thư mục hiển thị cho bạn mọi thứ bạn đã thực hiện trong vài ngày qua. Trong cột Hành động của phần dưới của hộp thoại, chọn hành động bạn muốn quay lại. [...] Làm như vậy, phần trên của hộp thoại hiển thị dạng xem cây của các tệp đã thay đổi. Nếu bạn chỉ muốn khôi phục tệp đã xóa, bất kể những thay đổi khác đã được thực hiện kể từ đó, bạn có thể chọn tệp Lost.txt trong chế độ xem dạng cây và nhấp vào nút Hoàn nguyên.

http://blog.jetbrains.com/idea/2008/01/USE-local-history-to-restore-delatted-files/

Điều này chỉ có ass của tôi ra lửa!


Đây là câu trả lời tốt nhất cho người dùng IntelliJ! Cảm ơn bạn rất nhiều, điều này làm việc hoàn hảo. Tôi đã thử mọi giải pháp khác và không ai trong số họ làm việc tốt. git reflogkhông hoạt động vì tôi không cam kết thay đổi. git fsck --lost-foundlàm việc cho các tập tin dàn dựng nhưng không phải tất cả chúng đều được dàn dựng. Lịch sử địa phương của IntelliJ đã phục hồi hoàn hảo các tệp chưa lưu của tôi, tôi rất biết ơn tính năng này
Denes Papp

30

Tôi vừa làm git reset --hardvà mất tất cả những thay đổi không cam kết của tôi. May mắn thay, tôi sử dụng một trình soạn thảo (IntelliJ) và tôi đã có thể khôi phục các thay đổi từ Lịch sử địa phương. Eclipse sẽ cho phép bạn làm như vậy.


20

Theo định nghĩa, git reset --hardsẽ loại bỏ các thay đổi không được cam kết mà không có cách nào để Git khôi phục chúng (hệ thống sao lưu của bạn có thể giúp đỡ, nhưng không phải là Git).

Trên thực tế, có rất ít trường hợp git reset --hardlà một ý tưởng tốt. Trong hầu hết các trường hợp, có một lệnh an toàn hơn để làm điều tương tự:

  • Nếu bạn muốn loại bỏ những thay đổi không được cam kết của mình, thì hãy sử dụng git stash. Nó sẽ giữ một bản sao lưu của những thay đổi này, nó sẽ hết hạn sau một thời gian nếu bạn chạy git gc. Nếu bạn chắc chắn 99,9% bạn sẽ không bao giờ cần những thay đổi này trở lại, thì đó git stashvẫn là bạn của bạn cho trường hợp 0,1%. Nếu bạn chắc chắn 100%, thì đó git stashvẫn là bạn của bạn vì 100% này có lỗi đo lường ;-).

  • Nếu bạn muốn di chuyển HEADvà đỉnh của chi nhánh hiện tại trong lịch sử, thì đó git reset --keeplà bạn của bạn. Nó sẽ làm tương tự như git reset --hard, nhưng sẽ không loại bỏ các thay đổi cục bộ của bạn.

  • Nếu bạn muốn làm cả hai, thì đó git stash && git reset --keeplà bạn của bạn.

Dạy ngón tay của bạn không sử dụng git reset --hard, nó sẽ trả lại một ngày.


Vì vậy, nếu một trong những điều git stash && git reset --hardđó sẽ xóa sạch bất kỳ nội dung được lưu trữ là đúng?
jxramos

1
Không, git reset --hardkhông loại bỏ rác. git stashlà một sự thay thế git reset --hardtheo nghĩa là nó sẽ loại bỏ các thay đổi không được cam kết khỏi bàn làm việc của bạn, ngoại trừ việc nó giữ chúng an toàn thay vì loại bỏ chúng vĩnh viễn.
Matthieu Moy

hoặc chỉ thực hiện các thay đổi của bạn trước khi bạn đặt lại khó khăn và chúng sẽ vẫn ở trong repo địa phương của bạn
ThaJay

11

Nếu bạn vô tình thiết lập lại một cam kết, thì hãy làm điều này,

git reflog show
git reset HEAD@{2} // i.e where HEAD used to be two moves ago - may be different for your case

giả sử HEAD@{2}là trạng thái bạn mong muốn quay trở lại


điều này hoạt động hoàn hảo với tôi nếu bạn làm điều này trên PowerShell, hãy đảm bảo viết nó như thế này git reset 'HEAD @ {2}' nếu không sẽ không hoạt động trong powershell
VectorX

10

Đây là những gì tôi thường làm nếu tôi mất một số thay đổi.

git reflog
git checkout <commit id> // now you are in where you want but you cannot push from detached branch to master
manually copy and paste changes from detached branch to master or working branch
git reset --hard HEAD // if needed
git add ... > git commit ... > git push ...

để di chuyển con trỏ trở lại các cam kết trước đó của bạn nhưng vẫn giữ các thay đổi bạn đã thực hiện cho đến nay trong kiểm tra cam kết mới nhất của bạn git reset --soft dadada


8

Thông tin bị mất.

Vì bạn không cam kết, .git của bạn không bao giờ lưu trữ thông tin này. Vì vậy, về cơ bản gitkhông thể phục hồi nó cho bạn.

Nhưng, nếu bạn vừa làm git diff, có một cách bạn có thể khôi phục bằng cách sử dụng đầu ra đầu cuối với 3 bước đơn giản sau.

  1. cuộn thiết bị đầu cuối của bạn và tìm kiếm o / p của git diff. Lưu o / p trong một tệp có tên diff.patch
  2. Tìm kiếm & Thay thế tất cả 7 khoảng trắng và 8 dấu cách bằng ký tự tab (\ t) và lưu các thay đổi.
  3. Đi vào kho git của bạn. Áp dụng diff.patch ( patch -p1 < diff.patch)

Bạn đã được cứu! :)

Lưu ý: Trong khi bạn đang sao chép dữ liệu từ thiết bị đầu cuối vào một tệp, hãy cẩn thận và thấy rõ rằng dữ liệu là đầu ra liên tục và không chứa bất kỳ dữ liệu dư thừa nào (do nhấn mũi tên lên và xuống). Nếu không, bạn có thể làm hỏng nó.


7

Tôi gặp vấn đề tương tự và tôi gần như phát điên .... ban đầu tôi đã cam kết dự án và sáp nhập .. sau này khi tôi thử chạy git push --set-upstream origin master tôi đã gặp lỗi này

  fatal: refusing to merge unrelated histories

Vì vậy, tôi đã chạy git reset --hard HEADvà nó đã xóa một dự án 3 tuần nhưng một số lệnh dưới đây lưu lại ngày:

git reset HEAD@{1}         //this command unstage changes after reset
git fsck --lost-found      //I got the dangling commit fc3b6bee2bca5d8a7e16b6adaca6a76e620eca4b
git show <dangling commit something like-> fc3b6bee2bca5d8a7e16b6adaca6a76e620eca4b>
git rebase fc3b6bee2bca5d8a7e16b6adaca6a76e620eca4b

hi vọng điêu nay co ich


6

Bạn có thể lấy lại cam kết sau khi thực hiện reset --hard HEAD .

Sử dụng " git reflog" để kiểm tra lịch sử củaHEAD chi nhánh.

Bạn sẽ thấy cam kết của bạn và id của nó ở đây.

Làm một

git reset {commit Id of the commit you want to bring back}

5

Nếu bạn may mắn có cùng các tệp được mở trên một trình soạn thảo khác (ví dụ: Sublime Text) hãy thử ctrl-z trên các trình soạn thảo đó. Nó vừa cứu tôi ..


3

Tôi phát hiện ra một cách khó khăn là bất kỳ tệp nào không được cam kết trước khi git reset --hard <commit>bị xóa khỏi lịch sử git. Tuy nhiên, tôi đã may mắn giữ phiên mở trình soạn thảo mã của mình trong suốt thời gian tôi nhổ tóc, tôi phát hiện ra rằng một đơn giản control + ztrong mỗi tệp bị ảnh hưởng đã trả lại trạng thái của tệp trở lại phiên bản trước khi Git bắt buộc thiết lập lại mọi thứ tôi không yêu cầu cụ thể.Hooray!!


3

Nếu bạn đang cố gắng sử dụng mã dưới đây:

git reflog show
# head to recover to
git reset HEAD@{1} 

và vì một số lý do đang nhận được:

lỗi: công tắc không xác định `e '

sau đó thử gói HEAD@{1}trong ngoặc kép

git reset 'HEAD@{1}'

3
 git reset HEAD@{4}

4 là thay đổi trước 4 bước trước. nếu bạn chọn một bước chính xác, nó sẽ hiển thị danh sách các tệp mà bạn đã xóa khỏi cứng. sau đó làm:

$ git reflog show

nó sẽ hiển thị cho bạn lịch sử cam kết địa phương mà chúng tôi đã tạo. bây giờ làm:

$ git reset --hard 8c4d112

8c4d112 là một mã bạn muốn đặt lại khó khăn của bạn ở đó. hãy xem https://www.theserverside.com/video/How-to-use-the-git-reset-hard-command-to-change-a-commit-history để có thêm thông tin.


Cảm ơn rất nhiều @mohammad, nó đã cứu tôi. Tôi không thể xem các tệp nguồn của mình sớm hơn, nhưng theo các bước trên tôi đã có thể khôi phục tất cả các tệp nguồn của mình.
Gaurav Bansal

2

Câu trả lời đúng. OK, bây giờ tôi thích git. :-) Đây là một công thức đơn giản hơn.

git log HEAD@{2}
git reset --hard  HEAD@{2}

Trong đó "2" là số lần quay lại nơi bạn đã cam kết thay đổi. Trong trường hợp của tôi, bị gián đoạn bởi đồng nghiệp và sếp để giúp gỡ lỗi một số vấn đề xây dựng; vì vậy, đã thiết lập lại - hai lần; vì vậy, HEAD và HEAD @ {1} đã bị ghi đè. Whew, sẽ mất một công việc khó khăn của chúng tôi.


2

tôi đã làm git reset --hard sai dự án (tôi biết ...). Tôi mới chỉ làm việc trên một tập tin và nó vẫn mở trong và sau khi tôi chạy lệnh.

Mặc dù tôi đã không cam kết, tôi có thể lấy lại tập tin cũ một cách đơn giản COMMAND + Z.


0

Câu trả lời tham khảo từ SO này,

Sau khi chạy git reflog show nói rằng bạn muốn đi đến cam kết 9300f9d

sau khi chạy git reset 9300f9d

bạn có thể thực hiện trạng thái git và sau đó bạn có thể cần kiểm tra (các) tệp của mình để khôi phục các thay đổi của mình

kiểm tra git - filepath / tên


0

Nếu bạn đang phát triển trên Netbeans, hãy xem giữa các tab tệp và khu vực chỉnh sửa tệp. Có một "Nguồn" và "Lịch sử". Trên "Lịch sử", bạn sẽ thấy các thay đổi được thực hiện bằng cách sử dụng kiểm soát phiên bản (git / khác), nhưng cũng có những thay đổi được thực hiện cục bộ. Trong trường hợp này, những thay đổi cục bộ có thể giúp bạn tiết kiệm.


0

( câu trả lời phù hợp cho một tập hợp con của người dùng )

Nếu bạn đang sử dụng macOS (gần đây) và ngay cả khi bạn rời khỏi đĩa Time Machine, HĐH sẽ lưu các bản sao lưu hàng giờ, được gọi là ảnh chụp nhanh cục bộ .

Nhập Time Machine và điều hướng đến tập tin bạn bị mất. Hệ điều hành sau đó sẽ hỏi bạn:

The location to which you're restoring "file.ext" already contains an
item with the same name. Do you want to replace it with the one you're
restoring?

Bạn sẽ có thể khôi phục (các) tệp bạn đã mất.


0

Nếu bạn đã mở IDE với cùng một mã, hãy thử thực hiện ctrl + z trên mỗi tệp riêng lẻ mà bạn đã thực hiện thay đổi. Nó giúp tôi phục hồi các thay đổi không được cam kết của mình sau khi thực hiện git reset --hard.


-3

Khi chúng tôi thực hiện thiết lập lại git - và tất cả các thay đổi không được cam kết cục bộ sẽ bị xóa. Để khôi phục lại các thay đổi - trong IDE, nhấp vào tệp, so sánh tệp với Lịch sử cục bộ sẽ liệt kê các thay đổi theo ngày và chúng tôi có thể khôi phục dữ liệu. Ngày của bạn được lưu!


1
Câu trả lời này lặp lại hai cái trước đó.
isherwood
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.