git: hủy bỏ cam kết ở giữa gõ tin nhắn


131

Tôi đang ở giữa cam kết. Tôi đã gõ tin nhắn cam kết của tôi trong vim. Bây giờ tôi nhớ tôi cần phải thay đổi một cái gì đó. Tôi nhận ra rằng có những lựa chọn khác để thực hiện những gì tôi muốn, nhưng tôi muốn biết liệu có cách nào để hủy bỏ cam kết nhưng vẫn lưu thông điệp cam kết mà tôi đã gõ cho đến nay.

Câu trả lời:


85

Đúng. Viết thông điệp cam kết vào một tệp khác ( :w /some/other/path.txt). Sau đó thoát khỏi trình soạn thảo mà không lưu ( :q!). Nếu trước đây bạn đã lưu tệp vào đường dẫn ban đầu của nó, hãy xóa mọi thứ và viết tệp trống trước (một thông báo cam kết trống sẽ hủy bỏ cam kết).

Bây giờ, khi bạn đã sẵn sàng cam kết "thực tế", hãy sử dụng tệp tin bạn đã lưu ở đường dẫn thay thế.

Thay phiên, sao chép thông điệp cam kết vào một trong các bộ đệm của vim.

Điều đáng chú ý là bạn thực sự không cần phải làm điều này : commit --amendcho phép bạn thay đổi cam kết sau khi thực hiện, vì vậy giải pháp dễ dàng là tạo ra cam kết với những gì bạn đã có và sau đó sửa chữa nó trước khi đẩy. Bạn thậm chí có thể hoàn thành cam kết ở trạng thái bị hỏng, reset HEAD~(đặt lại trạng thái bản sao làm việc của bạn trước khi cam kết), sửa bản sao làm việc của bạn và sau đó commit -a -c HEAD@{1}sử dụng thông báo cam kết cũ.


7
Lưu ý: Thoát vim bằng cách sử dụng ": q!" sẽ không hủy bỏ cam kết nếu có thông báo xung đột hợp nhất tự động. Thay vào đó, cam kết sẽ tiếp tục và thông báo sẽ không liệt kê các tệp nào có xung đột.
stephenbez

write the empty file (an empty commit message will abort the commit)một phần làm việc như một lá bùa, cảm ơn!
Саша TIẾNG ANH NGÀY 22/11/19

182

Nếu trình soạn thảo của bạn có thể thoát với mã lỗi - Git sẽ hủy bỏ cam kết. Khi sử dụng VIM, gõ

:cq

để thoát với mã lỗi khác không và hủy bỏ cam kết.


5
Đây là một mẹo hay để hủy bỏ commit --amendnhư bạn thường phải xóa thông điệp cam kết hiện có và :wq.
Alex Jasmin

2
Bí quyết đẹp! Tuy nhiên, câu hỏi là làm thế nào để lưu thông điệp cam kết, không xóa nó.
Elijah Lynn

vậy làm thế nào để svn quản lý để làm điều này? Nó nhìn gì ngoài mã thoát?
Chaim Geretz

1
tuyệt vời khi bạn đang thực hiện một cuộc
nổi loạn

đã cứu mạng tôi khi tôi làm git commit --amendthay vì git rebase --continuetrong cuộc nổi loạn.
Weishi Zeng

68

Nếu bạn đã mở vim để viết tin nhắn cam kết của mình, chỉ cần xóa các dòng không bắt đầu bằng # và git sẽ hủy bỏ cam kết của bạn

Aborting commit due to empty commit message.

11
Điều này đặc biệt hữu ích khi bạn muốn hủy bỏ cam kết git --amend.
edsko

1
Câu hỏi là làm thế nào để hủy bỏ cam kết nhưng lưu thông điệp cam kết. Xóa các dòng không bắt đầu bằng # có hiệu quả xóa thông báo cam kết, không lưu thông điệp cam kết. Không chắc làm thế nào điều này có rất nhiều upvote.
Elijah Lynn

2
ggdGsẽ cắt tất cả nội dung của tin nhắn, sau đó khi bạn chạy lần sau, vimbạn có thể chỉ Pvăn bản bạn đã cắt trước đó.
oromoiluig

hoạt động bằng cách sử dụng nano, ctrl + k tất cả các dòng sau đó lưu và thoát sẽ hủy bỏ
Juh_

9

Trong khi bạn có thể hủy bỏ cam kết, một cách tiếp cận khác là sửa đổi cam kết sau đó. Đơn giản chỉ cần cam kết công việc hiện tại của bạn, sau đó thực hiện bất kỳ thay đổi bổ sung nào bạn muốn, git addchúng, sau đó chạy git commit --amend. Bạn sẽ được đặt lại vào trình chỉnh sửa thông báo cam kết và khi bạn lưu, cam kết sẽ được sửa đổi để bao gồm các thay đổi bổ sung và thông báo cam kết mới của bạn.


7

Vâng nó có thể. Để cam kết, trình soạn thảo của bạn PHẢI viết thông điệp cam kết vào tệp .git/COMMIT_EDITMSGvà thoát với mã trạng thái 0.

Vì vậy, nếu bạn đang sử dụng VI / VIM, bạn có thể muốn làm như sau ...

  1. Viết thông điệp cam kết của bạn.
  2. Lưu tin nhắn cam kết với :w(theo mặc định, điều này sẽ lưu nội dung hiện tại vào .git/COMMIT_EDITMSG)
  3. Thoát khỏi trình chỉnh sửa có lỗi :cq
  4. ... làm những gì bạn phải làm ... thậm chí thêm / xóa tệp vào khu vực tổ chức.
  5. Tiếp tục chỉnh sửa thông điệp cam kết hiện tại của bạn với git commit -eF .git/COMMIT_MESSAGE

Các -F /path/to/filesẽ cư biên tập với bất kỳ nội dung cho từ / path / to / file. Tuy nhiên, theo mặc định, điều này sẽ ngay lập tức thực hiện cam kết, trừ khi bạn cung cấp -ethêm cờ để chỉnh sửa .


điều này hoạt động, nhưng ít được ưa thích hơn vì 1) nó giả sử CWD là nơi thư mục .git là 2) Tôi sử dụng git worktrees và với git worktrees, .git thực sự là một tệp cho biết thư mục .git thực sự ở đâu.
Alexander Bird

@AlexanderBird điều này không đúng ... khi bạn muốn nhận thông điệp cam kết cũ ở bước 5), bạn chỉ cần chỉ định một đường dẫn tương đối (giả sử bạn đang ở trong /foo/bar/thư mục, họ hàng từ thư mục gốc của dự án) nhưgit commit -eF ../../.git/COMMIT_MESSAGE
Rudolf Tucek

@AlexanderBird tuyệt vời, chưa được chú ý với tính năng của nhiều cây làm việc trong git. Thx cho gợi ý! Tôi tin rằng nhược điểm duy nhất của việc này là, bạn phải giữ một cái nhìn tổng quan chung trong đầu, điều này ngăn bạn tập trung vào mã thực tế. Và chỉ để nhận thông điệp cam kết về "nơi tôi đã rời đi" nó hơi nặng :)
Rudolf Tucek

1
@AlexanderBird sau đó thay vì :wlàm :sav committmpgit commit -eF committmp
Hashbrown

0

Tôi thường thực hiện các cam kết của mình trong khi IntelliJsử dụng các thiết bị đầu cuối được cung cấp. Thật không may, cam kết của tôi là thủ công:

git commit -m'my message' // etc

Vì vậy, điều duy nhất tôi nghĩ rằng an toàn để làm là chỉ cần đóng cửa sổ thiết bị đầu cuối! Chỉ cần tô sáng văn bản của bạn nếu bạn muốn lưu nó, sau đó sao chép, sau đó đóng cửa sổ terminal.


-2

Câu trả lời @bdonlan là tốt cho chính câu hỏi này nhưng tôi sẽ chỉ ra một tình huống mà bạn có thể muốn một giải pháp tốt hơn.

Nói rằng bạn muốn thêm các thay đổi để cam kết cuối cùng. Vì vậy, bạn làm như @bdolan đề xuất:

git add files
git commit --amend

Hãy tưởng tượng rằng trong khi viết tin nhắn mới, Bạn rất tiếc khi thêm các tệp đó vào cam kết đó. Vấn đề là bạn bị mắc kẹt với một thông báo cam kết đã lưu và thoát khỏi trình chỉnh sửa (có hoặc không lưu) sẽ thêm những thay đổi đó vào lần xác nhận cuối cùng. Quay trở lại điểm bạn đã có trước khi những hành động này yêu cầu bạn phải phân chia cam kết cuối cùng - Tôi cá là bạn muốn tránh nó.

Mẹo nhỏ là lưu và thoát trình soạn thảo trong khi nó chỉ có các dòng bắt đầu bằng #hoặc không có dòng nào cả. Khi bạn thoát, bạn sẽ được chào đón với thông báo:

Aborting commit due to empty commit message.

Và bạn đã không thay đổi cam kết cuối cùng.


Nếu tôi hiểu những gì bạn nói là một vấn đề, thì bạn không chính xác; như đã trình bày ở đây : git commit; vim ....; git commit --amend; git reset HEAD@{1}. Đó là: nếu tôi muốn "hoàn tác" sửa đổi, thì tôi làm không phải chia nhỏ cam kết trước đó. đối tượng cam kết là CHÍNH trước khi sửa đổi được lưu dưới dạng HEAD@{1}. Ngoài ra, zetta đã đề nghị xóa tất cả các dòng không bình luận.
Alexander Bird
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.