Làm cách nào tôi có thể hủy bỏ các tệp của mình một lần nữa sau khi thực hiện một cam kết cục bộ?


268

Tôi đã thực hiện lệnh sau

git add <foo.java>
git commit -m "add the foo.java file"

Làm cách nào tôi có thể xóa cam kết cục bộ của mình ngay bây giờ và bỏ qua foo.java?

Nếu tôi gõ git reset --hard, tôi thấy rằng nó hoàn nguyên sửa đổi của tôi foo.javavề bản gốc.

Câu trả lời:


452

git reset --soft HEAD~1nên làm những gì bạn muốn Sau này, bạn sẽ có những thay đổi đầu tiên trong chỉ mục (hiển thị với git diff --cached) và những thay đổi mới nhất của bạn không được tổ chức. git statussau đó sẽ trông như thế này:

# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   foo.java
#
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   foo.java
#

Sau đó, bạn có thể làm git add foo.javavà cam kết cả hai thay đổi cùng một lúc.


Tôi đã chỉnh sửa câu trả lời: "Thay đổi được cam kết" có những thay đổi đầu tiên và "những thay đổi không được tổ chức theo cam kết" có những thay đổi thứ hai.
Antti

4
Những gì được mô tả trong câu trả lời này thực sự là những gì git commit --amendlàm; nhưng với một quy trình làm việc phức tạp hơn nhiều. Điều này không trả lời câu hỏi OP đã hỏi, mặc dù đưa ra một hướng tốt ( git reset).
7heo.tk

2
Phải thay thế '^' bằng '~' để làm cho nó hoạt động, vì vậy nó trông giống như:git reset --soft HEAD~
Shahar

3
thực hiện git reset --soft Head ~ 1 sau đó git reset HEAD
Joko Wandiro

câu trả lời hoàn hảo cho những gì tôi muốn!
DeepInJava

78

Sử dụng:

git reset HEAD^

Đó là một thiết lập lại "hỗn hợp" theo mặc định, sẽ làm những gì bạn yêu cầu; đưa foo.java vào trạng thái chưa được sắp xếp, loại bỏ các cam kết gần đây nhất.


2
Bạn có phiền giải thích cho tôi thế nào là thiết lập lại "hỗn hợp", thiết lập lại "mềm" và "cứng" không?
Kit Ho

1
@Kit Ho - hướng dẫn thiết lập lại git có những mô tả tuyệt vời về những điều này.
manojlds

4
@Kit, @manojlds: stackoverflow.com/questions/2530060/ trên (phích cắm không biết xấu hổ)
Cascabel

5
Đó thực sự là câu trả lời đúng duy nhất . Hai câu trả lời khác sẽ dàn dựng các tập tin một lần nữa sau khi thực hiện một cam kết.
7heo.tk

git reset --softkhông hoạt động, nhưng git reset HEAD^đã làm
lời giới thiệu

43

Đối với tôi, cách sau đây dễ đọc hơn (vì thế thích hợp hơn) để làm điều đó:

git reset HEAD~1

Thay vì 1, có thể có bất kỳ số lượng cam kết nào bạn muốn hủy bỏ.


39

git reset --softchỉ dành cho điều đó: nó giống như git reset --hard, nhưng không chạm vào các tập tin.


4
Đó là lời giải thích dễ hiểu nhất mà tôi từng nghe (chỉ 11 từ)! Cảm ơn!
phreakhead

3
Câu trả lời đó là sai. git reset"Giống như git reset --hardnhưng không chạm vào các tập tin.". Không phải git reset --soft. git reset --softsẽ tạo ra các thay đổi, vì vậy bạn sẽ không phải thêm chúng vào dàn dựng trong trường hợp bạn muốn thực hiện chúng, nhưng bạn sẽ phải thực hiện git resetchúng (vâng, lần thứ hai và không có --soft) trong trường hợp bạn không. Vì vậy, câu trả lời là ngắn, nhưng không chính xác.
7heo.tk

12

Để hủy bỏ tất cả các tệp trong cam kết cuối cùng của bạn -

git reset HEAD~


8

"Đặt lại" là cách hoàn tác các thay đổi cục bộ. Khi cam kết, trước tiên bạn chọn các thay đổi để bao gồm với " git add " - đó được gọi là "dàn dựng". Và một khi các thay đổi được dàn dựng, thì bạn " git commit " chúng.

Để thoát ra khỏi dàn hoặc cam kết, bạn "đặt lại" ĐẦU. Trên một nhánh, HEAD là một biến git trỏ đến lần xác nhận gần đây nhất. Vì vậy, nếu bạn đã dàn dựng nhưng chưa cam kết, bạn hãy " git reset HEAD ". Điều đó hỗ trợ cho các Head hiện tại bằng cách thay đổi giai đoạn. Đó là viết tắt của " git reset - trộn lẫn ĐẦU ~ 0. "

Nếu bạn đã cam kết, thì CHÍNH đã nâng cao, vì vậy bạn cần sao lưu vào cam kết trước đó. Tại đây, bạn " đặt lại ĐẦU ~ 1 " hoặc " đặt lại ĐẦU ^ 1 " hoặc " đặt lại ĐẦU ~ " hoặc " đặt lại ĐẦU ^ " - tất cả các đầu tham chiếu trừ đi một.

Đó là biểu tượng tốt hơn, ~ hay ^? Hãy nghĩ về ~ tilde như một luồng duy nhất - khi mỗi cam kết có một cha mẹ duy nhất và đó chỉ là một chuỗi các thay đổi theo trình tự, sau đó bạn có thể tham chiếu ngược lại luồng bằng cách sử dụng dấu ngã, như ĐẦU ~ 1, ĐẦU ~ 2, TRƯỚC ~ 3, đối với cha mẹ, ông bà, ông cố, v.v. (về mặt kỹ thuật, đó là tìm cha mẹ đầu tiên ở các thế hệ trước).

Khi có một sự hợp nhất, thì các cam kết có nhiều hơn một cha mẹ. Đó là khi ^ caret phát huy tác dụng - bạn có thể nhớ vì nó cho thấy các nhánh đi cùng nhau. Sử dụng dấu mũ, ĐẦU ^ 1 sẽ là cha mẹ đầu tiên và ĐẦU ^ 2 sẽ là cha mẹ thứ hai của một cam kết duy nhất - ví dụ như mẹ và cha.

Vì vậy, nếu bạn chỉ quay trở lại một bước nhảy trên một cam kết cha mẹ đơn lẻ, thì HEAD ~ và HEAD ^ là tương đương - bạn có thể sử dụng một trong hai bước.

Ngoài ra, các thiết lập lại có thể --soft , --mixed , hoặc --hard . Thiết lập lại mềm chỉ sao lưu cam kết - nó thiết lập lại CHÍNH, nhưng nó không kiểm tra các tệp từ cam kết trước đó, vì vậy tất cả các thay đổi trong thư mục làm việc đều được giữ nguyên. Và --soft reset thậm chí không xóa giai đoạn (còn được gọi là chỉ mục ), vì vậy tất cả các tệp được dàn dựng vẫn sẽ ở trên sân khấu.

Một --mixed reset (mặc định) cũng không kiểm tra các tập tin từ các cam kết trước đó, vì vậy tất cả các thay đổi được bảo quản, nhưng sân khấu sẽ bị xóa. Đó là lý do tại sao một " git reset HEAD " đơn giản sẽ xóa sân khấu.

Một thiết lập lại - đặt lại ĐẦU, và nó xóa giai đoạn, nhưng nó cũng kiểm tra tất cả các tệp từ cam kết trước đó và do đó nó ghi đè lên bất kỳ thay đổi nào.

Nếu bạn đã đẩy cam kết vào một kho lưu trữ từ xa, thì thiết lập lại không hoạt động tốt như vậy. Bạn có thể đặt lại cục bộ, nhưng khi bạn cố gắng đẩy vào điều khiển từ xa, git sẽ thấy rằng CHÍNH cục bộ của bạn ở phía sau ĐẦU trong nhánh từ xa và sẽ từ chối đẩy. Bạn có thể buộc phải đẩy, nhưng git thực sự không thích làm điều đó.

Ngoài ra, bạn có thể giấu những thay đổi của bạn nếu bạn muốn giữ chúng, kiểm tra sớm hơn cam kết, un-stash thay đổi, giai đoạn đó, tạo ra một mới cam kết, và sau đó đẩy đó.


+1 để giải thích chi tiết về hoạt động. IMO đây sẽ là câu trả lời được chấp nhận!
ISAE

2

Hãy nói rằng bạn muốn hủy bỏ các thay đổi tối đa n cam kết,

Trường hợp băm cam kết như sau:

  • h1
  • h2 ...
  • hn
  • hn + 1

Sau đó chạy lệnh sau:
git reset hn

Bây giờ ĐẦU sẽ ở hn + 1. Thay đổi từ h1 đến hn sẽ không được thực hiện.

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.