Hoàn tác một cam kết cụ thể trong Git đã được đẩy lên repos từ xa


788

Cách đơn giản nhất để hoàn tác một cam kết cụ thể đó là:

  • không phải trong đầu hoặc đầu
  • Đã bị đẩy ra xa.

Bởi vì nếu đó không phải là cam kết mới nhất,

git reset HEAD

không hoạt động. Và bởi vì nó đã được đẩy đến một điều khiển từ xa,

git rebase -i

git rebase --onto

sẽ gây ra một số vấn đề trong điều khiển từ xa.

Hơn nữa, tôi không muốn sửa đổi lịch sử thực sự. Nếu có mã xấu, nó đã ở đó trong lịch sử và có thể được nhìn thấy. Tôi chỉ muốn nó trong bản sao làm việc và tôi không bận tâm đến một cam kết hợp nhất ngược.

Nói cách khác, Git tương đương với các lệnh svn nào sau đây:

svn merge -r 303:295 http://svn.example.com/repos/calc/trunk

trong đó loại bỏ tất cả các thay đổi từ 295 đến 302 bằng cách hợp nhất ngược tất cả các thay đổi trong các phiên bản đó, như là một cam kết mới.

svn merge -c -302 ^/trunk

tất nhiên, hoàn tác cam kết 302, tất nhiên bằng cách thêm một cam kết khác, ngược lại hợp nhất các thay đổi từ cam kết tương ứng đó.

Tôi nghĩ rằng nó nên là một hoạt động khá đơn giản trong Git và một trường hợp sử dụng khá phổ biến. Những gì khác là điểm của cam kết nguyên tử?

Chúng tôi đã dàn dựng stashing và tất cả để đảm bảo các cam kết là hoàn toàn nguyên tử, không nên bạn có thể hoàn tác một hoặc nhiều hơn những cam kết nguyên tử một cách dễ dàng?

Câu trả lời:


1210

Xác định hàm băm của cam kết, sử dụng git log, sau đó sử dụng git revert <commit>để tạo một cam kết mới loại bỏ các thay đổi này. Theo một cách nào đó, git revertlà sự đảo ngược của git cherry-pick- cái sau áp dụng bản vá cho một nhánh bị thiếu nó, cái trước loại bỏ nó khỏi một nhánh có nó.


237
Và sử dụng công tắc -n nếu bạn muốn mã trở lại, nhưng không tự động được cam kết lại
jaygooby

17
Tùy chọn "m" làm gì? Tôi đã thử git Revert 8213f7d nhưng thay vào đó: lỗi: Commit 8213f7dad1ed546b434a0d8a64cb783b530a5a30 là một sự hợp nhất nhưng không có tùy chọn -m nào được đưa ra. gây tử vong: hoàn nguyên thất bại
Malcolm

10
Để hoàn nguyên hợp nhất: git
Revert

31
Một cảnh báo cho bất kỳ ai muốn hoàn nguyên hợp nhất: git Revert sẽ hoàn tác tất cả các thay đổi dữ liệu (nghĩa là các thay đổi tệp sẽ được hoàn nguyên), nhưng việc hợp nhất vẫn còn trong lịch sử. Bởi vì điều này nếu bạn cố gắng hợp nhất cùng chi nhánh đó một lần nữa, nó sẽ không bao gồm bất kỳ cam kết nào từ chi nhánh hợp nhất trước khi hợp nhất được hoàn nguyên. Đây rất có thể không phải là những gì bạn muốn. Để hợp nhất hoàn toàn chi nhánh một lần nữa, trước tiên bạn cần hoàn nguyên cam kết nơi bạn hoàn nguyên hợp nhất ban đầu. Tìm hiểu thêm tại đây: kernel.mirrors.pair.com/pub/software/scm/git/docs/howto/ mẹo
etreworgy

3
Liên kết trong nhận xét của @etreworgy là 404. Tôi nghi ngờ đây là phiên bản cập nhật của liên kết: kernel.org/pub/software/scm/git/docs/howto/ tựa
Tim Smith

368

Tôi không thích tự động cam kết git revert, vì vậy điều này có thể hữu ích cho một số người.

Nếu bạn chỉ muốn các tệp sửa đổi không phải là tự động xác nhận , bạn có thể sử dụng--no-commit

% git revert --no-commit <commit hash>

giống như -n

% git revert -n <commit hash>

9
Bạn cũng có thể làm git reset HEAD~1 --softnếu bạn đã hoàn nguyên mà không có-n
Daniel

1
Nhưng git reset HEAD~nsẽ không giải quyết hoàn tác bất kỳ cam kết nào không thể tiếp cận từ đầu. Các truy vấn là để hoàn nguyên bất kỳ cam kết cụ thể.
sangeethkumarp

Tôi đã sử dụng giải pháp này nhưng đã xảy ra xung đột ở giữa hoàn nguyên. Sau khi giải quyết mâu thuẫn, tôi làm git revert --continuetheo chỉ dẫn. Nó làm việc, nhưng đáng buồn cam kết kết quả. Có lẽ tôi cần phải làm git revert --no-commit --continue.
mareoraft

1
@sangeethkumarp bình luận của Daniel là một bước bổ sung mà bạn có thể thực hiện sau git revert , nếu bạn quên -n; bởi vì tại thời điểm đó, lần xác nhận cuối cùng là sự đảo ngược, do đó, thiết lập lại mềm sẽ hoàn tác cam kết đó nhưng không thay đổi mã liên quan của hoàn nguyên
Oliver

@Daniel cung cấp giải pháp bằng cách nhận xét công việc cho tôi Cảm ơn rất nhiều '' git reset HEAD ~ 1 --soft ''
Md. Abu Sayed

41

Bởi vì nó đã được đẩy, bạn không nên trực tiếp thao túng lịch sử. git revertsẽ hoàn nguyên các thay đổi cụ thể từ một cam kết bằng cách sử dụng một cam kết mới, để không thao túng lịch sử cam kết.


1

Nếu cam kết bạn muốn hoàn nguyên là một cam kết đã hợp nhất (đã được hợp nhất), thì bạn nên -m 1hoặc -m 2tùy chọn như hiển thị bên dưới. Điều này sẽ cho git biết cam kết cha mẹ nào của cam kết được hợp nhất sẽ sử dụng. Thông tin chi tiết có thể được tìm thấy TẠI ĐÂY .

  • git revert <commit> -m 1
  • git revert <commit> -m 2
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.