Làm thế nào bạn có thể hoàn tác thêm git cuối cùng?


193

Có thể bỏ qua thay đổi giai đoạn cuối (không cam kết) trong git ? Giả sử có rất nhiều tệp trong nhánh hiện tại, một số được dàn dựng, một số thì không. Tại một số điểm, một số lập trình viên ngu ngốc đã vô tình thực hiện:

git add -- .

...thay vì:

git checkout -- .

Lập trình viên này bây giờ có thể làm sáng tỏ những thay đổi cuối cùng của anh ta bằng một số lệnh git ma thuật không? Hay anh ta nên cam kết trước khi thử nghiệm ở nơi đầu tiên?


Heh. Chúng tôi có một câu hỏi và câu trả lời hữu ích trong số này mặc dù.
steveha

2
bản sao có thể của Undo 'git add' trước khi cam kết
Jim Fell

Tôi tin rằng nó không phải là bản sao. OP trong câu hỏi khác đang yêu cầu một cách để hoàn tác điều này hoặc xóa các tệp này khỏi cam kết. Tôi muốn (ed) chính xác và duy nhất để hoàn tác các thay đổi đã được thêm bằng git addlệnh cuối cùng , đặc biệt là đối với các tệp đã thay đổi theo giai đoạn và có một số thay đổi sẽ được hoàn tác, không được dàn dựng. Không thể nói câu hỏi khác không liên quan mặc dù.
Septagram

1
Có lẽ anh ta nên / đã / cam kết trước khi thử nghiệm ở nơi đầu tiên.
android.weasel

@ android.weasel vâng, đó là nhiều năm trước ...
Septagram 21/07/2015

Câu trả lời:


299

Bạn có thể sử dụng git reset. Điều này sẽ 'unstage' tất cả các tệp bạn đã thêm sau lần cam kết cuối cùng.

Nếu bạn muốn hủy bỏ chỉ một số tập tin, sử dụng git reset -- <file 1> <file 2> <file n>.

Ngoài ra, có thể hủy bỏ một số thay đổi trong tệp bằng cách sử dụng git reset -p.


3
Buồn làm sao. Tôi đoán rằng có một cái gì đó sai trong thực hành cam kết của tôi sau khi tất cả. Chấp nhận câu trả lời này, bởi vì bạn đã đề cập đến -pchuyển đổi. Cảm ơn! :)
Septagram

Tạo (cho tôi) lỗi: gây tử vong: Không thể giải quyết 'ĐẦU' dưới dạng tham chiếu hợp lệ. Tôi chưa cam kết bất cứ điều gì (repo mới) chỉ cần thực hiện thêm git. và hối hận Tôi không muốn thiết lập lại toàn bộ add, chỉ một thư mục. git reset - dir /*.* tạo ra lỗi ở trên.
Francis Davey

... Ah, tôi thấy những gì đang xảy ra với tôi. Tôi chưa có bất cứ điều gì để HEAD chỉ ra và vì vậy git reset không thành công (vì nó hoạt động trên HEAD).
Francis Davey

42

Bạn không thể hoàn tác bổ sung git mới nhất , nhưng bạn có thể hoàn tác tất cả adds kể từ lần xác nhận cuối cùng. git resetkhông có đối số cam kết đặt lại chỉ mục (không thay đổi theo giai đoạn):

git reset

2
"Bạn không thể hoàn tác phần bổ sung mới nhất ": Wow, điều này thật đáng ngạc nhiên và có khả năng gây đau đớn. Có một nguồn chính xác cho việc này? Ngoài ra, có một lý do tốt nó nên được như vậy? Cảm ơn!
Andrew Moylan

@AndrewMoylan: tốt, không có cách nào tự động để làm như vậy. Bạn luôn có thể resetmột tập tin duy nhất hoặc sử dụng reset -pđể bỏ qua một hunk cụ thể.
knittl

15

Vì vậy, câu trả lời thực sự cho

Lập trình viên này bây giờ có thể làm sáng tỏ những thay đổi cuối cùng của anh ta bằng một số lệnh git ma thuật không?

thực ra là: Không, bạn không thể bỏ qua lần cuốigit add .

Đó là nếu chúng ta giải thích câu hỏi như trong tình huống sau:

Tập tin ban đầu:

void foo() {

}

main() {
    foo();
}

Thay đổi đầu tiên theo sau git add:

void foo(int bar) {
    print("$bar");
}

main() {
    foo(1337);
}

Thay đổi thứ hai theo sau git add:

void foo(int bar, String baz) {
    print("$bar $baz");
}

main() {
    foo(1337, "h4x0r");
}

Trong trường hợp này, git reset -psẽ không giúp ích gì, vì độ chi tiết nhỏ nhất của nó là các đường. gitkhông biết rằng về trạng thái trung gian của:

void foo(int bar) {
    print("$bar");
}

main() {
    foo(1337);
}

nữa không.


Tôi bực mình vì là một người dùng git mới, đó là một sự khác biệt thực sự quan trọng làm nổi bật những gì bạn bè của tôi mô tả là "giữ vệ sinh checkin tốt" ... trải nghiệm cá nhân của tôi - nó được mô tả là "đi chung xe" (tệ!).
benc


3

Tại ngày git nhắc:

  1. use "git rm --cached <file>..." to unstagenếu tập tin không có trong repo. Nó bỏ qua các tập tin giữ chúng ở đó.
  2. use "git reset HEAD <file>..." to unstagenếu các tệp nằm trong repo và bạn đang thêm chúng dưới dạng sửa đổi. Nó giữ các tập tin như chúng là, và bỏ qua chúng.

Theo hiểu biết của tôi, bạn không thể hoàn tác git add --nhưng bạn có thể hủy bỏ danh sách các tệp như đã đề cập ở trên.


2
  • Xóa tệp khỏi chỉ mục, nhưng giữ nguyên phiên bản và để lại các thay đổi không được cam kết trong bản sao làm việc:

    git reset head <file>
    
  • Đặt lại tệp về trạng thái cuối cùng từ CHÍNH, hoàn tác các thay đổi và xóa chúng khỏi chỉ mục:

    git reset HEAD <file>
    git checkout <file>
    
    # If you have a `<branch>` named like `<file>`, use:
    git checkout -- <file>

    Điều này là cần thiết vì git reset --hard HEADsẽ không làm việc với các tập tin duy nhất.

  • Xóa <file>khỏi chỉ mục và phiên bản, giữ tệp chưa được phiên bản với các thay đổi trong bản sao làm việc:

    git rm --cached <file>
    
  • Xóa <file>khỏi bản sao làm việc và phiên bản hoàn toàn:

    git rm <file>
    

2

Nếu bạn muốn xóa tất cả các tệp đã thêm khỏi git cho cam kết

git reset

Nếu bạn muốn xóa một tập tin cá nhân

git rm <file>

1

Bạn có thể dùng

git reset

để hoàn tác các tệp cục bộ được thêm gần đây

 git reset file_name

để hoàn tác các thay đổi cho một tệp cụ thể


0

Tùy thuộc vào kích thước và quy mô của khó khăn, bạn có thể tạo một nhánh đầu (tạm thời) và cam kết công việc hiện tại ở đó.

Sau đó chuyển sang và kiểm tra chi nhánh ban đầu của bạn và chọn các tệp thích hợp từ cam kết đầu.

Ít nhất bạn sẽ có một bản ghi vĩnh viễn về các trạng thái hiện tại và trước đó để làm việc (cho đến khi bạn xóa chi nhánh đầu đó).

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.