Tôi muốn sửa đổi một thông điệp cam kết sâu hơn trong lịch sử và tôi đã đẩy nhiều cam kết mới.
Làm cách nào để thay đổi thông điệp cam kết? Có thể không?
Tôi muốn sửa đổi một thông điệp cam kết sâu hơn trong lịch sử và tôi đã đẩy nhiều cam kết mới.
Làm cách nào để thay đổi thông điệp cam kết? Có thể không?
Câu trả lời:
Thông điệp từ Linus Torvalds có thể trả lời câu hỏi của bạn:
Sửa đổi / chỉnh sửa tin nhắn cam kết cũ
Câu trả lời ngắn: bạn không thể (nếu bị đẩy).
trích xuất (Linus gọi BitKeeper là BK):
Lưu ý bên lề, chỉ vì lợi ích lịch sử: trong BK bạn có thể.
Và nếu bạn đã quen với nó (như tôi) thì nó thực sự khá thiết thực. Tôi sẽ áp dụng một quả bom vá từ Andrew, nhận thấy có gì đó không ổn và chỉ cần chỉnh sửa nó trước khi đẩy nó ra.
Tôi có thể đã làm điều tương tự với git. Nó đã đủ dễ dàng để làm cho thông điệp cam kết không phải là một phần của tên, và vẫn đảm bảo rằng lịch sử không bị ảnh hưởng, và cho phép điều "sửa chữa bình luận sau".
Nhưng tôi đã không làm thế.
Một phần của nó hoàn toàn là "tính nhất quán nội bộ". Git đơn giản là một hệ thống sạch hơn nhờ mọi thứ được bảo vệ SHA1 và tất cả các đối tượng đều được đối xử như nhau, bất kể loại đối tượng. Vâng, có bốn loại đối tượng khác nhau và chúng đều thực sự khác nhau và chúng không thể được sử dụng theo cùng một cách, nhưng đồng thời, ngay cả khi mã hóa của chúng có thể khác nhau trên đĩa, về mặt khái niệm chúng đều hoạt động chính xác giống nhau.
Nhưng tính nhất quán nội bộ không thực sự là một lý do cho việc không linh hoạt, và rõ ràng nó sẽ rất linh hoạt nếu chúng ta có thể sửa chữa sai lầm sau khi chúng xảy ra. Vì vậy, đó không phải là một cuộc tranh luận thực sự mạnh mẽ.
Các thực lý do git không cho phép bạn thay đổi các cam kết thông báo kết thúc lên được rất đơn giản: đó là bằng cách nào, bạn có thể tin tưởng vào thông điệp. Nếu bạn cho phép mọi người thay đổi chúng sau đó, các tin nhắn vốn dĩ không đáng tin lắm.
Để hoàn thành, bạn có thể viết lại lịch sử cam kết cục bộ của mình để phản ánh những gì bạn muốn, như được đề xuất bởi sykora (với một số rebase và thiết lập lại - xin chào, thở hổn hển!)
Tuy nhiên, khi bạn xuất bản lịch sử sửa đổi của bạn một lần nữa (với một git push origin +master:master
, các +
dấu hiệu buộc push to xảy ra, ngay cả khi nó không dẫn đến một "tua" cam) ... bạn có thể nhận được vào một số rắc rối .
Trích từ câu hỏi SO khác này:
Tôi thực sự đã từng bị đẩy với - Force vào kho git.git và bị Linus BIG TIME mắng. Nó sẽ tạo ra rất nhiều vấn đề cho người khác. Một câu trả lời đơn giản là "đừng làm điều đó".
Hiện tại một thay thế git có thể làm thủ thuật.
Cụ thể: Tạo một nhánh làm việc tạm thời
git checkout -b temp
Đặt lại cam kết để thay thế
git reset --hard <sha1>
Sửa đổi cam kết với thông điệp phù hợp
git commit --amend -m "<right message>"
Thay thế cam kết cũ bằng cam kết mới
git replace <old commit sha1> <new commit sha1>
trở lại chi nhánh nơi bạn đã ở
git checkout <branch>
loại bỏ chi nhánh tạm thời
git branch -D temp
đẩy
guess
làm xong.
Bạn có thể sử dụng git rebase -i
(đối với chi nhánh bạn phân nhánh từ) 'i' để tương tác.
Thay thế pick
bên cạnh nhận xét cam kết bạn muốn thay đổi bằng r
(hoặc reword
), lưu và thoát và sau khi thực hiện, bạn sẽ có thể thực hiện chỉnh sửa.
git push
một lần nữa và bạn đã hoàn tất
-p
lập luận về rebase
việc p
dự trữ hợp nhất.
Giả sử bạn có một cái cây như thế này:
dd2e86 - 946992 - 9143a9 - a6fd86 - 5a6057 [master]
Đầu tiên, checkout
một nhánh tạm thời:
git checkout -b temp
Trên temp
nhánh, reset --hard
với một cam kết mà bạn muốn thay đổi thông điệp của nó (ví dụ: cam kết đó là 946992
):
git reset --hard 946992
Sử dụng amend
để thay đổi tin nhắn:
git commit --amend -m "<new_message>"
Sau đó, cây sẽ trông như thế này:
dd2e86 - 946992 - 9143a9 - a6fd86 - 5a6057 [master]
\
b886a0 [temp]
Sau đó, cherry-pick
tất cả các cam kết đó là trước 946992
từ master
để temp
và cam kết họ, sử dụng amend
nếu bạn muốn thay đổi thông điệp của họ cũng như:
git cherry-pick 9143a9
git commit --amend -m "<new_message>
...
git cherry-pick 5a6057
git commit --amend -m "<new_message>
Cây bây giờ trông như thế này:
dd2e86 - 946992 - 9143a9 - a6fd86 - 5a6057 [master]
\
b886a0 - 41ab2c - 6c2a3s - 7c88c9 [temp]
Bây giờ buộc đẩy nhánh tạm thời vào điều khiển từ xa:
git push --force origin temp:master
Bước cuối cùng, xóa chi nhánh master
trên địa phương,git fetch origin
để kéo chi nhánh master
khỏi máy chủ, sau đó chuyển sang chi nhánh master
và xóa chi nhánh temp
.
Bây giờ cả địa phương và từ xa của bạn sẽ có tất cả các tin nhắn được cập nhật.
Tại cửa hàng của chúng tôi, tôi đã giới thiệu quy ước thêm các thẻ chú thích có tên dễ nhận biết để cam kết với các thông báo không chính xác và sử dụng chú thích làm thay thế.
Mặc dù điều này không giúp những người chạy các lệnh "git log" thông thường, nhưng nó cung cấp cho chúng tôi cách khắc phục các tham chiếu theo dõi lỗi không chính xác trong các nhận xét và tất cả các công cụ xây dựng và phát hành của tôi đều hiểu quy ước.
Đây rõ ràng không phải là một câu trả lời chung chung, nhưng nó có thể là điều mà mọi người có thể chấp nhận trong các cộng đồng cụ thể. Tôi chắc chắn nếu điều này được sử dụng ở quy mô lớn hơn, một số loại hỗ trợ bằng sứ cho nó có thể mọc lên, cuối cùng ...
(Từ http://git.or.cz/gitwiki/GitTips#head-9f87cd21bcdf081a61c29985604ff4be35a5e6c0 )
Làm thế nào để thay đổi cam kết sâu hơn trong lịch sử
Vì lịch sử trong Git là bất biến, nên sửa bất cứ thứ gì ngoại trừ lần xác nhận gần đây nhất (cam kết không phải là chi nhánh) yêu cầu lịch sử được viết lại từ cam kết đã thay đổi và chuyển tiếp.
Bạn có thể sử dụng StGIT cho điều đó, khởi tạo chi nhánh nếu cần thiết, không tham gia vào cam kết bạn muốn thay đổi, bật lên nếu cần, thực hiện thay đổi sau đó làm mới bản vá (với tùy chọn -e nếu bạn muốn sửa thông báo cam kết), sau đó đẩy tất cả mọi thứ và stg cam kết.
Hoặc bạn có thể sử dụng rebase để làm điều đó. Tạo nhánh tạm thời mới, tua lại thành cam kết bạn muốn thay đổi bằng cách sử dụng git reset --hard, thay đổi cam kết đó (nó sẽ là đỉnh của đầu hiện tại), sau đó rebase nhánh trên đỉnh của cam kết đã thay đổi, sử dụng git rebase --onto.
Hoặc bạn có thể sử dụng git rebase - tương tác, cho phép sửa đổi khác nhau như sắp xếp lại bản vá, thu gọn, ...
Tôi nghĩ rằng nên trả lời câu hỏi của bạn. Tuy nhiên, lưu ý rằng nếu bạn đã đẩy mã đến một kho lưu trữ từ xa và mọi người đã lấy từ đó, thì điều này sẽ làm rối loạn lịch sử mã của họ, cũng như công việc họ đã làm. Vì vậy, làm điều đó một cách cẩn thận.