Làm cách nào tôi có thể hoàn tác một `git commit` cục bộ và trên một điều khiển từ xa sau khi` git push`


242

Tôi đã thực hiện git committheo sau a git push. Làm cách nào tôi có thể hoàn nguyên thay đổi đó trên cả kho lưu trữ cục bộ và từ xa?

$ git log
commit 364705c23011b0fc6a7ca2d80c86cef4a7c4db7ac8
Author: Michael Silver <Michael Silver@gmail.com>
Date:   Tue Jun 11 12:24:23 2011 -0700

Câu trả lời:


400
git reset --hard HEAD~1
git push -f <remote> <branch>

(Ví dụ đẩy git push -f origin bugfix/bug123:)

Điều này sẽ hoàn tác cam kết cuối cùng và đẩy lịch sử cập nhật lên điều khiển từ xa. Bạn cần vượt qua -fvì bạn đang thay thế lịch sử ngược dòng trong điều khiển từ xa.


24
Cách khác, sử dụng git reset --hard <the-sha-you-want-to-return-to>.
Alexander Groß

2
Tham chiếu được gọi là CHÍNH (phân biệt chữ hoa chữ thường)
dunni

26
Ngoài ra, hãy cẩn thận - AFAIK bạn không nên làm điều này nếu người khác đã rút khỏi repo.
Amadan

1
@BipinVayalu Nó ảnh hưởng đến chi nhánh bạn hiện đang ở. Chính xác hơn là TRỤ. Đầu thường được "gắn" vào một nhánh (chỉ vào tên nhánh thay vì chỉ trực tiếp vào một cam kết). Vì vậy, nói chung, nó sẽ ảnh hưởng đến các điểm CHÍNH của chi nhánh. Sử dụng git log --decorate --onelineđể tìm ra nơi CHÍNH của bạn chỉ đến.
Alexander Groß

4
git reset HEAD~1nếu bạn không muốn những thay đổi của mình biến mất (những thay đổi chưa được thực hiện). Thay đổi, cam kết và đẩy lạigit push -f [origin] [branch]
softvar

161

Nói chung, thực hiện một cam kết "nghịch đảo", sử dụng:

git revert 364705c

sau đó gửi nó đến điều khiển từ xa như bình thường:

git push

Điều này sẽ không xóa cam kết: nó thực hiện một cam kết bổ sung hoàn tác bất kỳ cam kết đầu tiên đã làm. Bất cứ điều gì khác, không thực sự an toàn, đặc biệt là khi những thay đổi đã được tuyên truyền.


9
Đây là một câu trả lời an toàn hơn (có lẽ tốt hơn) so với câu trả lời của Alexander Groß (câu trả lời được chọn).
Graeck

6
@Graeck Mỗi một giải pháp đều có ý nghĩa và giá trị của nó.
Alexander Groß

5
Đây phải là câu trả lời được chấp nhận, đó là cách tốt nhất để không bao giờ ghi đè lên lịch sử, thậm chí nhiều hơn nếu cộng tác với một nhóm. git resetchỉ được chấp nhận nếu bạn vẫn chưa đẩy các thay đổi đến máy chủ.
Josue Alexander Ibarra

17
@JosueIbarra Tôi không đồng ý cho tất cả các trường hợp. Đối với hầu hết các trường hợp, có, bạn không nên ghi đè lên lịch sử. Tuy nhiên, tôi tin rằng có những trường hợp hợp pháp mà bạn hoàn toàn nên làm. Chẳng hạn, bạn vô tình cam kết và đẩy tập tin bí mật của bạn lên. Điều đó không nên lên trong repo git. Vì vậy, bạn có thể nhanh chóng loại bỏ nó bằng cách sử dụng câu trả lời được chấp nhận ở đây.
bfcoder

11
@bfcoder nếu bạn đã đẩy "bí mật" sang repo từ xa thì đó không còn là bí mật nữa. Và cách khắc phục thích hợp là tạo ra một bí mật mới, không cố gắng che giấu lỗi lầm của bạn.
erbsman

41

Trước hết, hãy thư giãn.

"Không có gì nằm dưới sự kiểm soát của chúng tôi. Sự kiểm soát của chúng tôi chỉ là ảo ảnh.", "Sai lầm là con người"

Tôi hiểu rằng bạn đã vô tình đẩy mã của bạn đến remote-master. Điều này sẽ ổn thôi.

1. Lúc đầu, hãy lấy SHA-1giá trị của cam kết mà bạn đang cố gắng trả lại, ví dụ như cam kết với nhánh chính. chạy cái này:

git log

bạn sẽ thấy bó 'f650a9e398ad9ca606b25513bd4af9fe ...' giống như các chuỗi cùng với mỗi cam kết. sao chép số đó từ cam kết mà bạn muốn quay lại .

2. Bây giờ, gõ lệnh dưới đây:

git reset --hard your_that_copied_string_but_without_quote_mark

bạn sẽ thấy thông báo như "ĐẦU bây giờ". bạn rõ ràng Những gì nó vừa làm là phản ánh sự thay đổi đó cục bộ.

3. Bây giờ, gõ lệnh dưới đây:

git push -f

bạn nên xem như

"warning: push.default không được đặt, giá trị ngầm định của nó đã thay đổi trong ..... ... Tổng 0 (delta 0), tái sử dụng 0 (delta 0) ... ... your_branch_name -> master (bắt buộc cập nhật) . "

Bây giờ, bạn đã rõ ràng. Kiểm tra lại bản gốc với "git log" một lần nữa, fixed_destination_commit của bạn sẽ nằm trên đầu danh sách.

Bạn được chào đón (trước;))

CẬP NHẬT:

Bây giờ, những thay đổi bạn đã thực hiện trước khi tất cả những điều này bắt đầu, giờ đã biến mất. Nếu bạn muốn mang những công việc khó khăn đó trở lại, điều đó là có thể. Nhờ git reflog , và git cherry-pick .

Vì vậy, tôi sẽ đề nghị vui lòng theo dõi blog này hoặc bài đăng này .


đó là một biện pháp tốt để chỉ định điều khiển từ xa và chi nhánh khi thực hiện "git đẩy -f", nhưng "git đẩy -f" sẽ hoạt động trong hầu hết thời gian
Robson

8

git reset HEAD~1nếu bạn không muốn những thay đổi của mình biến mất (những thay đổi chưa được thực hiện). Thay đổi, cam kết và đẩy lạigit push -f [origin] [branch]


3

Bạn có thể thực hiện một rebase tương tác:

git rebase -i <commit>

Điều này sẽ đưa lên trình soạn thảo mặc định của bạn. Chỉ cần xóa dòng chứa cam kết bạn muốn xóa để xóa cam kết đó.

Tất nhiên, bạn cũng sẽ cần truy cập vào kho lưu trữ từ xa để áp dụng thay đổi này ở đó.

Xem câu hỏi này: Git: xóa các xác nhận đã chọn khỏi kho lưu trữ


3

Hãy thử sử dụng

git reset --hard <commit id> 

Xin lưu ý: Ở đây id id sẽ là id của cam kết bạn muốn đến nhưng không phải id bạn muốn đặt lại. đây là điểm duy nhất mà tôi cũng bị mắc kẹt.

sau đó đẩy

git push -f <remote> <branch>

2

Cách khác:

git push origin +364705c23011b0fc6a7ca2d80c86cef4a7c4db7ac8^:master

Buộc nhánh chính của kho lưu trữ từ xa gốc đến cha mẹ của lần xác nhận cuối cùng

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.