2012-01-18 31 views
39

Tôi đã làm một cam kết và đẩy lùi vớiGit trở lại cuối cùng cam kết và loại bỏ nó khỏi lịch sử

git revert HEAD^ 

chỉ git log

➜ git:(master) git log 
commit 45a0b1371e4705c4f875141232d7a97351f0ed8b 
Author: Daniel Palacio <[email protected]> 
Date: Tue Jan 17 16:32:15 2012 -0800 

    Production explanation 

Nhưng nếu tôi làm git log --Tất cả nó vẫn xuất hiện. Tôi cần phải loại bỏ nó khỏi lịch sử vì nó có thông tin nhạy cảm

git log --all 
commit 5d44355080500ee6518f157c084f519da47b9391 
Author: Daniel Palacio 
Date: Tue Jan 17 16:40:48 2012 -0800 

    This commit has to be reset 

commit 45a0b1371e4705c4f875141232d7a97351f0ed8b 
Author: Daniel Palacio 
Date: Tue Jan 17 16:32:15 2012 -0800 

    Production explanation 

Làm thế nào để loại bỏ các cam kết 5d44355080500ee6518f157c084f519da47b9391 từ lịch sử quá?

+0

thể trùng lặp của [Git undo commit cuối cùng] (http://stackoverflow.com/questions/927358/git-undo-last-commit) –

+0

@AdrianCornish: Đó là một khởi đầu tốt, nhưng nó không giúp với "thông tin nhạy cảm" bit. –

+0

@KevinBallard - git reset --hard sẽ như thế nào? Giả sử nó đã không được đẩy bất cứ nơi nào - nếu nó đã được đẩy tất cả các cược là tắt –

Trả lời

46

Trước hết, git revert là lệnh sai tại đây. Điều đó tạo ra một cam kết mới mà chuyển đổi một cái cũ hơn. Đó không phải là những gì bạn đang yêu cầu. Thứ hai, có vẻ như bạn muốn hoàn nguyên HEAD thay vì HEAD^.

Nếu bạn chưa đẩy điều này ở bất kỳ đâu, bạn có thể sử dụng git reset --hard HEAD^ để vứt bỏ cam kết mới nhất (điều này cũng loại bỏ mọi thay đổi không được cam kết, vì vậy hãy chắc chắn bạn không có bất kỳ điều gì bạn muốn lưu). Giả sử bạn đồng ý với thông tin nhạy cảm có trong bản sao của bạn và không ai khác, bạn đã hoàn tất. Bạn có thể tiếp tục làm việc và sau đó git push sẽ không đẩy cam kết xấu của bạn.

Nếu đó không phải là một giả định an toàn (mặc dù nếu tôi không muốn nghe lý do tại sao), thì bạn cần hết hạn reflog và buộc thu gom rác thu thập tất cả các đối tượng nổi bật ngay bây giờ. Bạn có thể làm điều đó với

git reflog expire --expire=now --expire-unreachable=now --all 
git gc --prune=now 

mặc dù điều này chỉ nên được thực hiện nếu bạn thực sự tuyệt đối cần làm điều đó.


Nếu bạn đẩy cam kết của bạn, sau đó bạn khá nhiều trong số may mắn. Bạn có thể thực hiện một lực đẩy để hoàn nguyên từ xa (mặc dù chỉ khi phía từ xa cho phép), nhưng bạn không thể xóa chính cam kết đó khỏi cơ sở dữ liệu của cơ sở dữ liệu từ xa, vì vậy bất kỳ ai có quyền truy cập vào kho lưu trữ đó đều có thể tìm thấy nó nếu chúng biết những gì cần tìm.

+2

Tất nhiên, nếu * bạn * có quyền truy cập hệ thống tập tin vào điều khiển từ xa, bạn có thể chỉ đơn giản là làm sạch nó giống như cách bạn đã làm một địa phương. – Cascabel

+0

git reflog hết hạn dường như không hoạt động, tôi vẫn có thể truy cập vào cam kết đó nếu tôi đi qua lịch sử theo cách thủ công. Dù sao tôi chỉ quyết định xóa toàn bộ kho lưu trữ an toàn, lần sau tôi sẽ triển khai từ một ổ đĩa được mã hóa để tôi không phải trải qua điều này. – daniel

+0

Và bạn không biết cách làm như vậy, chỉ xóa lịch sử cam kết ở giữa lịch sử? –

4

Nếu bạn chưa đẩy cam kết nào, bạn có thể chỉ:

git reset --hard ĐẦU ~ 2

(HEAD ~ 2 để loại bỏ bạn gốc cam kết và bạn "trở lại" cam kết).

Thao tác này sẽ đặt lại nhánh hiện tại của bạn thành điểm trong lịch sử trước cam kết bạn muốn xóa. Nếu cam kết đó không nằm trong bất kỳ nhánh nào khác, nó sẽ không được đẩy tới nguồn gốc của bạn.

+0

Điều đó không giúp ích gì với phần lịch sử. Cam kết vẫn còn trong lịch sử. – daniel

+1

Không thực sự, từ thời điểm này trên cam kết đó sẽ không là một phần của chi nhánh hiện tại của bạn, và cuối cùng sẽ bị xóa bởi git gc. Nếu bạn muốn thực sự loại bỏ các cam kết ngay bây giờ, bạn có thể sử dụng git gc để cắt tỉa mà bây giờ, hoặc nhân bản kho lưu trữ một lần nữa; khi nhân bản một kho lưu trữ, chỉ cam kết có thể truy cập bởi một số nhánh là bản sao. –

27

Nếu bạn không quan tâm đến các cam kết, chỉ cần làm:

git reset --hard HEAD~ 

để thổi đi những cam kết.

Nếu bạn muốn thay đổi được trong thư mục làm việc, làm:

git reset HEAD~ 

Tùy thuộc vào những gì bạn đã làm với git revert, bạn có thể phải thay đổi các lệnh trên.Hoàn nguyên tạo một cam kết mới để hoàn nguyên cam kết bạn muốn hoàn nguyên. Vì vậy, sẽ có hai cam kết. Bạn có thể phải làm HEAD~2 để xóa cả hai.

Lưu ý rằng, thông thường, hoàn nguyên là cách an toàn hơn, tốt, hoàn nguyên các thay đổi. Nhưng ở đây, vì bạn muốn xóa dữ liệu nhạy cảm, đặt lại là cách tiếp cận tốt nhất.

5

Có một giải pháp tốt đẹp here. Để xóa cuối cùng (top) cam kết bạn có thể làm

git push [remote] +[bad_commit]^:[branch] 

nơi [bad_commit] là cam kết rằng [chi nhánh] hiện đang trỏ tới, hoặc nếu [chi nhánh] được kiểm tra ra tại địa phương, bạn cũng có thể làm

git reset HEAD^ --hard 
git push [remote] -f 
-1

Để hoàn nguyên thay đổi và xóa lịch sử trong repo từ xa, điều này đã hiệu quả đối với tôi. 1. Để trở lại một cam kết, cố gắng git reset --hard ĐẦU^tại chi nhánh địa phương của bạn và 2. Để buộc đẩy đến chi nhánh từ xa thử git push gốc + branch_name

Để biết thêm thông tin chi tiết tham khảo này https://ncona.com/2011/07/how-to-delete-a-commit-in-git-local-and-remote

+0

Trong trường hợp bạn không nhận thấy, bạn vừa nói chính xác những điều cũ hơn, câu trả lời tốt hơn nhiều đã có. Vui lòng đọc [answer]. – Ajean

Các vấn đề liên quan