Sự khác biệt giữa 'git reset --hard HEAD ~ 1' và 'git reset --soft HEAD ~ 1' là gì?


Câu trả lời:


176

git resetkhông biết năm "chế độ": mềm, hỗn hợp, cứng, hợp nhất và giữ. Tôi sẽ bắt đầu với ba chế độ đầu tiên, vì đây là những chế độ bạn thường gặp. Sau đó, bạn sẽ tìm thấy một khoản tiền thưởng nhỏ, vì vậy hãy tiếp tục theo dõi.

mềm mại

Khi sử dụng, git reset --soft HEAD~1bạn sẽ loại bỏ cam kết cuối cùng khỏi nhánh hiện tại, nhưng các thay đổi tệp sẽ nằm trong cây làm việc của bạn . Ngoài ra, các thay đổi sẽ vẫn còn trên chỉ mục của bạn, vì vậy theo sau với a git commitsẽ tạo một cam kết với các thay đổi chính xác giống như cam kết mà bạn đã "xóa" trước đó.

Trộn

Đây là chế độ mặc định và khá giống với soft. Khi "loại bỏ" một cam kết với git reset HEAD~1bạn, bạn sẽ vẫn giữ các thay đổi trong cây làm việc của bạn nhưng không có trên chỉ mục; vì vậy nếu bạn muốn "làm lại" cam kết, bạn sẽ phải thêm các thay đổi ( git add) trước khi cam kết.

cứng

Khi sử dụng, git reset --hard HEAD~1bạn sẽ mất tất cả các thay đổi không giới hạn ngoài những thay đổi được giới thiệu trong lần cam kết cuối cùng. Các thay đổi sẽ không nằm trong cây làm việc của bạn, vì vậy thực hiện một git statuslệnh sẽ cho bạn biết rằng bạn không có bất kỳ thay đổi nào trong kho lưu trữ của mình.

Đọc kỹ với cái này. Nếu bạn vô tình xóa các thay đổi không giới hạn chưa bao giờ được theo dõi git(nói: cam kết hoặc ít nhất là được thêm vào chỉ mục), bạn không có cách nào để sử dụng lại chúng git.

Tặng kem

giữ

git reset --keep HEAD~1là một trong những thú vị và hữu ích. Nó chỉ đặt lại các tệp khác nhau giữa cam kết hiện tại HEAD và cam kết đã cho. Nó hủy bỏ việc đặt lại nếu bất kỳ ai trong số các tệp này có các thay đổi không giới hạn. Về cơ bản, nó hoạt động như một phiên bản an toàn hơn của hard.

Chế độ này đặc biệt hữu ích khi bạn có một loạt các thay đổi và muốn chuyển sang một nhánh khác mà không làm mất những thay đổi này - ví dụ như khi bạn bắt đầu làm việc với nhánh sai.


Bạn có thể đọc thêm về điều đó trong tài liệu git reset .

Lưu ý
Khi thực hiện git resetxóa một cam kết, cam kết không thực sự bị mất, chỉ là không có tham chiếu nào trỏ đến nó hoặc bất kỳ phần tử nào của nó. Bạn vẫn có thể khôi phục một cam kết đã bị "xóa" bằng git resetcách tìm khóa SHA-1 của nó, chẳng hạn với một lệnh chẳng hạn git reflog.


1
Tôi không đồng ý rằng 3 cái này là những cái chúng ta thường nên sử dụng. Chúng là 3 cái đầu tiên có sẵn để mọi người nói về 3 cái này nhiều hơn, nhưng --hardhầu như không bao giờ là điều đúng đắn để làm, vì --keepnó an toàn hơn nhiều và áp dụng cho hầu hết các senarios nơi --hardhoạt động. Đào tạo các ngón tay của bạn để sử dụng --keepcó thể giúp bạn, tiết kiệm một ngày nào đó ...
Matthieu Moy

Tôi không cố gắng gợi ý rằng chúng ta nên sử dụng chúng, chỉ đơn thuần rằng đây là những lệnh mà người ta thường gặp. Vui lòng chỉnh sửa câu trả lời khi bạn thấy phù hợp.
Sascha Wolf

Để thêm một chút chi tiết, sau khi đặt lại git --soft HEAD ~ 1, sử dụng git commit --reuse-message = HEAD @ {1} để sử dụng lại lần commit cuối cùng với chỉ mục cũ được bảo toàn như được hiển thị ở đây stackoverflow.com/a/ 25930432/2883282
englealuze

3
@MatthieuMoy, muộn ba năm nhưng tôi đã thêm một phần vào keep. ;)
Sascha Wolf

Làm cách nào để hoàn tác cam kết cuối cùng? Xin vui lòng giúp đỡ. Nếu tôi sử dụng git reset --soft HEAD ~ 1, tôi nhận được: death: đối số không rõ ràng 'HEAD ~ 1': bản sửa đổi không xác định hoặc đường dẫn không có trong cây làm việc. Sử dụng '-' để tách các đường dẫn khỏi các bản sửa đổi, như sau: 'git <command> [<revision> ...] - [<file> ...]'
elvis

6

Git reset có 5 chế độ chính: soft, mix, merge, hard, keep . Sự khác biệt giữa chúng là thay đổi hoặc không thay đổi head, stage (chỉ mục), thư mục làm việc .

Git reset --hard sẽ thay đổi head, index và thư mục làm việc.
Git reset --soft sẽ chỉ thay đổi đầu. Không thay đổi chỉ mục, thư mục làm việc.

Vì vậy, nói cách khác, nếu bạn muốn hoàn tác cam kết của mình, --soft phải đủ tốt. Nhưng sau đó, bạn vẫn có những thay đổi từ cam kết xấu trong chỉ mục và thư mục làm việc của mình. Bạn có thể sửa đổi tệp, sửa chúng, thêm chúng vào chỉ mục và cam kết lại.

Với --hard, bạn hoàn toàn có được một phương án sạch sẽ trong dự án của mình. Như thể không có bất kỳ thay đổi nào so với lần cam kết cuối cùng. Nếu bạn chắc chắn đây là những gì bạn muốn thì hãy tiếp tục. Nhưng một khi bạn làm điều này, bạn sẽ mất hoàn toàn cam kết cuối cùng của mình. (Lưu ý: vẫn có cách để khôi phục cam kết bị mất).


5

Đây là một bài viết hữu ích hiển thị bằng đồ thị giải thích về lệnh đặt lại.

https://git-scm.com/docs/git-reset

Reset --hard có thể khá nguy hiểm vì nó ghi đè bản sao làm việc của bạn mà không cần kiểm tra, vì vậy nếu bạn chưa cam kết tệp nào, nó sẽ biến mất.

Đối với cây Nguồn, không có cách nào tôi biết để hoàn tác các cam kết. Nó rất có thể sẽ sử dụng thiết lập lại dưới nắp dù sao


+1 cho liên kết đến tài liệu chính thức. Tôi cũng sẽ đề cập đến git reset --helpđiều giải thích khá tốt (theo ý kiến ​​của tôi) về năm chế độ, hoặc ít nhất là hai chế độ được OP yêu cầu.
ThanksForAllTheFish

1
Liên kết bị hỏng. Có thể đây là phiên bản hiện tại: git-scm.com/docs/git-reset
Kiki Jewell

1

Đây là sự khác biệt chính giữa sử dụng git reset --hardgit reset --soft:

--soft

Hoàn toàn không chạm vào tệp chỉ mục hoặc cây làm việc (nhưng đặt lại đầu, giống như tất cả các chế độ làm). Điều này để lại tất cả các tệp đã thay đổi của bạn "Các thay đổi sẽ được cam kết", như trạng thái git sẽ đặt nó.

--hard

Đặt lại chỉ mục và cây làm việc. Bất kỳ thay đổi nào đối với tệp được theo dõi trong cây làm việc kể từ đó đều bị loại bỏ.


1
Đây là những gì tôi đang tìm kiếm. Gọn gàng và chính xác.
Qasim
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.