Xóa các cam kết git cũ


88

Tôi rất mới sử dụng git, và tự hỏi liệu điều gì đó như thế này có khả thi không?

>git log --pretty=oneline --abbrev-commit
2f05aba Added new feature
3371cec Fixed screw up    <-- I want to remove this
daed25c Screw up          <-- and remove this.
e2b2a84 First.                So it's like they never happend.

Điều này có khả thi không?

Câu trả lời:


63

Điều này có thể với git rebase. Hãy thử những điều sau

git rebase -i HEAD~4

và sau đó, làm theo hướng dẫn tương tác trong trình chỉnh sửa của bạn. Trong bước đầu tiên, bạn "bí mật" các cam kết. Nó sẽ trông giống như sau:

pick 2f05aba ... will be preserved
squash 3371cec ... will be squashed with daed25c
squash daed25c ... will be squashed with e2b2a84
pick e2b2a84 .. will contain this and 3371cec and daed25c

Trong bước thứ hai, bạn có thể chỉnh sửa các thông báo cam kết.


25
Không phải câu hỏi về việc xóa các cam kết thay vì xóa chúng?
Richard

3
@Stony: Chà, bạn cũng có thể xóa chúng. Nhưng từ các nhận xét cam kết trong OP ("Bắt vít" và "Vặn cố định"), tôi đã giả định rằng cái này đang hoàn tác cái kia và bạn cũng có thể làm hỏng cả hai.
Deve

85

Nếu bạn thực sự muốn xóa chúng (xóa chúng khỏi lịch sử, không bao giờ bị nhìn thấy nữa), bạn có thể

chạy rebase:

git rebase -i HEAD~4

và sau đó, chỉ cần xóa (hoặc nhận xét) các dòng tương ứng với các cam kết bạn muốn xóa, như sau:

pick 2f05aba ... #will be preserved
#pick 3371cec ... #will be deleted
#pick daed25c ... #will be deleted
pick e2b2a84 ... #will be preserved

2
Tôi mới sử dụng github, Làm thế nào để bạn đẩy các thay đổi sau đó (khi tôi nhấp vào Đồng bộ hóa, nó chỉ hoàn nguyên những gì tôi đã làm). Tôi nghĩ rằng tôi đã hiểu: git push origin HEAD --force
Nicolas Thery

@NicolasThery bạn không. Đó là lý do tại sao git push từ chối hoạt động nếu không có --force, bởi vì bạn đang viết lại lịch sử và bạn sẽ phá vỡ kho lưu trữ của các dân tộc khác. Nếu bạn đã đẩy thì lựa chọn duy nhất của bạn là thực hiện a git revert. Điều này, khi bạn nghĩ về nó là hợp lý bởi vì nếu bạn kéo mã của người khác, bạn sẽ không muốn họ có thể xóa các cam kết cũ của bạn mà không cần một số loại lịch sử phải không?
Angry Dan

Tôi giả sử điều này chỉ hoạt động trong repo Git hiện tại và không thay đổi bất kỳ thứ gì ngược dòng / bất kỳ nút Git nào khác?
Alexander Mills

2
@AlexanderMills Nó không thay đổi bất cứ điều gì ngược dòng miễn là bạn không đẩy nó (và nếu có, bạn phải thêm cờ --force như Angry Dan đã nói).
Shathur

dhoặc droplà lệnh xóa các cam kết khỏi lịch sử.
Giỏ hàng bị bỏ rơi

5

Để xóa hoàn toàn (các) cam kết, hiện có một tùy chọn mới dropcho giảm giá tương tác git. Lần chạy đầu tiên:

git rebase -i HEAD~4

Sau đó, thay thế pickbằng dropcho (các) cam kết bị loại bỏ:

pick 2f05aba ... #will be preserved
drop 3371cec ... #will be dropped
drop daed25c ... #will be dropped
pick e2b2a84 ... #will be preserved

Điều này đã hoạt động trên Fedora cho tôi với phiên bản sau:

$ git version
git version 2.21.0

2

Squash hữu ích khi bạn muốn tạo danh sách các cam kết hợp nhất dưới một hàm băm duy nhất, nhưng nếu bạn đang muốn thực hiện ba cam kết riêng biệt và có kết quả cuối cùng giống như đó là một cam kết duy nhất, tôi khuyên bạn nên fixup

git rebase -i HEAD~4

pick 2f05aba ... will be preserved
fixup 3371cec ... will be merged with daed25c
fixup daed25c ... will be merged with e2b2a84
pick e2b2a84 .. will include 3371cec and daed25c, but only the commit message of e2b2a84

Bạn có thể tìm thêm thông tin trong danh sách lệnh của giao diện người dùng rebase tương tác.

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.