Tóm lược
Thông báo lỗi
Không thể 'squash' mà không có cam kết trước đó
có nghĩa là bạn có thể đã cố gắng để squash xuống dưới. Git luôn ép một cam kết mới hơn vào một cam kết cũ hơn hoặc về hướng lên trên như được xem trên danh sách việc cần làm tương tác, đó là một cam kết trên một dòng trước đó. Việc thay đổi lệnh trên dòng đầu tiên trong danh sách việc cần làm của squash
bạn sẽ luôn tạo ra lỗi này vì không có gì cho cam kết đầu tiên đè bẹp.
Sửa chữa
Trước tiên hãy quay lại nơi bạn bắt đầu với
$ git rebase --abort
Nói lịch sử của bạn là
$ git log --pretty=oneline
a931ac7c808e2471b22b5bd20f0cad046b1c5d0d c
b76d157d507e819d7511132bdb5a80dd421d854f b
df239176e1a2ffac927d8b496ea00d5488481db5 a
Đó là, a là cam kết đầu tiên, sau đó là b, và cuối cùng là c. Sau khi cam kết c, chúng tôi quyết định ép b và c lại với nhau:
(Lưu ý: Chạy git log
ống dẫn đầu ra của nó vào máy nhắn tin, less
theo mặc định trên hầu hết các nền tảng. Để thoát máy nhắn tin và quay lại dấu nhắc lệnh của bạn, hãy bấm q
phím.)
Chạy git rebase --interactive HEAD~2
cho bạn một trình soạn thảo với
pick b76d157 b
pick a931ac7 c
# Rebase df23917..a931ac7 onto df23917
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
(Lưu ý rằng danh sách việc cần làm này theo thứ tự ngược lại so với đầu ra của git log
.)
Việc thay đổi b pick
thành squash
sẽ dẫn đến lỗi mà bạn đã thấy, nhưng nếu thay vào đó, bạn ép c thành b (cam kết mới hơn vào cũ hơn hoặc nghiền nát hướng lên trên) bằng cách thay đổi danh sách việc cần làm thành
pick b76d157 b
squash a931ac7 c
và thoát khỏi trình soạn thảo của bạn, bạn sẽ nhận được một trình soạn thảo khác có nội dung
# This is a combination of 2 commits.
# The first commit's message is:
b
# This is the 2nd commit message:
c
Khi bạn lưu và thoát, nội dung của tệp đã chỉnh sửa sẽ trở thành thông báo cam kết của cam kết kết hợp mới:
$ git log --pretty=oneline
18fd73d3ce748f2a58d1b566c03dd9dafe0b6b4f b and c
df239176e1a2ffac927d8b496ea00d5488481db5 a
Lưu ý về lịch sử viết lại
Rebase tương tác viết lại lịch sử. Cố gắng đẩy đến một điều khiển từ xa có chứa lịch sử cũ sẽ thất bại bởi vì nó không phải là một chuyển tiếp nhanh.
Nếu chi nhánh bạn nổi loạn là một chủ đề hoặc chi nhánh tính năng mà bạn đang làm việc một mình , không có vấn đề gì lớn. Việc đẩy sang kho lưu trữ khác sẽ yêu cầu --force
tùy chọn, hoặc thay vào đó, bạn có thể, tùy thuộc vào quyền của kho lưu trữ từ xa, trước tiên xóa chi nhánh cũ và sau đó đẩy phiên bản được khởi động lại. Ví dụ về các lệnh sẽ có khả năng phá hủy công việc nằm ngoài phạm vi của câu trả lời này.
Viết lại lịch sử đã xuất bản trên một chi nhánh tại mà bạn đang làm việc với những người khác mà không cần rất lý do chính đáng như bị rò rỉ mật khẩu hoặc các chi tiết nhạy cảm lực lượng lao động khác vào cộng tác viên của bạn và chống đối xã hội và sẽ làm phiền nhà phát triển khác. Phần mềm phục hồi từ một phần Rebase ngược dòng trong git rebase
tài liệu giải thích, với sự nhấn mạnh thêm.
Rebasing (hoặc bất kỳ hình thức viết lại nào khác) một nhánh mà những người khác đã làm việc dựa trên đó là một ý tưởng tồi: bất kỳ ai ở hạ lưu của nó đều bị buộc phải tự sửa lịch sử của họ. Phần này giải thích cách thực hiện sửa chữa theo quan điểm của hạ lưu. Tuy nhiên, cách khắc phục thực sự sẽ là tránh việc ngược dòng ở vị trí đầu tiên. Giáo dục