Thêm thay đổi cho một cam kết trước đó với Magit


43

Tôi có 2 lần cam kết, A rồi B, sẵn sàng để được đẩy. Tôi nhận ra tôi đã quên thêm một cái gì đó vào A.

Làm cách nào tôi có thể thêm thay đổi này vào A bằng Magit? Tôi thậm chí không biết phần nào trong tài liệu Git mà tôi nên xem.

Câu trả lời:


68

Hãy giả vờ một lúc rằng bạn muốn thêm một cái gì đó vào HEADcam kết, tức là "cam kết thứ hai B" trong ví dụ của bạn.

Cửa sổ bật lên cam kết trên ctính năng ràng buộc " aSửa đổi". Nhấn phím đó sẽ "sửa đổi" các thay đổi theo giai đoạn đối với HEADcam kết. Vì các xác nhận không thể thay đổi trong Git, nên điều này thực sự sẽ thay thế các cam kết cũ bằng một cam kết mới. Một bộ đệm với thông báo cam kết cũ sẽ bật lên, để bạn có thể sửa đổi nó trong trường hợp thay đổi được thêm vào cũng yêu cầu bạn điều chỉnh thông báo. Như mọi khi, nhấn C-c C-ckhi bạn hoàn thành chỉnh sửa tin nhắn. Điều này tương đương với việc chạy git commit --amendtrên dòng lệnh.

  • a Sửa đổi - thêm các thay đổi theo giai đoạn HEADvà chỉnh sửa thông điệp cam kết của nó

Vì thường xảy ra việc bạn chỉ phải điều chỉnh thay đổi hoặc tin nhắn, Magit cung cấp hai biến thể bổ sung:

  • e Mở rộng - thêm các thay đổi theo giai đoạn vào HEADmà không chỉnh sửa thông điệp cam kết
  • w Phần thưởng - thay đổi thông báo HEADmà không cần thêm các thay đổi theo giai đoạn cho nó

Khi bạn muốn chỉnh sửa một cam kết không HEAD, thì những điều trên sẽ không hoạt động. Các lệnh này luôn "sửa đổi" (tức là thay thế) HEADcam kết. Git không cung cấp một lệnh duy nhất để sửa đổi một cam kết nào khác ngoài HEADviệc này có liên quan nhiều hơn một chút.

Magit không cung cấp một lệnh như vậy, nhưng vì có những tình huống mà trong đó nó là thích hợp hơn để làm điều này trong nhiều bước, chúng tôi sẽ thảo luận rằng đầu tiên.

Sửa đổi một cam kết khác hơn HEADcó thể được chia thành ba bước:

  1. Tạm thời làm cho điều đó khác cam kết ( A) các HEAD.
  2. Sửa đổi HEAD(như được mô tả ở trên), dẫn đến cam kết A'.
  3. Nói với Git để áp dụng lại các cam kết tiếp theo A, nhưng trên đầu trang A'.

Điều này có thể được thực hiện bằng cách sử dụng một rebase tương tác. Nhập rđể hiển thị cửa sổ bật lên rebase. Sau đó gõ mđể gọi biến thể rebase "chỉnh sửa cam kết". Một bộ đệm với các cam kết gần đây xuất hiện. Di chuyển đến cam kết bạn muốn sửa đổi và gõ C-c C-cđể chọn nó. Git sau đó tua lại lịch sử với cam kết đó và hiển thị thông tin về cuộc nổi loạn đang diễn ra trong bộ đệm trạng thái.

Sửa đổi HEADnhư mô tả ở trên. Sau đó nói với Git rằng bạn đã hoàn thành bằng cách gõ r r. Nếu A'Bxung đột thì rebase sẽ dừng lại Bvà bạn phải giải quyết xung đột. Sau khi bạn đã làm như vậy nhấn r rđể tiếp tục.

Nếu bạn biết rằng những thay đổi của bạn Asẽ dẫn đến xung đột với B, thì hãy tiếp tục như mô tả ở trên, nếu không hãy sử dụng phương pháp sau.


Git cho phép tạo "cam kết sửa lỗi" bằng cách sử dụng git commit --fixup A. Điều này tạo ra một cam kết mới , ghi lại những thay đổi "đáng lẽ phải được thực hiện trong một cam kết khác". Cam kết đó trở thành mới HEAD. Cũng tồn tại một --squashbiến thể. Để biết thông tin về sự khác biệt xem git-committrang người đàn ông.

Để thực sự kết hợp các Acam kết và cam kết mới A'và sau đó áp dụng lại Btrên đầu trang, bạn phải sử dụng rebase. Magit cung cấp một lệnh thuận tiện để làm như vậy trên r f.

Sự khác biệt chính của cách tiếp cận ở trên là ở đây trước tiên chúng tôi tạo một cam kết mới và sau đó chúng tôi khởi động lại để kết hợp điều đó với "mục tiêu" và áp dụng lại B. Ở trên chúng tôi bắt đầu với việc nổi loạn thay vì cam kết.

Trong Magit cả --fixupvà các --squashbiến thể đều có sẵn từ cửa sổ bật lên cam kết, trên fs. Nhưng Magit cũng cung cấp các biến thể "tức thời" của các lệnh sửa lỗi và squash trên FS. Các biến thể này tạo ra một cam kết mới như các biến thể "không tức thời", nhưng sau đó chúng ngay lập tức kết hợp cam kết sửa lỗi với cam kết đích bằng cách sử dụng rebase mà không cần bạn phải gọi lệnh khác.

"Sửa lỗi tức thì" ( c F) về cơ bản giống như "mở rộng HEAD" ( c e), ngoại trừ việc nó hoạt động cho bất kỳ cam kết nào, không chỉ HEAD.


Đọc thêm:


Tinh thể rõ ràng! Cảm ơn bạn, gói BTW tuyệt vời.
Mathieu Marques

1
Vâng, tôi nghĩ rằng có một số phần ủy mị trong nửa sau câu trả lời của tôi. Nhưng để tránh những điều đó tôi sẽ phải tăng gấp đôi độ dài của câu trả lời đã dài này, vì vậy tôi rất vui vì điều này hiệu quả với bạn ;-)
tarsius

Cảm ơn cho câu trả lời này tarsius, điều này thực sự làm việc cho tôi.
anquegi

Sự rõ ràng của nửa đầu của lời giải thích này làm cho việc đọc nửa sau, khó theo dõi hơn, khá bực bội!
Lyn Headley

git-committrang man chuyển hướng git-rebase(1)có các dòng này: Thông báo cam kết được đề xuất cho cam kết được gấp lại là nối các thông điệp cam kết của cam kết đầu tiên và của những người có lệnh "squash", nhưng bỏ qua các thông báo cam kết cam kết với "sửa lỗi" chỉ huy. IOW, sử dụng fixup nếu bạn chỉ muốn sửa mã trong lần xác nhận trước, sử dụng squash nếu bạn cũng muốn sửa thông báo cam kết.
Yasushi Shoji

3

git commit --amend –C HEADlà lệnh Git mà bạn muốn tìm kiếm và bạn có thể sửa đổi trong Magit với C-c C-a.


Tôi đang sử dụng Magit mới nhất, C-c C-alà từ phiên bản cũ hơn (tôi nghĩ). Hơn nữa, tôi thấy không có dấu vết của "sửa đổi" trong bộ đệm trợ giúp ( ?).
Mathieu Marques

Xem câu trả lời của Rémi cho phép thuật tương đương 2.x.
npostavs

3

Vì vậy, một quy trình công việc là:

  • thay đổi
  • c (cam kết) f (sửa lỗi - chọn cam kết sửa lỗi của bạn)

Sau đó

  • r (rebase) -a (autosquash, có thể được mặc định) i (tương tác)

Tự động điền sẽ tự động di chuyển tất cả! Fixup cam kết đến đúng nơi và đặt chúng bị đè bẹp trên cơ sở lại.


Điều duy nhất tôi đã làm mà bạn không nói là giai đoạn giữa viên đạn đầu tiên và viên thứ hai. Đánh isản lượng cho tôi Cannot rebase: Your index contains uncommitted changes. Please commit or stash them.. Ngoại trừ tôi không có bất kỳ thay đổi không cam kết nào. : /
Mathieu Marques

Đã thử lại sau khi kéo Proceed despite merge in rebase range? [c]ontinue, [s]elect other, [a]bort. Có phải nó đang cố nói với tôi rằng bản sửa lỗi của tôi có thể gặp sự cố trong lần hợp nhất sắp tới không?
Mathieu Marques

@MathieuMarques: "Ngoại trừ tôi không có bất kỳ thay đổi nào không được cam kết" - git nghĩ rằng bạn làm. Lưu ý thông báo gợi ý những thay đổi được dàn dựng, không phải là những thay đổi. Re : merge in rebase, xem BUGS dưới git help rebase. Tôi đề nghị làm việc sửa chữa trước khi kéo ngược dòng.
npostavs

1

Để thực hiện cam kết cuối cùng, đó là "c a". Fixup là để tăng cường một số cam kết cũ.


Đó là trường hợp, tôi cam kết A rồi B. Cập nhật bài viết cho rõ ràng.
Mathieu Marques
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.