Làm thế nào để hủy cam kết git un-đẩy cuối cùng mà không mất các thay đổi


540

Có cách nào để hoàn nguyên một cam kết để bản sao cục bộ của tôi giữ các thay đổi được thực hiện trong cam kết đó, nhưng chúng trở thành các thay đổi không cam kết trong bản sao làm việc của tôi không? Hoàn trả lại một cam kết đưa bạn đến cam kết trước đó - Tôi muốn giữ các thay đổi đã thực hiện nhưng tôi đã cam kết chúng với chi nhánh sai.

Điều này đã không được thúc đẩy, chỉ cam kết.



6
git reset --softgit reset --mixedcả hai đều làm điều này (một chút khác biệt), xem git-reset
torek

Câu trả lời:


931

Có rất nhiều cách để làm như vậy, ví dụ:

trong trường hợp bạn chưa thúc đẩy cam kết công khai:

git reset HEAD~1 --soft   

Đó là, các thay đổi cam kết của bạn sẽ nằm trong thư mục làm việc của bạn, trong khi đó cam kết LAST sẽ bị xóa khỏi chi nhánh hiện tại của bạn. Xem người đàn ông thiết lập lại git


Trong trường hợp bạn đã đẩy công khai (trên một nhánh gọi là 'master'):

git checkout -b MyCommit //save your commit in a separate branch just in case (so you don't have to dig it from reflog in case you screw up :) )

hoàn nguyên cam kết và đẩy

git checkout master
git revert a8172f36 #hash of the commit you want to destroy
# this introduces a new commit (say, it's hash is 86b48ba) which removes changes, introduced in the commit in question (but those changes are still visible in the history)
git push origin master

ngay bây giờ nếu bạn muốn có những thay đổi đó khi bạn thay đổi cục bộ trong bản sao làm việc của mình ("để bản sao cục bộ của bạn giữ các thay đổi được thực hiện trong cam kết đó") - chỉ cần hoàn nguyên cam kết hoàn nguyên với --no-committùy chọn:

git revert --no-commit 86b48ba (hash of the revert commit).

Tôi đã tạo ra một ví dụ nhỏ: https://github.com/Isantipov/git-revert/commits/master


5
cảm ơn bạn rất nhiều, trong trường hợp của tôi, tôi đã có hai lần cam kết tôi muốn hủy và chạy 'git reset HEAD ~ 1 --soft' hai lần liên tiếp đưa tôi đến nơi tôi cần.
Geoff Gunter

2
để thêm một chút rõ ràng nếu bạn không sử dụng CLI, resetlệnh đầu tiên được đề cập là nói "nhẹ nhàng" đặt lại thành 1 vòng quay trước đầu, giúp duy trì tất cả các thay đổi cục bộ. điều này không rõ ràng ngay lập tức đối với tôi để sử dụng trong SourceTree. chỉ cần đảm bảo rằng bạn đang thiết lập lại mềm cho vòng quay trước, chứ không phải vòng quay bạn đang cố gắng đặt lại
Jon B

1
Tôi đã thử cách tiếp cận "đã được đẩy" và nó không hiệu quả với tôi, với git 2.14.1: nó nói "Already up to date"khi thực hiện hợp nhất.
Fabio A.

1
@FabioA. , Tôi đã cập nhật câu trả lời với một phiên bản làm việc. Cảm ơn vì đã chú ý điều này!
Isantipov

1
Điều này không hoạt động. Tôi đã bỏ qua thiết lập lại và cam kết và chỉ thực hiện git hoàn nguyên và đẩy ra ... bây giờ có thể thay đổi bị mất chưa chắc chắn ... may mắn là tôi đã tạo một bản sao lưu một cách dễ dàng với hy vọng rằng một cái vẫn sẽ hoạt động; .
Skybuck bay

13

Nếu bạn đã đẩy các thay đổi, bạn có thể thực hiện undovà chuyển các tệp trở lại giai đoạn mà không cần sử dụng một nhánh khác.

git show HEAD > patch
git revert HEAD
git apply patch

Nó sẽ tạo một tệp vá chứa các thay đổi nhánh cuối cùng. Sau đó, nó hoàn nguyên các thay đổi. Và cuối cùng, áp dụng các tập tin vá cho cây làm việc.


bạn có thể muốn rm patchquá
Max Coplan

6

Đối với trường hợp: "Điều này đã không được thúc đẩy, chỉ cam kết ." - nếu bạn sử dụng IntelliJ (hoặc IDE JetBrains khác) và bạn chưa đẩy các thay đổi nào bạn có thể làm tiếp theo.

  1. Chuyển đến cửa sổ Kiểm soát phiên bản ( Alt + 9 / Command + 9 ) - tab "Nhật ký".
  2. Nhấp chuột phải vào một cam kết trước khi cuối cùng của bạn.
  3. Đặt lại chi nhánh hiện tại ở đây
  4. chọn Mềm (!!!)
  5. nhấn nút Reset ở dưới cùng của cửa sổ hộp thoại.

Làm xong.

Điều này sẽ "không phổ biến" các thay đổi của bạn và đưa trạng thái git của bạn về điểm trước khi cam kết cục bộ cuối cùng của bạn. Bạn sẽ không mất bất kỳ thay đổi nào bạn đã thực hiện.


2
Tôi thích học cách JetBrains, cảm ơn! Điều đó tương đương với git reset --soft "HEAD^"trên Windows, btw. :)
payne

3

Với tôi hầu hết điều đó xảy ra khi tôi đẩy các thay đổi sang nhánh sai và nhận ra sau này. Và sau đây làm việc trong hầu hết thời gian.

git revert commit-hash
git push

git checkout my-other-branch
git revert revert-commit-hash
git push
  1. hoàn nguyên cam kết
  2. (tạo và) kiểm tra chi nhánh khác
  3. hoàn nguyên

1
Tôi đã thử nghiệm điều này. Cách tiếp cận của bạn cũng hoạt động nếu bạn không được đẩy từ xa. $ git Revert <commit-hash> ... sau đó kiểm tra một số nhánh khác, sau đó nhập $ git Revert <Revert-commit-hash> (không có các lần đẩy). Cảm ơn bạn đã chia sẻ phương pháp đơn giản này !!
Natalie Cottrill

2

Cách đơn giản năm 2020:

git reset <commit_hash>

Cam kết băm của cam kết cuối cùng bạn muốn giữ.


1

Vui lòng đảm bảo sao lưu các thay đổi của bạn trước khi chạy các commANGE này trong một thư mục riêng

kiểm tra chi nhánh git_name

Thanh toán trên chi nhánh của bạn

hợp nhất git --abort

Hủy bỏ hợp nhất

tình trạng git

Kiểm tra trạng thái của mã sau khi hủy hợp nhất

thiết lập lại git - nguồn gốc / nhánh_name

các lệnh này sẽ đặt lại các thay đổi của bạn và căn chỉnh mã của bạn với mã Branch_name (nhánh).

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.