Thay đổi tin nhắn cam kết cũ trên Git


136

Tôi đã cố gắng chỉnh sửa một thông điệp cam kết cũ như được giải thích ở đây .

Điều này là bây giờ, khi tôi cố chạy rebase -i HEAD~5nó nói interactive rebase already started.

Vì vậy, sau đó tôi cố gắng: git rebase --continuenhưng đã nhận được lỗi này:

error: Ref refs/heads/master is at 7c1645b447a8ea86ee143dd08400710c419b945b but expected c7577b53d05c91026b9906b6d29c1cf44117d6ba
fatal: Cannot lock the ref 'refs/heads/master'.

Có ý kiến ​​gì không?

Câu trả lời:


125

Nó nói rằng:

Khi bạn lưu và thoát trình chỉnh sửa, nó sẽ tua lại bạn trở lại cam kết cuối cùng trong danh sách đó và thả bạn vào dòng lệnh với thông báo sau:

$ git rebase -i HEAD~3
Stopped at 7482e0d... updated the gemspec to hopefully work better
You can amend the commit now, with

Nó không có nghĩa:

gõ lại git rebase -i HEAD~3

Cố gắng khônggit rebase -i HEAD~3khi thoát khỏi trình soạn thảo, và nó sẽ hoạt động tốt.
(nếu không, trong tình huống cụ thể của bạn, git rebase -i --abortcó thể cần thiết để đặt lại mọi thứ và cho phép bạn thử lại)


Như Dave Vogt đã đề cập trong các bình luận, git rebase --continuelà để đi đến nhiệm vụ tiếp theo trong quá trình nổi loạn, sau khi bạn đã sửa đổi cam kết đầu tiên .

Ngoài ra, Gregg Lind đề cập đến trong câu trả lời của mình về rewordlệnhgit rebase :

Bằng cách thay thế lệnh "chọn" bằng lệnh "chỉnh sửa", bạn có thể yêu git rebasecầu dừng lại sau khi áp dụng cam kết đó, để bạn có thể chỉnh sửa các tệp và / hoặc thông báo cam kết, sửa đổi cam kết và tiếp tục khởi động lại.

Nếu bạn chỉ muốn chỉnh sửa thông báo cam kết cho một cam kết, hãy thay thế lệnh " pick" bằng lệnh " reword" , kể từ Git1.6.6 (tháng 1 năm 2010) .

Nó thực hiện điều tương tự ' edit' trong quá trình rebase tương tác, ngoại trừ việc nó chỉ cho phép bạn chỉnh sửa thông điệp cam kết mà không trả lại quyền điều khiển cho trình bao . Điều này là vô cùng hữu ích.
Hiện tại nếu bạn muốn dọn sạch các tin nhắn cam kết của mình, bạn phải:

$ git rebase -i next

Sau đó đặt tất cả các cam kết thành 'chỉnh sửa'. Sau đó, trên mỗi một:

# Change the message in your editor.
$ git commit --amend
$ git rebase --continue

Sử dụng ' reword' thay vì ' edit' cho phép bạn bỏ qua git-commitgit-rebasegọi .


2
Ngoài ra, git rebase --continueđi đến nhiệm vụ tiếp theo trong quy trình khởi động lại, sau khi bạn đã sửa đổi cam kết đầu tiên.
Dave Vogt

1
Thêm liên kết vào bài viết wiki github để thay đổi thông điệp cam kết
Joy

60

Như Gregg Lind đã đề xuất, bạn có thể sử dụng tua lại để được nhắc chỉ thay đổi thông điệp cam kết (và giữ nguyên cam kết khác):

git rebase -i HEAD~n

Đây nlà danh sách n cam kết cuối cùng.

Ví dụ: nếu bạn sử dụng git rebase -i HEAD~4, bạn có thể thấy một cái gì đó như thế này:

pick e459d80 Do xyz
pick 0459045 Do something
pick 90fdeab Do something else
pick facecaf Do abc

Bây giờ thay thế chọn bằng tua lại cho các cam kết bạn muốn chỉnh sửa các thông báo của:

pick e459d80 Do xyz
reword 0459045 Do something
reword 90fdeab Do something else
pick facecaf Do abc

Thoát khỏi trình chỉnh sửa sau khi lưu tệp và tiếp theo bạn sẽ được nhắc chỉnh sửa các thông báo cho các cam kết bạn đã đánh dấu tua lại , trong một tệp cho mỗi tin nhắn. Lưu ý rằng nó sẽ đã đơn giản hơn nhiều để chỉ chỉnh sửa các bài viết cam kết khi bạn thay thế pickvới reword, nhưng làm điều đó không có tác dụng.

Tìm hiểu thêm trên trang của GitHub để Thay đổi thông điệp cam kết .


Giải thích rất tốt. Cảm ơn: D
Shubham Jain

Cảm ơn @ShubhamJain Rất vui vì câu trả lời của tôi rất hữu ích
Punit Vara

Tôi đã làm điều đó, và sau đó cam kết từ các chi nhánh khác xuất hiện trong chi nhánh của tôi
Reza

@Reza bạn có thể đã làm rối tung mọi thứ. Hãy thử điều này trong một số repo khác. Giải pháp này hoạt động hoàn hảo
Punit Vara

54

FWIW, git rebase tương tác bây giờ có tùy chọn "tua lại", điều này làm cho điều này ít đau đớn hơn nhiều!


3
Khi sử dụng reword, tại sao git không đơn giản cho phép bạn chỉnh sửa các thông điệp cam kết trong tệp đó với danh sách các cam kết? Thay vào đó, nó sẽ khởi chạy trình soạn thảo với một tệp tin nhắn cam kết trên mỗi reworddòng. Điều này là không cần thiết. Ngay cả khi các hành động khác hơn pickhoặc rewordyêu cầu khởi chạy các lệnh bên ngoài, rewordsẽ không bắt buộc điều đó.
Dan Dascalescu

9

Chỉ muốn cung cấp một tùy chọn khác nhau cho việc này. Trong trường hợp của tôi, tôi thường làm việc trên các nhánh riêng lẻ sau đó hợp nhất thành chủ và các cam kết cá nhân tôi làm với địa phương của mình không quan trọng.

Do một git hook kiểm tra số vé thích hợp trên Jira nhưng phân biệt chữ hoa chữ thường, tôi đã bị ngăn không cho đẩy mã của mình. Ngoài ra, cam kết đã được thực hiện từ lâu và tôi không muốn tính có bao nhiêu cam kết quay trở lại cuộc nổi loạn.

Vì vậy, những gì tôi đã làm là tạo ra một nhánh mới từ chủ nhân mới nhất và squash tất cả các cam kết từ nhánh vấn đề thành một cam kết duy nhất trên nhánh mới. Nó dễ dàng hơn đối với tôi và tôi nghĩ rằng đó là ý tưởng tốt để có nó ở đây làm tài liệu tham khảo trong tương lai.

Từ chủ nhân mới nhất:

git checkout -b new-branch

Sau đó

git merge --squash problem-branch
git commit -m "new message" 

Giới thiệu: https://github.com/rotati/wiki/wiki/Git:-Combine-all-messy-commits-into-one-commit-b Before-merging-to-Master-branch


1
Câu trả lời của bạn thực sự đã cứu ngày của tôi :). Tôi đã vật lộn với rebase -ikhoảng 2 giờ và không thành công. Cam kết của tôi đứng sau 18 lần cam kết, vì vậy bạn có thể tưởng tượng. Đây là cách đơn giản và tiện dụng hơn mà tôi có thể tìm thấy mà không cần sử dụng rebase. Cảm ơn bạn!
Carlos Parra

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.