Câu hỏi Làm thế nào tôi có thể loại bỏ một cam kết trên GitHub?


Tôi "vô tình" đã đẩy một cam kết để GitHub.

Có thể loại bỏ cam kết này không?

Tôi muốn hoàn nguyên kho lưu trữ GitHub của mình như trước khi commit này.


1410
2018-01-15 23:20


gốc


Lời cảnh cáo: Đừng bao giờ làm điều này khi bạn có nhiều người theo dõi kho lưu trữ của mình, bạn sẽ làm cho kho lưu trữ cục bộ của họ bị mất đồng bộ nếu họ đã lấy các thay đổi mới nhất. Nếu điều này liên quan đến một sai lầm, bạn chỉ có thể thực hiện một cam kết khác để hoàn tác lỗi. Nếu điều này liên quan đến mật khẩu, bạn có thể muốn thay đổi mật khẩu thay thế và không vội vàng xóa mật khẩu này. Buộc mọi thứ không đi mà không có nhược điểm. - Tom Wijsman
Lời cảnh cáo 2: Cam kết vẫn có thể truy cập trực tiếp qua SHA1. Lực đẩy không xóa cam kết, nó tạo ra một cam kết mới và di chuyển con trỏ tập tin vào nó. Để thực sự xóa một cam kết, bạn phải xóa toàn bộ repo. - Gustav
Cảm ơn, WOC2 đã giúp tôi khôi phục lại mã quý giá của tôi từ việc xóa nhầm! Cảm ơn! - kR105
@Gustav "... bạn phải xóa toàn bộ repo." - Hoặc chỉ ép buộc thu gom rác thải vào. - IQAndreas
Phiên bản Bitbucket của câu hỏi này. - naught101


Các câu trả lời:


Chú thích: xin vui lòng xem thay thế để git rebase -i trong các bình luận bên dưới—

git reset --soft HEAD^

Đầu tiên, loại bỏ cam kết trên kho lưu trữ cục bộ của bạn. Bạn có thể làm điều này bằng cách sử dụng git rebase -i. Ví dụ, nếu đó là cam kết cuối cùng của bạn, bạn có thể làm git rebase -i HEAD~2 và xóa dòng thứ hai trong cửa sổ trình soạn thảo bật lên.

Sau đó, ép buộc GitHub bằng cách sử dụng git push origin +branchName

Xem Git Magic Chapter 5: Bài học về lịch sử - Và sau đó một số để biết thêm thông tin (ví dụ: nếu bạn muốn xóa các cam kết cũ hơn).

Oh, và nếu cây làm việc của bạn bẩn, bạn phải làm git stash đầu tiên, và sau đó là git stash apply sau.


1019
2018-01-15 23:24



Chính xác hơn, bạn / có / để stash vì git rebase -i sẽ không cho bạn nếu bạn có cây bẩn. - Otto
Lưu ý rằng điều này vẫn sẽ để lại các cam kết trong reflog. Nếu bạn có dữ liệu nhạy cảm trong đó, bạn có thể phải xóa hoàn toàn. - troelskn
Tôi bối rối. Tại sao không thể bỏ qua git reset --soft HEAD^ và sau đó làm git push origin +master? Tại sao chúng ta sử dụng git rebase -i HEAD^^ trong trường hợp này? - Dennis
@ Dennis vì tôi không quen thuộc với reset --soft 3,5 năm trước. =) - Can Berk Güder
Mọi người hãy cẩn thận. Xem bình luận của subutux dưới đây. Ngay cả sau khi ép buộc GitHub, GH vẫn lưu trữ cam kết của bạn. Từ help.github.com/articles/remove-sensitive-data : "Nguy hiểm: Khi cam kết đã được đẩy, bạn nên xem xét dữ liệu bị xâm phạm. Nếu bạn đã cam kết mật khẩu, hãy thay đổi mật khẩu đó! Nếu bạn đã tạo khóa, hãy tạo một mã mới." - Patrick


git push -f origin HEAD^:master

Điều đó nên "hoàn tác" sự thúc đẩy.


854
2018-01-16 00:11



Điều này cũng làm việc tốt! Nó loại bỏ sự đẩy từ github nhưng để nguyên kho lưu trữ cục bộ của tôi. Cảm ơn! - hectorsq
Vâng, vâng. Nó chỉ làm những gì bạn yêu cầu. :) Kho lưu trữ của bạn và kho lưu trữ từ xa không cần phải có các tham chiếu phù hợp. - Dustin
Tuy nhiên, lưu ý rằng điều này chỉ di chuyển con trỏ nhánh. Cam kết được đẩy vô tình vẫn xuất hiện trong repo từ xa. Trong trường hợp của GitHub, điều này có nghĩa là nó vẫn có thể được nhìn thấy nếu bạn biết hàm băm SHA-1 (ví dụ: từ lịch sử hoạt động của người dùng). - Thiago Arrais
do: git push -f origin HEAD ^ ^: master để đảo ngược 2 thay đổi cuối cùng, hoạt động n lần - ianj
@ianj Lưu ý rằng HEAD có n ^ có thể được thay thế bằng HEAD ~ n, ví dụ: HEAD ~ 3 thay vì HEAD ^^^. - Mark Reed


Để trở lại dễ dàng nếu nó chỉ là một sai lầm (có lẽ bạn đã chia nhỏ một repo, sau đó kết thúc đẩy đến bản gốc thay vì một cái mới) đây là một khả năng khác:

git reset --hard 71c27777543ccfcb0376dcdd8f6777df055ef479

Rõ ràng là hoán đổi số đó cho số cam kết bạn muốn quay trở lại.

Mọi thứ kể từ đó sẽ bị xóa sau khi bạn đẩy lại. Để làm điều đó, bước tiếp theo sẽ là:

git push --force

293
2018-04-21 20:26



CẢNH BÁO: Thao tác này sẽ ghi lại lịch sử của bạn, bạn sẽ mất cam kết và thường không phải là một điều rất hay để làm trong môi trường cộng tác. - Oliver
Vâng, đây là cách dễ nhất và tốt nhất cho tôi. Ngã ba của tôi cần phải được hoàn nguyên trước khi tôi có thể gửi PR cho một thứ khác. Tôi nên đã đặt những thay đổi của tôi trong một chi nhánh để bắt đầu. - Web and Flow
Điều này hoạt động trên các nhánh không được bảo vệ. Nếu nhánh Github được bảo vệ, push cưỡng bức sẽ thất bại. - Adarsha
Hoặc: || git reset --hard HEAD ^ 1 || (1 là lần commit cuối cùng) - Marian07
Làm việc tốt cho tôi - raftaar1191


  1. git log để tìm ra cam kết bạn muốn hoàn nguyên

  2. git push origin +7f6d03:master trong khi 7f6d03 là cam kết trước khi cam kết sai được đẩy. + dành cho force push

Và đó là nó.

Đây là một hướng dẫn rất tốt giải quyết vấn đề của bạn, dễ dàng và đơn giản!


71
2018-02-09 11:58



Tôi khuyên bạn nên hướng dẫn, siêu hữu ích trong việc này. - tfantina
Câu trả lời hay nhất! Điều đang diễn ra rất rõ ràng - Naramsim


Bạn sẽ cần xóa bộ nhớ cache để xóa hoàn toàn bộ nhớ cache. trang trợ giúp này từ git sẽ giúp bạn. (Nó đã giúp đỡ tôi) http://help.github.com/remove-sensitive-data/


34
2017-07-27 22:38



+1: trong khi loại bỏ các cam kết từ chi nhánh của bạn, nó vẫn có sẵn trên GitHub nếu bạn biết URL / SHA-1. Cách duy nhất để xóa cam kết khỏi bộ nhớ cache là bằng cách liên hệ với bộ phận hỗ trợ GH (xem phần 'Dữ liệu được lưu trong bộ nhớ cache trên Github' trong liên kết đó - Patrick
Tôi muốn lưu ý rằng nó có thể là một ý tưởng tốt hơn để thực sự giải thích những gì trên trang và trích dẫn các phần có liên quan. Từ trợ giúp chỉ dẫn, nó nói: "Liên kết với các nguồn lực bên ngoài được khuyến khích, nhưng hãy thêm ngữ cảnh xung quanh liên kết để người dùng của bạn sẽ có một số ý tưởng về nó là gì và tại sao nó lại ở đó. Luôn trích dẫn phần liên quan quan trọng nhất, trong trường hợp mục tiêu trang web không thể truy cập được hoặc sẽ ngoại tuyến vĩnh viễn ". Quy tắc chung: giả vờ liên kết không có ở đó hoặc họ không thể nhấp vào liên kết đó. - Jeremy Rodi
Có một cách khác để xóa bộ nhớ cache: Xóa kho lưu trữ, sau đó tạo lại và đẩy. Mặc dù điều này có thể không xảy ra đối với mọi người, nhưng với nhiều người thì việc này dễ dàng hơn và nhanh hơn việc liên hệ với bộ phận Hỗ trợ Github (và có thể bạn không muốn trỏ đến bên thứ ba [Github] mà bạn đã đẩy dữ liệu nhạy cảm). - Juliane Holzt


Trong trường hợp bạn muốn giữ cam kết thay đổi sau khi xóa:

Lưu ý rằng giải pháp này hoạt động nếu cam kết được xóa là cam kết cuối cùng.


1 - Sao chép tham chiếu cam kết bạn muốn quay lại từ nhật ký:

git log

2 - Đặt lại git thành tham chiếu cam kết:

 git reset <commit_ref>

3 - Stash / lưu trữ các thay đổi cục bộ từ cam kết sai để sử dụng sau này sau khi đẩy đến điều khiển từ xa:

 git stash

4 - Đẩy các thay đổi vào kho lưu trữ từ xa, (-f hoặc --force):

git push -f

5 - Lấy lại các thay đổi được lưu trữ cho kho lưu trữ cục bộ:

git stash apply

7 - Trong trường hợp bạn có các tập tin chưa được chỉnh sửa / mới trong các thay đổi, bạn cần phải thêm chúng vào git trước khi cam kết:

git add .

6 - Thêm bất kỳ thay đổi bổ sung nào bạn cần, sau đó cam kết các tệp cần thiết, (hoặc sử dụng dấu chấm '.' Thay vì chỉ định từng tên tệp, để cam kết tất cả các tệp trong kho lưu trữ cục bộ:

git commit -m "<new_commit_message>" <file1> <file2> ...

hoặc là

git commit -m "<new_commit_message>" .

31
2018-06-07 14:44



Xin vui lòng, tránh chỉnh sửa nhỏ cho câu trả lời của bạn để làm cho nó bật lên trang đầu - Thomas Ayoub
Được rồi, đã ghi nhớ! Sẽ ngừng làm điều đó. - Loukan ElKadi
tuyệt vời @LoukanElKadi - rustyMagnet


Sử dụng git revert để hoàn nguyên việc đẩy của bạn.

git-revert - Hoàn nguyên một số cam kết hiện có

git revert [--edit | --no-edit] [-n] [-m parent-number] [-s] <commit>...
git revert --continue
git revert --quit
git revert --abort

Hoàn nguyên các thay đổi mà các bản vá lỗi có liên quan giới thiệu và ghi lại một số cam kết mới ghi lại chúng. Điều này đòi hỏi cây làm việc của bạn phải sạch sẽ (không có sửa đổi từ cam kết CHÍNH).


25
2017-07-17 08:21



Đó là cách được khuyến nghị để tránh phá vỡ các bản sao của người khác. Nó tạo ra một cam kết mới mà undoes một cam kết trước đó. Tuy nhiên nó không trả lời câu hỏi, đó là để loại bỏ một cam kết từ "lịch sử". - joeytwiddle
nhiều câu trả lời khác là tốt, nhưng đây là cách duy nhất có vẻ hiệu quả nếu bạn không thể ép buộc để làm chủ. - Christopher Hunter


1. git reset HEAD^ --hard
2. git push origin -f

Công việc này cho tôi.


19
2017-08-10 08:41



Nói "Mọi thứ cập nhật" khi cam kết đã được đẩy lên GitHub ... - Benny Neugebauer
Nếu commit A là giá trị cao nhất, B là giá trị thứ hai. Bạn muốn đặt lại cam kết nào? - Hilen
A mới nhất và tôi muốn quay trở lại B. - Benny Neugebauer
git reset B --hard sau đó git push origin -f - Hilen
Điều này làm việc tốt nhất cho tôi khi tôi muốn xóa một cam kết từ một chi nhánh tôi đã làm việc trên. - Leraa


Để xóa cam kết từ kho lưu trữ từ xa:

 git push -f origin last_known_good_commit:branch_name

Để xóa cam kết từ kho lưu trữ cục bộ của bạn:

git reset --hard HEAD~1

liên kết


13
2018-03-07 01:27





Xóa cam kết gần đây nhất, giữ lại công việc bạn đã thực hiện:

git reset --soft HEAD~1

Xóa cam kết gần đây nhất, phá hủy công việc bạn đã thực hiện:

git reset --hard HEAD~1

10
2017-11-15 12:39





Tìm spec spec của commit bạn muốn trở thành người đứng đầu chi nhánh của bạn trên Github và sử dụng lệnh sau:

git push origin +[ref]:[branchName]

Trong trường hợp của bạn, nếu bạn chỉ muốn quay trở lại một lần commit, hãy tìm phần đầu của ref cho commit đó, ví dụ nó là 7f6d03, và tên nhánh bạn muốn thay đổi, ví dụ nó là master, và làm như sau:

git push origin +7f6d03:master

Ký tự cộng thêm được hiểu là --force, điều này sẽ cần thiết vì bạn đang viết lại lịch sử.

Lưu ý rằng bất cứ lúc nào bạn --force một cam kết bạn có khả năng viết lại lịch sử của những người khác đã hợp nhất chi nhánh của bạn. Tuy nhiên, nếu bạn gặp vấn đề một cách nhanh chóng (trước khi bất kỳ ai khác sáp nhập chi nhánh của bạn), bạn sẽ không gặp bất kỳ vấn đề nào.


9
2018-06-22 10:36