Làm cách nào để hoàn tác 'git reset'?


1313

Cách đơn giản nhất để hoàn tác

git reset HEAD~

chỉ huy? Hiện tại, cách duy nhất tôi có thể nghĩ đến là thực hiện "git clone http: // ..." từ một repo từ xa.


2
Nếu bất cứ ai đang tìm cách hoàn tác thiết lập lại cứng, hãy kiểm tra Hoàn tác thiết lập lại git - HÃY ĐẦU TIÊN ~ 1 . Các giải pháp rất giống nhau.


2
Nó không phải là một bản sao của các câu hỏi liên quan đến --hard! Nguy cơ vô tình chạy lệnh này cao hơn nhiều. Chẳng hạn, bạn muốn hủy bỏ một tập tin duy nhất với git reset foo-file. Bạn chỉ viết phần đầu tiên của tên tệp, nhấn tab để tự động hoàn thành, nó thực sự hoàn thành một tên nhánh, git reset foo-branchthay vào đó bạn không chú ý đến nó và chạy lệnh . Voilà
Yushin Washio

Câu trả lời:


2389

Câu trả lời ngắn:

git reset 'HEAD@{1}'

Câu trả lời dài:

Git giữ một bản ghi của tất cả các cập nhật ref (ví dụ: thanh toán, đặt lại, cam kết, hợp nhất). Bạn có thể xem nó bằng cách gõ:

git reflog

Đâu đó trong danh sách này là cam kết mà bạn đã mất. Giả sử bạn vừa gõ git reset HEAD~và muốn hoàn tác nó. Reflog của tôi trông như thế này:

$ git reflog
3f6db14 HEAD@{0}: HEAD~: updating HEAD
d27924e HEAD@{1}: checkout: moving from d27924e0fe16776f0d0f1ee2933a0334a4787b4c
[...]

Dòng đầu tiên nói rằng HEAD0 vị trí trước đây (nói cách khác, vị trí hiện tại) là 3f6db14; nó đã đạt được bằng cách đặt lại HEAD~. Dòng thứ hai nói rằng HEAD1 vị trí trước (nói cách khác, trạng thái trước khi đặt lại) là d27924e. Nó có được bằng cách kiểm tra một cam kết cụ thể (mặc dù điều đó không quan trọng ngay bây giờ). Vì vậy, để hoàn tác thiết lập lại, hãy chạy git reset HEAD@{1}(hoặc git reset d27924e).

Mặt khác, nếu bạn đã chạy một số lệnh khác kể từ đó cập nhật CHÍNH, thì cam kết bạn muốn sẽ không đứng đầu danh sách và bạn sẽ cần tìm kiếm trong đó reflog.

Một lưu ý cuối cùng: Có thể dễ dàng hơn khi xem xét reflogchi nhánh cụ thể mà bạn muốn hủy đặt lại, nói chính chủ, thay vì HEAD:

$ git reflog show master
c24138b master@{0}: merge origin/master: Fast-forward
90a2bf9 master@{1}: merge origin/master: Fast-forward
[...]

Điều này sẽ có ít tiếng ồn hơn so với chung HEAD reflog.


25
Là một thay thế trực quan và đẹp hơn reflogcho mục đích này, tôi thích sử dụng git log --graph --decorate --oneline $(git rev-list -g --all). Nó cho thấy một cây của tất cả các cam kết, bao gồm cả các nhánh không được đặt tên
texasflood

1
Hãy nói rằng tôi có một thư mục chứa các tập tin hiện có trong đó. Trong thư mục này tôi chạy git init, và ngay sau đó git reset --hard. Không có reflog, hoặc thậm chí bất kỳ nhật ký để bắt đầu. Bây giờ các tập tin này có khá nhiều bánh mì nướng không?
AlanSE

@AlanSE, thật đáng buồn khi những tập tin đó là bánh mì nướng, theo như tôi biết. Nếu bạn chưa bao giờ thực hiện git add(tức là chưa bao giờ dàn dựng phiên bản của tệp đó), thì git checkouthoặc git reset --hardsẽ thổi bay bản sao duy nhất (thư mục làm việc) không có bản sao lưu. Tôi ước nó đã không.
Đánh dấu Lodato

2
git reset HEAD~12Rất tiếc ... không ... git reset HEAD@{12}'git reflog' để giải cứu! ồ chỉ làgit reset HEAD@{1}
Dennis

Sau khi đọc bài viết tuyệt vời git-scm.com/blog/2011/07/11/reset.html git-reset, tôi hơi khó hiểu.
Andriy Drozdyuk

192

Câu hỏi cũ, và câu trả lời được đăng công việc tuyệt vời. Tôi sẽ đồng ý với một lựa chọn khác mặc dù.

git reset ORIG_HEAD

ORIG_HEADtham chiếu các cam kết mà HEADtrước đây đã tham chiếu.


1
Điều này có vẻ tuyệt vời - bạn sẽ có thể xây dựng? "ORIG" ở đây là viết tắt của "bản gốc" hay "nguồn gốc"? Re Ie, nó có thiết lập lại vị trí của TRƯỚC trước khi bắt đầu làm khỉ với nó không? Hoặc đến nơi có nguồn gốc? Điều gì xảy ra nếu bạn đã di chuyển TRƯỚC vài lần trước git reset ORIG_HEAD? Cảm ơn.
Stewohn

ORIG là viết tắt của từ gốc, ORIG_HEAD có nghĩa là ĐẦU gốc, trước khi đặt lại
Sam Gallagher

"Một số thao tác nhất định, chẳng hạn như hợp nhất và đặt lại, ghi lại phiên bản ĐẦU TIÊN trước đó trong ORIG_HEAD ngay trước khi điều chỉnh nó thành giá trị mới. Bạn có thể sử dụng ORIG_HEAD để khôi phục hoặc hoàn nguyên về trạng thái trước đó hoặc để so sánh." Trích từ cuốn sách: "Kiểm soát phiên bản với Git"
Amirreza

56

Hoàn cảnh của tôi hơi khác, tôi đã làm git reset HEAD~ba lần.

Để hoàn tác nó tôi phải làm

git reset HEAD@{3}

vì vậy bạn sẽ có thể làm

git reset HEAD@{N}

Nhưng nếu bạn đã thực hiện thiết lập lại git bằng cách sử dụng

git reset HEAD~3

bạn sẽ cần phải làm

git reset HEAD@{1}

Vì {N} đại diện cho số lượng hoạt động trong Reflog. Như Mark đã chỉ ra trong các ý kiến.


2
tùy chọn được chấp nhận không cung cấp ví dụ về việc chuyển tiếp NI trong tình huống một giờ trước khi tôi muốn chuyển tiếp hơn 1. Đã thử với nhiều và nó đã hoạt động. Muốn thêm nó ở đây. Sẽ hữu ích cho những người đang tìm cách hoàn tác thiết lập lại với git reset HEAD ~ 3
zainengineer

3
nhưng nếu ai đó đã thực hiện git reset HEAD ~ 3, anh ta có thể nhanh chóng xem cách hoàn tác nó, git reset HEAD @ {3} là bắt buộc mà không cần vào reflog git reset HEAD ~ 3 vv là một tình huống phổ biến
zainengineer

1
Tôi nghĩ rằng bất kỳ ai nhìn thấy {1} / {2} sẽ nhận ra rằng số đó có thể là bất kỳ số sửa đổi nào, mà refloglệnh cung cấp cho bạn. Đồng ý rằng quan điểm của bạn về các con số giống nhau cho cả hai hướng ~ 3 / @ {3} nhưng thực sự không cần phải là một câu trả lời mới.
Clint

30

1.Sử dụng git reflogđể có được tất cả các cập nhật tài liệu tham khảo.

2.git reset <id_of_commit_to_which_you_want_restore>

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.