Git: Làm cách nào để chỉnh sửa / điều chỉnh lại thông điệp của một cam kết hợp nhất?


147

Làm cách nào để chỉnh sửa hoặc điều chỉnh lại thông điệp của cam kết hợp nhất?

git commit --amendhoạt động nếu đó là cam kết cuối cùng được thực hiện ( HEAD), nhưng nếu nó đến trước HEADthì sao?

git rebase -i HEAD~5 không liệt kê các cam kết hợp nhất.

Câu trả lời:


206

Nếu bạn thêm --preserve-mergestùy chọn (hoặc từ đồng nghĩa của nó -p) vào git rebase -ilệnh thì git sẽ cố gắng duy trì các kết hợp khi khởi động lại, thay vì tuyến tính hóa lịch sử và bạn cũng có thể sửa đổi các cam kết hợp nhất:

git rebase -i -p HEAD~5

1
Tôi đã thực hiện điều này nhưng sau khi thực hiện các thay đổi của mình và tôi cố gắng thúc đẩy các thay đổi của mình, tôi nhận được điều này! [rejected] HEAD -> master (non-fast-forward)error: failed to push some refs to
Marc

1
hãy thử chạy git đẩy -f và sau đó là nhánh gốc của bạn. cái này nên hoạt động Tôi cũng gặp vấn đề tương tự, vì một số lý do, đây là một yếu tố của sự nổi loạn bởi vì điều cơ bản đã xảy ra là sau khi nổi loạn, bạn đã kết thúc với một cái hốc tách ra, vì vậy, lực lượng nên khắc phục điều đó và nên đẩy mọi thứ.
Radu Comaneci

11
@Marc Điều này xảy ra vì bạn đã sửa đổi các cam kết mà bạn đã gửi. Nó được coi là thực hành xấu để buộc đẩy đến một máy chủ vì nó hoàn toàn có thể đồng bộ hóa bạn và đồng nghiệp của bạn. Chà, nếu bạn ở một mình thì đó không phải là vấn đề.
ibizaman

Cha HEAD~5mẹ của cam kết bạn muốn sửa đổi ở đâu (thường là sha1 ^).
Gabriel Devillers

2
--preserve-mergesbây giờ--rebase-merges
OrangeDog

32

Lưu ý rằng, bắt đầu git1.7.9.6 (và git1.7.10 +), git mergechính nó sẽ luôn kích hoạt trình chỉnh sửa , để bạn thêm chi tiết vào hợp nhất.

" git merge $tag" Để hợp nhất một thẻ chú thích luôn mở trình chỉnh sửa trong phiên chỉnh sửa tương tác. Sê-ri v1.7.10 đã giới thiệu biến môi trường GIT_MERGE_AUTOEDIT để giúp các tập lệnh cũ từ chối hành vi này, nhưng theo dõi bảo trì cũng nên hỗ trợ nó.

Nó cũng giới thiệu một biến môi trường GIT_MERGE_AUTOEDITđể giúp các tập lệnh cũ từ chối hành vi này.

Xem " Dự đoán Git 1.7.10 ":

Gần đây trong một cuộc thảo luận về danh sách gửi thư của Git , Linus đã thừa nhận (và tôi đã đồng ý) rằng đây là một trong những lỗi thiết kế mà chúng tôi đã mắc phải trong lịch sử của Git.
Và trong 1.7.10 trở lên, lệnh git merge được chạy trong phiên tương tác (nghĩa là cả đầu vào tiêu chuẩn và đầu ra tiêu chuẩn của nó được kết nối với thiết bị đầu cuối) sẽ mở trình soạn thảo trước khi tạo cam kết ghi lại kết quả hợp nhất, để đưa ra người dùng có cơ hội giải thích hợp nhất, giống như lệnh git commit mà người dùng chạy sau khi giải quyết hợp nhất đã xung đột.

Linus nói:

Nhưng tôi không thực sự quan tâm sâu sắc đến cách nó thực sự hoạt động - vấn đề chính của tôi là git làm cho nó trở nên quá dễ dàng để có các thông điệp hợp nhất xấu.
Tôi nghĩ rằng một phần của điều đó là một thành ngữ thậm chí còn đơn giản hơn: chúng tôi thậm chí không bao giờ kích hoạt trình chỉnh sửa theo mặc định cho "hợp nhất git", nhưng chúng tôi làm cho " git commit".
Đó là một lỗi thiết kế và nó có nghĩa là nếu bạn thực sự muốn thêm một ghi chú vào một sự hợp nhất, bạn phải làm thêm. Vì vậy, mọi người không
.


Lưu ý rằng, trước Git 2.17 (quý 2 năm 2018), " git rebase -p" các thông điệp nhật ký được đọc sai của một cam kết hợp nhất, hiện đã được sửa.

Xem cam kết ed5144d (ngày 08 tháng 2 năm 2018) của Gregory Herrero (``) .
Gợi ý: Vegard Nossum ( vegard)Quentin Casasnovas ( casasnovas) .
(Được hợp nhất bởi Junio ​​C Hamano - gitster- trong cam kết 8b49408 , ngày 27 tháng 2 năm 2018)

rebase -p: sửa thông báo cam kết không chính xác khi gọi git merge.

cam kết dd6fb00 (" rebase -p: sửa lỗi trích dẫn khi gọi git merge", tháng 1 năm 2018, Git 2.16.0-rc2), thông báo cam kết của cam kết hợp nhất được phản hồi được chuyển đến lệnh hợp nhất bằng cách sử dụng lệnh con ' git rev-parse --sq-quote'.

Các dấu ngoặc kép là cần thiết xung quanh lớp con này để các dòng mới được giữ cho git mergelệnh.

Trước bản vá này, sau thông báo hợp nhất:

"Merge mybranch into mynewbranch

Awesome commit."

trở thành:

"Merge mybranch into mynewbranch Awesome commit."

sau a rebase -p.


Với Git 2.23 (quý 2 năm 2019), một merge -clệnh "" trong khi " git rebase --rebase-merges" sẽ cung cấp cho người dùng cơ hội chỉnh sửa thông điệp tường trình, ngay cả khi không cần phải tạo một hợp nhất mới và thay thế một kết hợp hiện có (thay vào đó là chuyển tiếp nhanh ), nhưng không.
Mà đã được sửa chữa.

Xem cam kết 6df8df0 (02 tháng 5 năm 2019) của Phillip Wood ( phillipwood) .
(Được hợp nhất bởi Junio ​​C Hamano - gitster- trong cam kết c510261 , ngày 13 tháng 6 năm 2019)


16

Một câu trả lời hay khác chỉ sử dụng các lệnh nguyên thủy - bởi knittl https://stackoverflow.com/a/7599522/94687 :

git checkout <sha of merge>
git commit --amend # edit message
git rebase HEAD previous_branch

hoặc một lệnh rebase cuối cùng tốt hơn (chính xác hơn):

git rebase <sha of merge> previous_branch --onto HEAD

BTW, sử dụng các lệnh nguyên thủy có thể có "tính năng" tuyệt vời là không tiêu tốn quá nhiều CPU và khiến bạn phải chờ thời gian không xác định cho đến khi Git kết thúc suy nghĩ về danh sách các cam kết cần phải được khởi động lại trong trường hợp git rebase -p -i HEAD^^^^(một lệnh như vậy sẽ dẫn đến một danh sách chỉ có 4 lần xác nhận cuối cùng với sự hợp nhất là lần cuối cùng trong trường hợp của tôi trong trường hợp của tôi mất khoảng 50 giây!).


2
Điều này thực sự hữu ích, tiết kiệm cho tôi khá nhiều thời gian. Công ty của tôi chặn một số thông điệp cam kết trong kho lưu trữ, điều này rất dễ dàng với --amend hoặc với các lệnh rebase nhưng: Vấn đề lớn nếu chúng ta hợp nhất một số chi nhánh vào của bạn, thực hiện một số cam kết và cố gắng đẩy, thông báo hợp nhất mặc định của git bị chặn ( điều này nên được sửa, tôi biết) điều đó buộc chúng ta phải thay đổi thông điệp đó. Cho đến khi có câu trả lời này, tôi đã thử nhiều cách để thay đổi một thông điệp hợp nhất giữa lịch sử cam kết không thành công.
Giovanni Silva

2

git merge --edit
Cho phép bạn đưa ra nhận xét ngay cả trong trường hợp hợp nhất không tương tác.

git merge --edit --no-ff có thể hữu ích nếu bạn theo dòng git với việc nổi loạn trên nhánh phát triển và sáp nhập vào nó mà không cần chuyển tiếp nhanh.


2

Đối với các phiên bản Git hiện tại (Mai 2020):

git rebase -i -r <parent>,

sau đó thay thế trong trình chỉnh sửa merge -C ...bằng merge -c ....

Điều này sẽ mở thông điệp cam kết trong trình chỉnh sửa trong khi khởi động lại, nơi bạn có thể thay đổi nó.

(Cảm ơn VonC về gợi ý .)


0

Các git rebase -i HEAD~5lệnh bật lên trình soạn thảo. Nó liệt kê các cam kết được chỉ định (trong trường hợp này là năm trong số chúng). Cột đầu tiên chứa pickcho mọi cam kết. Chỉ cần thay thế pickbằng rewordtrong trình soạn thảo đó và lưu + đóng trình chỉnh sửa. Sau đó git sẽ bật lên các biên tập viên cho mỗi cam kết mà bạn đã thay đổi pickđến rewordvà sẽ cho phép bạn chỉnh sửa các cam kết thông báo.


6
Điều này không hoạt động cho một cam kết hợp nhất trừ khi bạn cũng thêm -pvào git rebaselệnh.
Paul Giá

4
câu trả lời tuyệt vời nếu đó là một câu hỏi khác
doz87
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.