Cách hợp nhất xung đột Git trong Emacs


84

Sự hợp nhất Git gần đây của tôi đã dẫn đến một số lượng lớn các xung đột. Cách tiếp cận hiện tại của tôi là tìm kiếm sự xuất hiện tiếp theo của '<<<' và sau đó thực hiện hợp nhất bằng cách chỉnh sửa văn bản tiêu chuẩn.

Câu hỏi : có cách nào Emacs có thể hỗ trợ hợp nhất bằng cách sử dụng thông tin có sẵn trong Git về phiên bản của tôi, phiên bản của chúng và phiên bản cơ sở của tệp không?


Chỉnh sửa: Câu hỏi này có phạm vi khác với câu hỏi liên quan này , vì nó không giới hạn trong việc gọi ediff.


7
Nếu bạn đã sử dụng Magit, bạn có thể tải lên bộ đệm trạng thái và sau đó nhấn evào các tệp được hiển thị là xung đột. Magit sẽ khởi chạy ediffđể thực hiện việc hợp nhất và nhắc bạn sau đó để xác nhận các thay đổi của bạn, sau đó bạn có thể tạo tập tin được hợp nhất.
wvxvw

@Beginner: 3 người khác nghĩ rằng đó là một bản sao và tôi là người bỏ phiếu cuối cùng. Tại sao: các chủ đề khác được trích dẫn đưa ra cùng một câu trả lời ( smergevc-resolve-conflict, cũng như một trên ediff) và đã tồn tại lâu hơn. Tôi đồng ý rằng chủ đề đầu tiên có thể sử dụng một tiêu đề tốt hơn, mặc dù.
Dan

@Dan Tôi không đồng ý: đó là một câu hỏi khác và câu trả lời tương tự không làm thay đổi điều đó.
Người mới bắt đầu

1
@IqbalAnsari: Tôi nghĩ rằng chủ đề khác cần một tiêu đề tốt hơn để mọi người có thể tìm thấy nó dễ dàng hơn. Trong thực tế, tôi nghĩ tiêu đề chủ đề của người mới bắt đầu sẽ là tuyệt vời cho nó. Tuy nhiên, chúng ta hãy chờ một chút để xem mọi người có muốn mở lại chủ đề này không. Nếu không, tôi sẽ ủng hộ việc đổi tên chuỗi đầu tiên với tiêu đề của Người mới bắt đầu.
Dan

1
Và với những gì đáng giá, tôi nghĩ đây là một câu hỏi hay với những câu trả lời hay. Chỉ là tôi cũng nghĩ đó là một bản sao - nhưng những người khác có thể không chia sẻ ý kiến ​​đó (về sự trùng lặp, đó là).
Dân

Câu trả lời:


86

Bạn có thể muốn thử smerge-modechỉ cần mở tệp xung đột và làm M-xsmerge-modeRET. Nó sẽ làm nổi bật tất cả các khu vực xung đột. Nó cũng bổ sung các phím bấm để dễ dàng giải quyết các xung đột, tham khảo ý kiến ​​của nó C-hfsmerge-modeRETđể biết chúng.

Tiền tố mặc định

Tôi tìm thấy tiền tố mặc định cho smerge-mode C-c^cồng kềnh vì vậy tôi đã thay đổi nó thành C-cv

(setq smerge-command-prefix "\C-cv")

Bàn phím quan trọng

Đối với tôi các ràng buộc quan trọng nhất là:

smerge-nextràng buộc để smerge-command-prefixndi chuyển đến xung đột tiếp theo.

smerge-previousràng buộc để smerge-command-prefixpdi chuyển đến xung đột trước đó.

smerge-keep-currentràng buộc để smerge-command-prefixRETgiữ phiên bản con trỏ được bật.

smerge-keep-mineràng buộc để smerge-command-prefixmgiữ những thay đổi của bạn.

smerge-keep-otherràng buộc để smerge-command-prefixogiữ những thay đổi khác.

smerge-ediffbị ràng buộc để smerge-command-prefixEbắt đầu một phiên ediff để hợp nhất các xung đột. Điều này giống như vc-resolve-conflicts(cảm ơn @phils và @Malabarba đã chỉ ra điều này).

Kích hoạt chế độ smerge tự động

CẬP NHẬT: Những điều sau chỉ liên quan đến các phiên bản Emacs trước đây 25.1, những điều sau đây có thể gây ra sự cố cho các phiên bản sau, xem https://github.com/magit/magit/issues/3897

Ngoài ra, bạn có thể quan tâm đến việc tự động bật smerge-modekhi truy cập tệp / bộ đệm với các dấu xung đột, bạn có thể sử dụng một cái gì đó như sau để đạt được điều này

(defun my-enable-smerge-maybe ()
  (when (and buffer-file-name (vc-backend buffer-file-name))
    (save-excursion
      (goto-char (point-min))
      (when (re-search-forward "^<<<<<<< " nil t)
        (smerge-mode +1)))))

(add-hook 'buffer-list-update-hook #'my-enable-smerge-maybe)

Lưu ý rằng tôi đang sử dụng buffer-list-update-hookvà không phải find-file-hookvì hầu hết các lần tôi gặp xung đột trong bộ đệm đã được mở trong emacs trong trường hợp find-file-hookkhông có ích.

Cũng kiểm tra các phương pháp khác được đề cập trong câu trả lời này


1
(1) Đừng quên smerge-ediff. (2) Bạn đang dùng phiên bản Emacs nào? Trên nhánh chính của emacs hiện tại, smerge sẽ tự động bật. (3) Tại sao bạn sử dụng buffer-list-update-hookthay vì find-file-hook?
Malabarba

Để làm rõ thêm, lưu ý rằng smerge-ediffvc-resolve-conflictslà điều tương tự.
phils

@Malabarba 1) Tôi đã đề cập đến smerge-modecác phím bấm được ghi lại trong tài liệu của nó. Có lẽ tôi có thể trích dẫn hướng dẫn ở đây cho đầy đủ. Cảm ơn vì bạn đã phản hồi. 2) Tôi đang ở phiên bản 24,5, mặc dù đôi khi tôi thử dùng nhánh chính, tôi không nhớ smerge được bật tự động (đây có phải là thay đổi gần đây không?). 3) Đó là bởi vì hầu hết các lần tôi gặp xung đột trong các bộ đệm đã mở, trong trường hợp đó tôi cần phải bật một cách rõ ràngsmerge-mode
Iqbal Ansari

@IqbalAnsari có lý do gì để không smerge-modekích hoạt mọi lúc không? Có lẽ nó không làm được gì nhiều cho đến khi được gọi.
PythonNut

@PythonNut Câu hỏi hay, thật không may, tôi không có câu trả lời vì tôi chưa bao giờ thử giữ nó cho phép mọi lúc, dù vậy nó cũng đáng để thử
Iqbal Ansari

32

Chỉnh sửa: vì câu trả lời này có nhiều upvote hơn tôi mong đợi, tôi đã mở rộng nó một chút.

Để bổ sung câu trả lời của @IqbalAnsari, bạn cũng có thể sử dụng vc-resolve-conflicts(như được đề cập bởi những người khác, đó là một bí danh smerge-ediff). Điều này sẽ bắt đầu ediffgiao diện. Ở bên trái sẽ là cha mẹ hợp nhất đầu tiên và cha mẹ hợp nhất thứ hai ở bên phải. Chúng được dán nhãn trên modeline với MINEOTHERtương ứng. Bộ đệm hợp nhất được hiển thị bên dưới (xem ảnh chụp màn hình).

Ảnh chụp màn hình giao diện <code> ediff </ code>

Tổ hợp phím

  • Điều hướng thông qua các xung đột với np.
  • Chấp nhận phiên bảnahoặc b.
  • Nhìn tổ tiên với /!
  • Thoát khỏi phiên ediff với q.

Bạn cũng có thể điều hướng đến bộ đệm đã hợp nhất other-windowvà chỉnh sửa bằng tay trong trường hợp giải quyết xung đột phức tạp hơn là chấp nhận một phiên bản. Khi bạn đã hoàn tất, bạn có thể lưu bộ đệm và thoát Emacs như bình thường. Để được trợ giúp thêm, chỉ cần sử dụng ?trong ediffphiên, có cả đống lệnh rất hữu ích trong đó. Tôi vẫn không biết một nửa trong số họ làm gì!


2
Đây là phương pháp IMO đẹp nhất. Tôi có ràng buộc với nó C-x v <, mặc dù trong thực tế tôi có nhiều khả năng sẽ gọi nó bằng Magit (theo nhận xét của wvxvw).
phils

1
Vì năm 2000 vc-resolve-conflictlà một bí danh smerge-ediff, như cái tên gợi ý bắt đầu một phiên Ediff, không phải là phiên Emerge. Nhân tiện, tiêu đề thư viện ediff.elthừa nhận emerge.elảnh hưởng của nó và sau đó tiếp tục nói "Phiên bản hiện tại của Ediff thay thế Emerge. Nó cung cấp giao diện người dùng ưu việt và có nhiều tính năng chính không có trong Emerge. Đặc biệt, nó có thể vá và So sánh tập tin 2 chiều và 3 chiều, hợp nhất và hoạt động thư mục. "
tarsius

6
Cũng lưu ý rằng magit-ediff-resolve( Emhoặc etrên một tệp có xung đột) sử dụng smerge-ediffnội bộ. Tuy nhiên, nó ghi đè lên ediff-quit-hookđể cung cấp trải nghiệm kết thúc phiên tốt hơn một chút. Thay vì nói với bạn rằng bạn có thể lưu "bộ đệm" (có một số bộ đệm), nó hỏi bạn có muốn lưu bộ đệm không (trong khi hiển thị cho bạn tên của nó).
tarsius

Có cách nào để hiển thị 4 cửa sổ (của chúng tôi, cha mẹ, của họ, không gian làm việc) như vimdiff không?
dùng1133275

9

Nếu bạn tình cờ sử dụng Spacemac, tôi khuyên bạn nên kích hoạt "chế độ smerge-transient-mode", trình đơn này sẽ hiển thị menu hydra với tất cả các lệnh smerge có thể.

Để làm điều đó, chỉ cần gọi Mx spacemacs/smerge-transient-state/body, được gán mặc định SPC-g-r.

Đây là một ảnh chụp màn hình:

nhập mô tả hình ảnh ở đây

Chỉnh sửa tệp của bạn sau đó nên trực quan:

  1. Nhấn nđể đi đến hunk tiếp theo.
  2. Chọn một hành động hợp nhất .
  3. Lặp lại cho đến khi hoàn thành.
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.