Cách giải quyết xung đột hợp nhất trong Git


4769

Làm cách nào để giải quyết xung đột hợp nhất trong Git?


31
Bài đăng trên blog sau đây dường như đưa ra một ví dụ rất hay về cách xử lý xung đột hợp nhất với Git sẽ giúp bạn đi đúng hướng. Xử lý và tránh xung đột trong Git
mwilliams

4
Bạn có thể cấu hình một công cụ hợp nhất (kdiff3 jebaird.com/2013/07/08/ trên ) và sau đó sử dụng git mergetool. Khi bạn làm việc trong các nhóm nhà phát triển lớn, bạn sẽ luôn gặp phải xung đột hợp nhất.
Grady G Cooper

Đừng quên rằng bạn có thể giảm thiểu hầu hết các xung đột hợp nhất bằng cách thường xuyên hợp nhất xuôi dòng!
Ant P


8
Câu hỏi hấp dẫn: Được hỏi vào năm 2008, 100% mở kết thúc mà không có gợi ý nào về những gì nó thực sự nói về (đó là về GUI? Về các lệnh git? Về ngữ nghĩa? Về việc đẩy / kéo hoặc chỉ xung đột chung?) - hoàn toàn không thể trả lời được. 30 câu trả lời, tất cả chúng (chỉ trong nháy mắt cho thấy) ít nhiều diễn ra về các công cụ diff3 và hợp nhất khác nhau, không được chấp nhận. Câu trả lời được bình chọn hàng đầu đề cập đến một lệnh thậm chí không hoạt động ngoài hộp với gitcài đặt mặc định . Quản lý để đạt trang bắt đầu SE cho tôi ngày hôm nay, 2017, với 1,3 triệu lượt xem và hàng ngàn phiếu bầu cả hai chiều. Hấp dẫn.
AnoE

Câu trả lời:


2912

Thử: git mergetool

Nó mở một GUI giúp bạn vượt qua từng xung đột và bạn có thể chọn cách hợp nhất. Đôi khi nó đòi hỏi một chút chỉnh sửa tay sau đó, nhưng thường thì nó là đủ. Nó tốt hơn nhiều so với việc làm toàn bộ bằng tay chắc chắn.

Theo nhận xét @JoshGlover:

Lệnh

không nhất thiết phải mở GUI trừ khi bạn cài đặt. Chạy git mergetoolcho tôi kết quả vimdifflà được sử dụng. Bạn có thể cài đặt một trong các công cụ sau đây để sử dụng nó thay vì: meld, opendiff, kdiff3, tkdiff, xxdiff, tortoisemerge, gvimdiff, diffuse, ecmerge, p4merge, araxis, vimdiff, emerge.

Dưới đây là quy trình mẫu để sử dụng vimdiffđể giải quyết xung đột hợp nhất. Dựa trên liên kết này

Bước 1 : Chạy các lệnh sau trong thiết bị đầu cuối của bạn

git config merge.tool vimdiff
git config merge.conflictstyle diff3
git config mergetool.prompt false

Điều này sẽ đặt vimdiff làm công cụ hợp nhất mặc định.

Bước 2 : Chạy lệnh sau trong terminal

git mergetool

Bước 3 : Bạn sẽ thấy màn hình vimdiff ở định dạng sau

  ╔═══════╦══════╦════════╗
  ║       ║      ║        ║
  ║ LOCAL ║ BASE ║ REMOTE ║
  ║       ║      ║        ║
  ╠═══════╩══════╩════════╣
  ║                       ║
  ║        MERGED         ║
  ║                       ║
  ╚═══════════════════════╝

4 quan điểm này là

ĐỊA PHƯƠNG - đây là tập tin từ chi nhánh hiện tại

BASE - tổ tiên chung, cách tệp nhìn trước cả hai thay đổi

XÓA - tập tin bạn đang hợp nhất vào chi nhánh của bạn

SỨC MẠNH - kết quả hợp nhất, đây là những gì được lưu trong repo

Bạn có thể điều hướng trong số các chế độ xem này bằng ctrl+ w. Bạn có thể trực tiếp đạt đến chế độ xem MERGED bằng cách sử dụng ctrl+ wtheo sau j.

Thông tin thêm về điều hướng vimdiff ở đâyở đây

Bước 4 . Bạn có thể chỉnh sửa chế độ xem NHIỀU theo cách sau

Nếu bạn muốn nhận được các thay đổi từ XÓA

:diffg RE  

Nếu bạn muốn nhận thay đổi từ BASE

:diffg BA  

Nếu bạn muốn nhận thay đổi từ ĐỊA PHƯƠNG

:diffg LO 

Bước 5 . Lưu, thoát, cam kết và dọn dẹp

:wqa lưu và thoát khỏi vi

git commit -m "message"

git clean Xóa các tệp bổ sung (ví dụ * .orig) được tạo bởi công cụ diff.


54
FYI bạn có thể sử dụng git mergetool -yđể lưu một vài tổ hợp phím nếu bạn hợp nhất nhiều tệp cùng một lúc.
davr

373
Chà, nó không nhất thiết phải mở GUI trừ khi bạn cài đặt. Chạy git mergetoolcho tôi kết quả vimdifflà được sử dụng. Bạn có thể cài đặt một trong những công cụ sau để sử dụng thay thế : meld opendiff kdiff3 tkdiff xxdiff tortoisemerge gvimdiff diffuse ecmerge p4merge araxis vimdiff emerge.
Josh Glover

31
Điểm tốt Josh. Trên Ubuntu tôi đã có may mắn nhất với meld, màn hình hợp nhất ba chiều của nó không tệ. Trên OSX git đã chọn một mặc định đẹp.
Peter Burns

18
Điều này đã mở KDiff3. Mà tôi hoàn toàn không có manh mối làm thế nào để sử dụng.
David Murdoch

7
Bạn cũng có thể sử dụng Beyond So sánh 3 ngay bây giờ ( git mergetool -t bc3).
AzP

1703

Đây là trường hợp sử dụng có thể xảy ra, từ đầu:

Bạn sẽ có một số thay đổi, nhưng rất tiếc, bạn không cập nhật:

git fetch origin
git pull origin master

From ssh://gitosis@example.com:22/projectname
 * branch            master     -> FETCH_HEAD
Updating a030c3a..ee25213
error: Entry 'filename.c' not uptodate. Cannot merge.

Vì vậy, bạn cập nhật và thử lại, nhưng có một xung đột:

git add filename.c
git commit -m "made some wild and crazy changes"
git pull origin master

From ssh://gitosis@example.com:22/projectname
 * branch            master     -> FETCH_HEAD
Auto-merging filename.c
CONFLICT (content): Merge conflict in filename.c
Automatic merge failed; fix conflicts and then commit the result.

Vì vậy, bạn quyết định xem xét các thay đổi:

git mergetool

Ôi trời ơi, ngược dòng đã thay đổi một số thứ, nhưng chỉ để sử dụng những thay đổi của tôi ... không ... những thay đổi của họ ...

git checkout --ours filename.c
git checkout --theirs filename.c
git add filename.c
git commit -m "using theirs"

Và sau đó chúng tôi thử một lần cuối cùng

git pull origin master

From ssh://gitosis@example.com:22/projectname
 * branch            master     -> FETCH_HEAD
Already up-to-date.

Ta-da!


19
Điều này rất hữu ích vì tôi có rất nhiều lỗi hợp nhất với các tệp nhị phân (tài sản nghệ thuật) và việc hợp nhất các lỗi đó dường như luôn luôn thất bại, vì vậy tôi cần ghi đè lên nó với tệp mới luôn và không "hợp nhất"
petrocket

188
Cẩn thận! Ý nghĩa của --ours và --theirs bị đảo ngược. --ours == điều khiển từ xa. --theirs == địa phương. Xemgit merge --help
mmell

57
Trong trường hợp của tôi, tôi xác nhận rằng --theirs = kho lưu trữ từ xa, --ours = kho lưu trữ cục bộ của riêng tôi. Nó trái ngược với ý kiến ​​của @mmell.
Aryo

24
@mmell Chỉ trên một rebase, rõ ràng. Xemthis question
Navin

184
Các bạn, "của chúng ta" và "của họ" có liên quan đến việc bạn có hợp nhất hay không. Nếu bạn đang hợp nhất , thì "của chúng tôi" có nghĩa là chi nhánh bạn đang hợp nhất và "của họ" là chi nhánh bạn đang hợp nhất. Khi bạn nổi loạn , thì "của chúng tôi" có nghĩa là các cam kết bạn đang phản đối , trong khi "của họ" đề cập đến các cam kết mà bạn muốn bắt đầu lại.

736

Tôi thấy các công cụ hợp nhất hiếm khi giúp tôi hiểu được xung đột hoặc giải quyết. Tôi thường thành công hơn khi xem các dấu xung đột trong trình soạn thảo văn bản và sử dụng nhật ký git làm phần bổ sung.

Dưới đây là một vài lời khuyên:

Mẹo một

Điều tốt nhất tôi đã tìm thấy là sử dụng kiểu xung đột hợp nhất "diff3":

git config merge.conflictstyle diff3

Điều này tạo ra các dấu hiệu xung đột như thế này:

<<<<<<<
Changes made on the branch that is being merged into. In most cases,
this is the branch that I have currently checked out (i.e. HEAD).
|||||||
The common ancestor version.
=======
Changes made on the branch that is being merged in. This is often a 
feature/topic branch.
>>>>>>>

Phần giữa là những gì tổ tiên chung trông giống như. Điều này rất hữu ích vì bạn có thể so sánh nó với các phiên bản trên cùng và dưới cùng để hiểu rõ hơn về những gì đã thay đổi trên mỗi nhánh, điều này cho bạn ý tưởng tốt hơn về mục đích của mỗi thay đổi là gì.

Nếu xung đột chỉ là một vài dòng, điều này thường làm cho xung đột rất rõ ràng. (Biết cách khắc phục xung đột rất khác nhau; bạn cần lưu ý về những gì người khác đang làm. Nếu bạn bối rối, có lẽ tốt nhất là gọi người đó vào phòng của bạn để họ có thể thấy bạn đang nhìn gì tại.)

Nếu xung đột kéo dài hơn, thì tôi sẽ cắt và dán từng phần trong ba phần thành ba tệp riêng biệt, chẳng hạn như "của tôi", "chung" và "của họ".

Sau đó, tôi có thể chạy các lệnh sau để xem hai khối khác nhau gây ra xung đột:

diff common mine
diff common theirs

Điều này không giống như sử dụng một công cụ hợp nhất, vì một công cụ hợp nhất sẽ bao gồm tất cả các khối khác nhau không xung đột. Tôi thấy rằng để được phân tâm.

Mẹo hai

Ai đó đã đề cập đến vấn đề này, nhưng hiểu được ý định đằng sau mỗi hunk diff thường rất hữu ích để hiểu được xung đột đến từ đâu và cách xử lý nó.

git log --merge -p <name of file>

Điều này cho thấy tất cả các cam kết đã chạm vào tệp đó ở giữa tổ tiên chung và hai đầu bạn đang hợp nhất. (Vì vậy, nó không bao gồm các cam kết đã tồn tại trong cả hai nhánh trước khi hợp nhất.) Điều này giúp bạn bỏ qua các khối khác biệt rõ ràng không phải là một yếu tố trong xung đột hiện tại của bạn.

Mẹo ba

Xác nhận thay đổi của bạn với các công cụ tự động.

Nếu bạn có các bài kiểm tra tự động, hãy chạy chúng. Nếu bạn có một lint , chạy nó. Nếu đó là một dự án có thể xây dựng, thì hãy xây dựng nó trước khi bạn cam kết, v.v. Trong mọi trường hợp, bạn cần thực hiện một chút thử nghiệm để đảm bảo các thay đổi của bạn không phá vỡ bất cứ điều gì. (Heck, ngay cả một sự hợp nhất mà không có xung đột có thể phá vỡ mã làm việc.)

Mẹo bốn

Lên kế hoạch trước; giao tiếp với đồng nghiệp.

Lập kế hoạch trước và nhận thức được những gì người khác đang làm việc có thể giúp ngăn ngừa xung đột hợp nhất và / hoặc giúp giải quyết chúng sớm hơn - trong khi các chi tiết vẫn còn mới mẻ.

Ví dụ: nếu bạn biết rằng bạn và một người khác đều đang thực hiện các phép tái cấu trúc khác nhau, cả hai sẽ ảnh hưởng đến cùng một tập tin, bạn nên nói chuyện với nhau trước và hiểu rõ hơn về loại thay đổi của mỗi bạn chế tạo. Bạn có thể tiết kiệm đáng kể thời gian và công sức nếu bạn tiến hành thay đổi theo kế hoạch một cách thanh thản hơn là song song.

Đối với các phép tái cấu trúc chính cắt ngang một dải mã lớn, bạn nên cân nhắc việc làm việc một cách nghiêm túc: mọi người ngừng làm việc trên khu vực đó của mã trong khi một người thực hiện tái cấu trúc hoàn chỉnh.

Nếu bạn không thể làm việc bình thường (do áp lực thời gian, có thể), thì việc truyền đạt về xung đột hợp nhất dự kiến ​​ít nhất sẽ giúp bạn giải quyết vấn đề sớm hơn trong khi các chi tiết vẫn còn mới mẻ. Ví dụ: nếu đồng nghiệp đang thực hiện một loạt các cam kết đột phá trong khoảng thời gian một tuần, bạn có thể chọn hợp nhất / rebase trên chi nhánh đồng nghiệp đó một hoặc hai lần mỗi ngày trong tuần đó. Bằng cách đó, nếu bạn tìm thấy xung đột hợp nhất / rebase, bạn có thể giải quyết chúng nhanh hơn nếu bạn chờ vài tuần để hợp nhất mọi thứ lại với nhau trong một lần lớn.

Mẹo năm

Nếu bạn không chắc chắn về việc hợp nhất, đừng ép buộc.

Sáp nhập có thể cảm thấy quá sức, đặc biệt là khi có rất nhiều tệp xung đột và các dấu xung đột bao gồm hàng trăm dòng. Thông thường, khi ước tính các dự án phần mềm, chúng tôi không bao gồm đủ thời gian cho các mục trên cao như xử lý hợp nhất sởn gai ốc, do đó, cảm giác giống như một lực cản thực sự để dành vài giờ để mổ xẻ mỗi xung đột.

Về lâu dài, lập kế hoạch trước và nhận thức được những gì người khác đang làm là những công cụ tốt nhất để dự đoán xung đột hợp nhất và chuẩn bị cho mình để giải quyết chúng một cách chính xác trong thời gian ngắn hơn.


6
Tùy chọn diff3 là một tính năng tuyệt vời để có với sự hợp nhất. GUI duy nhất tôi gặp phải cho thấy nó là Perforce p4merge, có thể được cài đặt và sử dụng riêng biệt với các công cụ khác của Perforce (mà tôi chưa sử dụng, nhưng nghe thấy khiếu nại về).
alxndr

3
Sau một nỗ lực rebase dẫn đến xung đột hợp nhất: $ git log --merge -p build.xml output: fatal: --merge without MERGE_HEAD?
Ed Randall

Điều gì xảy ra nếu tôi có thay đổi trên một tệp từ nhánh1 và xóa tệp đó trong nhánh2. Làm thế nào tôi có thể giải quyết xung đột hợp nhất đó? Có cách nào sử dụng git mà tôi có thể hợp nhất chúng bằng cách giữ các thay đổi của một nhánh không?
Mật ong

git config merge.conflictstyle diff3- cảm ơn ngài. Điều này thật tuyệt vời và đã giải phóng tôi khỏi việc cố gắng tìm (và trả $$) cho GUI hợp nhất 3 chiều. IMO điều này tốt hơn bởi vì nó hiển thị tổ tiên chung cũng như cục bộ / từ xa hiển thị các dòng nhật ký cam kết cuối cùng mà (AFAIK) không có GUI nào thực hiện. Các cam kết chắc chắn giúp bạn xác định mã nào thuộc về nhánh nào.
ffxsam

Tôi đã phát hiện ra rằng đôi khi kiểu xung đột diff3 tạo ra các khối khác nhau rất lớn giống hệt nhau, trong khi mặc định sẽ tạo ra các khối lớn hơn, dễ quản lý hơn. Thật không may, tôi không có trình sao chép mà tôi có thể sử dụng cho báo cáo lỗi. Nhưng nếu bạn gặp phải vấn đề này, bạn có thể cân nhắc tắt tùy chọn tạm thời.
Dave Abrahams

348
  1. Xác định các tệp đang xung đột (Git sẽ cho bạn biết điều này).

  2. Mở từng tệp và kiểm tra các khác biệt; Git phân định chúng. Hy vọng nó sẽ rõ ràng phiên bản của mỗi khối để giữ. Bạn có thể cần thảo luận với các nhà phát triển đồng nghiệp đã cam kết mã.

  3. Khi bạn đã giải quyết xung đột trong một tệp git add the_file.

  4. Khi bạn đã giải quyết tất cả các xung đột, hãy thực hiện git rebase --continuehoặc bất kỳ lệnh nào mà Git đã nói sẽ làm khi bạn hoàn thành.


38
@Justin Hãy nghĩ về Git như theo dõi nội dung thay vì theo dõi tệp. Sau đó, thật dễ dàng để thấy rằng nội dung bạn đã cập nhật không có trong kho lưu trữ và cần được thêm vào. Cách suy nghĩ này cũng giải thích tại sao Git không theo dõi các thư mục trống: Mặc dù chúng là các tệp kỹ thuật, không có bất kỳ nội dung nào cần theo dõi.
Gareth

7
Nội dung ở đó, xung đột xảy ra vì có 2 phiên bản nội dung. Do đó "git add" không đúng. Và nó không làm việc (git add, git commit) nếu bạn muốn cam kết duy nhất mà một tập tin sau khi xung đột đã được giải quyết: ( "chết người không thể làm cam kết một phần trong một cuộc hợp nhất.")
Dainius

1
Vâng, về mặt kỹ thuật, điều này trả lời câu hỏi như đã hỏi, nhưng theo tôi, xin lỗi. Là gì điểm của việc một chi nhánh giống như khác? Tất nhiên một sự hợp nhất sẽ có xung đột ..
Thufir

5
Thulfir: ai nói bất cứ điều gì về việc làm cho một chi nhánh giống như một chi nhánh khác? Có nhiều kịch bản khác nhau mà bạn cần hợp nhất, mà không "tạo một nhánh giống như một nhánh khác". Một là khi bạn hoàn thành một nhánh phát triển và muốn kết hợp các thay đổi của nó vào nhánh chính; sau đó, nhánh phát triển có thể bị xóa. Một cách khác là khi bạn muốn khởi động lại nhánh phát triển của mình, để dễ dàng hợp nhất cuối cùng vào chủ.
Teemu Leisti

4
@JustinGrant git addgiai đoạn tập tin trong chỉ mục; nó không thêm bất cứ thứ gì vào kho lưu trữ. git committhêm những thứ vào kho lưu trữ. Việc sử dụng này có ý nghĩa đối với việc hợp nhất - việc hợp nhất sẽ tự động thực hiện tất cả các thay đổi có thể được hợp nhất tự động; bạn có trách nhiệm hợp nhất phần còn lại của các thay đổi và thêm những thay đổi đó vào chỉ mục khi bạn hoàn thành.
Đánh dấu E. Haase

105

Kiểm tra các câu trả lời trong câu hỏi Stack Overflow Hủy bỏ hợp nhất trong Git , đặc biệt là câu trả lời của Charles Bailey trong đó cho thấy cách xem các phiên bản khác nhau của tệp có vấn đề, ví dụ:

# Common base version of the file.
git show :1:some_file.cpp

# 'Ours' version of the file.
git show :2:some_file.cpp

# 'Theirs' version of the file.
git show :3:some_file.cpp

Ngoài ra, hãy kiểm tra tùy chọn "-m" thành "git checkout -m" - nó cho phép bạn trích xuất các con ruồi khác nhau trở lại không gian làm việc của bạn
qneill

Điều này đã cứu tôi. Nhìn vào từng tệp riêng biệt cho phép tôi nhớ những gì tôi sẽ làm trong mỗi chi nhánh. Sau đó tôi có thể đưa ra quyết định lựa chọn.
Rohmer

99

Hợp nhất xung đột xảy ra khi thay đổi được thực hiện cho một tệp cùng một lúc. Đây là cách giải quyết nó.

git CLI

Dưới đây là các bước đơn giản phải làm gì khi bạn rơi vào trạng thái xung đột:

  1. Lưu ý danh sách các tệp bị xung đột với: git status(trong Unmerged pathsphần).
  2. Giải quyết các xung đột riêng cho từng tệp bằng một trong các cách tiếp cận sau:

    • Sử dụng GUI để giải quyết các xung đột: git mergetool(cách dễ nhất).

    • Để chấp nhận từ xa / phiên bản khác, sử dụng : git checkout --theirs path/file. Điều này sẽ từ chối mọi thay đổi cục bộ bạn đã làm cho tệp đó.

    • Để chấp nhận phiên bản cục bộ / của chúng tôi, hãy sử dụng: git checkout --ours path/file

      Tuy nhiên, bạn phải cẩn thận, vì những thay đổi từ xa mà xung đột đã được thực hiện vì một số lý do.

      Liên quan: Ý nghĩa chính xác của "chúng ta" và "của họ" trong git là gì?

    • Chỉnh sửa các tệp bị xung đột theo cách thủ công và tìm khối mã giữa <<<<</ >>>>>sau đó chọn phiên bản từ bên trên hoặc bên dưới =====. Xem: Làm thế nào xung đột được trình bày .

    • Xung đột đường dẫn và tên tệp có thể được giải quyết bằng git add/ git rm.

  3. Cuối cùng, xem lại các tệp đã sẵn sàng để cam kết sử dụng : git status.

    Nếu bạn vẫn còn bất kỳ tệp nào bên dưới Unmerged pathsvà bạn đã giải quyết xung đột theo cách thủ công, thì hãy cho Git biết rằng bạn đã giải quyết nó bằng cách : git add path/file.

  4. Nếu tất cả các xung đột đã được giải quyết thành công, hãy thực hiện các thay đổi bằng cách: git commit -avà đẩy sang điều khiển từ xa như bình thường.

Xem thêm: Giải quyết xung đột hợp nhất từ ​​dòng lệnh tại GitHub

Để có hướng dẫn thực tế, hãy kiểm tra: Kịch bản 5 - Khắc phục xung đột hợp nhất của Katacoda .

DiffMerge

Tôi đã sử dụng thành công DiffMerge có thể so sánh và hợp nhất các tệp trên Windows, macOS và Linux / Unix một cách trực quan.

Nó đồ họa có thể hiển thị các thay đổi giữa 3 tệp và cho phép tự động hợp nhất (khi an toàn để làm như vậy) và toàn quyền kiểm soát chỉnh sửa tệp kết quả.

DiffMerge

Nguồn hình ảnh: DiffMerge (ảnh chụp màn hình Linux)

Đơn giản chỉ cần tải xuống và chạy trong repo như:

git mergetool -t diffmerge .

hệ điều hành Mac

Trên macOS, bạn có thể cài đặt qua:

brew install caskroom/cask/brew-cask
brew cask install diffmerge

Và có lẽ (nếu không được cung cấp), bạn cần trình bao bọc đơn giản bổ sung sau được đặt trong PATH của bạn (ví dụ /usr/bin):

#!/bin/sh
DIFFMERGE_PATH=/Applications/DiffMerge.app
DIFFMERGE_EXE=${DIFFMERGE_PATH}/Contents/MacOS/DiffMerge
exec ${DIFFMERGE_EXE} --nosplash "$@"

Sau đó, bạn có thể sử dụng các phím tắt sau:

  • - Alt- Up/ Downđể chuyển sang các thay đổi trước đó / tiếp theo.
  • - Alt- Left/ Rightđể chấp nhận thay đổi từ trái hoặc phải

Ngoài ra, bạn có thể sử dụng opendiff (một phần của Công cụ Xcode) cho phép bạn hợp nhất hai tệp hoặc thư mục lại với nhau để tạo tệp hoặc thư mục thứ ba.


79

Nếu bạn đang thực hiện các cam kết nhỏ thường xuyên, thì hãy bắt đầu bằng cách xem các nhận xét cam kết với git log --merge. Sau đó git diffsẽ cho bạn thấy những xung đột.

Đối với các xung đột liên quan đến nhiều hơn một vài dòng, sẽ dễ dàng hơn để xem những gì đang diễn ra trong một công cụ GUI bên ngoài. Tôi thích opendiff - Git cũng hỗ trợ vimdiff, gvimdiff, kdiff3, tkdiff, meld, xxdiff, xuất hiện trong hộp và bạn có thể cài git config merge.tool "your.tool"đặt các công cụ khác: sẽ đặt công cụ đã chọn của bạn và sau đó git mergetoolkết hợp thất bại sẽ hiển thị cho bạn các khác biệt trong bối cảnh.

Mỗi lần bạn chỉnh sửa một tệp để giải quyết xung đột, git add filenamesẽ cập nhật chỉ mục và diff của bạn sẽ không hiển thị nữa. Khi tất cả các xung đột được xử lý và các tệp của chúng đã được xử lý git add, git commitsẽ hoàn tất việc hợp nhất của bạn.


8
Sử dụng "git add" là mẹo thực sự ở đây. Bạn thậm chí có thể không muốn cam kết (có thể bạn muốn stash), nhưng bạn phải thực hiện "git add" để hoàn thành việc hợp nhất. Tôi nghĩ mergetool sẽ bổ sung cho bạn (mặc dù nó không có trong manpage), nhưng nếu bạn thực hiện hợp nhất thủ công, bạn cần sử dụng "git add" để hoàn thành nó (ngay cả khi bạn không muốn cam kết).
tộc

47

Xem cách Xung đột được trình bày hoặc, trong Git, git mergetài liệu để hiểu các dấu hiệu xung đột hợp nhất là gì.

Ngoài ra, phần Cách giải quyết xung đột giải thích cách giải quyết xung đột:

Sau khi thấy một cuộc xung đột, bạn có thể làm hai điều:

  • Quyết định không hợp nhất. Việc dọn dẹp duy nhất bạn cần là đặt lại tệp chỉ mục thành HEADcam kết để đảo ngược 2. và dọn sạch các thay đổi của cây làm việc được thực hiện bởi 2. và 3.; git merge --abortcó thể được sử dụng cho việc này.

  • Giải quyết các xung đột. Git sẽ đánh dấu các xung đột trong cây làm việc. Chỉnh sửa các tập tin thành hình và git addchúng vào chỉ mục. Sử dụng git commitđể niêm phong thỏa thuận.

Bạn có thể làm việc thông qua xung đột với một số công cụ:

  • Sử dụng một mergetool. git mergetoolđể khởi chạy một công cụ hợp nhất đồ họa sẽ giúp bạn hoàn thành việc hợp nhất.

  • Nhìn vào khác biệt. git diffsẽ hiển thị một diff ba chiều, làm nổi bật những thay đổi từ cả HEADMERGE_HEADcác phiên bản.

  • Nhìn vào sự khác biệt từ mỗi chi nhánh. git log --merge -p <path>sẽ hiển thị khác trước cho HEADphiên bản và sau đó là MERGE_HEADphiên bản.

  • Nhìn vào bản gốc. git show :1:filenamehiển thị tổ tiên chung, git show :2:filenamehiển thị HEADphiên bản và git show :3:filenamehiển thị MERGE_HEADphiên bản.

Bạn cũng có thể đọc về các dấu xung đột hợp nhất và cách giải quyết chúng trong phần sách Pro Git Xung đột hợp nhất cơ bản .


42

Tôi muốn phiên bản của tôi hoặc của họ đầy đủ hoặc muốn xem xét các thay đổi riêng lẻ và quyết định cho từng thay đổi.

Chấp nhận hoàn toàn phiên bản của tôi hoặc của họ :

Chấp nhận phiên bản của tôi (địa phương, của chúng tôi):

git checkout --ours -- <filename>
git add <filename>              # Marks conflict as resolved
git commit -m "merged bla bla"  # An "empty" commit

Chấp nhận phiên bản của họ (từ xa, của họ):

git checkout --theirs -- <filename>
git add <filename>
git commit -m "merged bla bla"

Nếu bạn muốn làm cho tất cả các tệp xung đột chạy:

git merge --strategy-option ours

hoặc là

git merge --strategy-option theirs

Xem lại tất cả các thay đổi và chấp nhận chúng riêng lẻ

  1. git mergetool
  2. Xem lại các thay đổi và chấp nhận một trong hai phiên bản cho mỗi trong số chúng.
  3. git add <filename>
  4. git commit -m "merged bla bla"

Mặc định mergetoolhoạt động trong dòng lệnh . Làm thế nào để sử dụng một sáp nhập dòng lệnh nên là một câu hỏi riêng biệt.

Bạn cũng có thể cài đặt công cụ trực quan cho việc này, ví dụ meldvà chạy

git mergetool -t meld

Nó sẽ mở phiên bản cục bộ (của chúng tôi), phiên bản "cơ sở" hoặc "hợp nhất" (kết quả hiện tại của việc hợp nhất) và phiên bản từ xa (của họ). Lưu phiên bản đã hợp nhất khi bạn kết thúc, chạy git mergetool -t meldlại cho đến khi bạn nhận được "Không cần tập tin hợp nhất", sau đó chuyển đến Bước 3. và 4.


Lệnh này: git checkout --theirs - <filename> đã thay đổi TẤT CẢ các tệp thành tệp của họ, không chỉ <tên tệp>
Donato

Thật ra tôi đã sai. Điều này chỉ cập nhật tập tin được chỉ định.
Donato

40

Đối với người dùng Emacs muốn giải quyết xung đột hợp nhất một cách thủ công:

git diff --name-status --diff-filter=U

hiển thị tất cả các tệp yêu cầu giải quyết xung đột.

Mở từng tệp một, hoặc tất cả cùng một lúc bằng cách:

emacs $(git diff --name-only --diff-filter=U)

Khi truy cập bộ đệm yêu cầu chỉnh sửa trong Emacs, hãy nhập

ALT+x vc-resolve-conflicts

Điều này sẽ mở ba bộ đệm (của tôi, của họ và bộ đệm đầu ra). Điều hướng bằng cách nhấn 'n' (khu vực tiếp theo), 'p' (khu vực thịnh hành). Nhấn 'a' và 'b' để sao chép vùng của tôi hoặc vùng của chúng vào bộ đệm đầu ra, tương ứng. Và / hoặc chỉnh sửa bộ đệm đầu ra trực tiếp.

Khi kết thúc: Nhấn 'q'. Emacs hỏi bạn nếu bạn muốn lưu bộ đệm này: có. Sau khi hoàn thành đánh dấu bộ đệm, nó được giải quyết bằng cách chạy từ teriminal:

git add FILENAME

Khi kết thúc với tất cả các loại bộ đệm

git commit

để kết thúc hợp nhất.


33

Tặng kem:

Khi nói về pull / fetch / merge trong các câu trả lời trên, tôi muốn chia sẻ một mẹo thú vị và hiệu quả,

git pull --rebase

Lệnh trên là lệnh hữu ích nhất trong cuộc sống git của tôi giúp tiết kiệm rất nhiều thời gian.

Trước khi đẩy sự thay đổi mới cam kết của bạn đến máy chủ từ xa, hãy thử git pull --rebasethay git pullvà bằng tay mergevà nó sẽ tự động đồng bộ hóa mới nhất thay đổi máy chủ từ xa (với lấy + merge) và sẽ đưa địa phương cam kết mới nhất ở trên cùng trong git log. Không cần phải lo lắng về việc kéo / hợp nhất thủ công.

Trong trường hợp có xung đột, chỉ cần sử dụng

git mergetool
git add conflict_file
git rebase --continue

Tìm thông tin chi tiết tại: http://gitolite.com/git-pull--rebase


32

Đơn giản, nếu bạn biết rõ rằng những thay đổi trong một trong các kho lưu trữ là không quan trọng và muốn giải quyết tất cả các thay đổi có lợi cho cái khác, hãy sử dụng:

git checkout . --ours

để giải quyết các thay đổi có lợi cho kho lưu trữ của bạn , hoặc

git checkout . --theirs

để giải quyết các thay đổi có lợi cho kho khác hoặc kho lưu trữ chính .

Hoặc nếu không, bạn sẽ phải sử dụng công cụ hợp nhất GUI để lần lượt từng tệp một, giả sử công cụ hợp nhất là p4mergehoặc viết bất kỳ tên nào bạn đã cài đặt

git mergetool -t p4merge

và sau khi hoàn thành một tệp, bạn sẽ phải lưu và đóng, vì vậy tệp tiếp theo sẽ mở.


2
kiểm tra git. - những người đã giải quyết vấn đề của tôi nhờ
Ramesh Chand

nếu bạn muốn giải quyết xung đột theo cách thủ công, hãy thử mở thư mục trong Visual Studio Code, nó đánh dấu các tệp có xung đột và màu sắc xung đột bên trong mỗi người
Mohamed Selim

31

Vui lòng làm theo các bước sau để khắc phục xung đột hợp nhất trong Git:

  1. Kiểm tra trạng thái Git: trạng thái git

  2. Nhận bản vá : git fetch (kiểm tra bản vá đúng từ cam kết Git của bạn)

  3. Kiểm tra một chi nhánh địa phương (temp1 trong ví dụ của tôi ở đây): git checkout -b temp1

  4. Kéo các nội dung gần đây từ master: git pull --rebase origin master

  5. Bắt đầu mergetool và kiểm tra các xung đột và khắc phục chúng ... và kiểm tra các thay đổi trong nhánh từ xa với nhánh hiện tại của bạn: git mergetool

  6. Kiểm tra lại trạng thái: trạng thái git

  7. Xóa các tệp không mong muốn được tạo cục bộ bởi mergetool, thông thường mergetool tạo tệp bổ sung có phần mở rộng * .orig. Vui lòng xóa tệp đó vì đó chỉ là bản sao và sửa các thay đổi cục bộ và thêm phiên bản chính xác của tệp của bạn. git thêm #your_changed_c chính_files

  8. Kiểm tra lại trạng thái: trạng thái git

  9. Cam kết các thay đổi đối với cùng một id xác nhận (điều này tránh một bộ bản vá riêng biệt mới): git commit --amend

  10. Đẩy đến nhánh chính: git đẩy (vào kho Git của bạn)


28

Có 3 bước:

  1. Tìm tập tin nào gây ra xung đột bằng lệnh

    git status
    
  2. Kiểm tra các tệp, trong đó bạn sẽ tìm thấy các xung đột được đánh dấu như

    <<<<<<<<head
    blablabla
    
  3. Thay đổi nó theo cách bạn muốn, sau đó cam kết bằng các lệnh

    git add solved_conflicts_files
    git commit -m 'merge msg'
    

Đã làm cho tôi! Cảm ơn!
Nuwan Jayawardene

Bạn phải chú ý nếu làm điều này trong rebase. Bạn nên sử dụng git rebase - liên tục thay vì git commit
Samuel Dauzon

27

Bạn có thể sửa các xung đột hợp nhất theo một số cách như những cách khác đã nêu chi tiết.

Tôi nghĩ rằng chìa khóa thực sự là biết cách thay đổi chảy với các kho lưu trữ cục bộ và từ xa. Chìa khóa cho việc này là sự hiểu biết theo dõi các chi nhánh. Tôi đã thấy rằng tôi nghĩ về nhánh theo dõi là "phần bị thiếu ở giữa" giữa thư mục tệp thực tế, cục bộ của tôi và từ xa được xác định là gốc.

Cá nhân tôi đã có thói quen 2 điều để giúp tránh điều này.

Thay vì:

git add .
git commit -m"some msg"

Trong đó có hai nhược điểm -

a) Tất cả các tệp mới / thay đổi được thêm vào và có thể bao gồm một số thay đổi không mong muốn.
b) Bạn không được xem lại danh sách tập tin trước.

Vì vậy, thay vì tôi làm:

git add file,file2,file3...
git commit # Then type the files in the editor and save-quit.

Bằng cách này, bạn sẽ cân nhắc nhiều hơn về những tập tin nào được thêm vào và bạn cũng có thể xem lại danh sách và suy nghĩ thêm một chút trong khi sử dụng trình chỉnh sửa cho tin nhắn. Tôi thấy nó cũng cải thiện các thông điệp cam kết của tôi khi tôi sử dụng trình chỉnh sửa toàn màn hình thay vì -mtùy chọn.

[Cập nhật - khi thời gian trôi qua tôi đã chuyển nhiều hơn sang:

git status # Make sure I know whats going on
git add .
git commit # Then use the editor

]

Ngoài ra (và phù hợp hơn với tình huống của bạn), tôi cố gắng tránh:

git pull

hoặc là

git pull origin master.

bởi vì pull ngụ ý hợp nhất và nếu bạn có các thay đổi cục bộ mà bạn không muốn hợp nhất, bạn có thể dễ dàng kết thúc với mã được hợp nhất và / hoặc xung đột hợp nhất cho mã không nên được hợp nhất.

Thay vào đó tôi cố gắng làm

git checkout master
git fetch   
git rebase --hard origin/master # or whatever branch I want.

Bạn cũng có thể thấy điều này hữu ích:

chi nhánh git, ngã ba, tìm nạp, hợp nhất, rebase và clone, sự khác biệt là gì?


Này, tôi khá hiểu câu trả lời của bạn. Nhưng vì tôi chưa quen với các xung đột hợp nhất của github, tôi nghĩ rằng còn thiếu một cái gì đó. Điều gì xảy ra thay đổi địa phương của bạn khi bạn làm git checkout mastergit fetchgit rebase --hard origin/master
Suhaib

Tôi tin rằng bạn nên thêm chi tiết về những gì cần làm. Một ví dụ khác làm tôi bối rối, bạn đã đề cập trong câu trả lời của bạn: chúng tôi làm git add ., liệu nó có lưu các sửa đổi cục bộ của chúng tôi để chúng tôi có thể theo dõi git checkout masterkhông? hoặc là hai kịch bản khác nhau?
Suhaib

@MichaelDurrant $ git rebase --hard origin/master b5a30cc159ba8dd error: unknown option hard 'cách sử dụng: git rebase [-i] [tùy chọn] [--exec <cmd>] [--onto <newbase>] [<ngược dòng>] [<chi nhánh>] hoặc: git rebase [-i] [ tùy chọn] [--exec <cmd>] [--onto <newbase>] --root [<chi nhánh>] hoặc: git rebase --continue | - --skip | --edit-todo `
likejudo

24

Câu trả lời của CoolAJ86 tổng hợp khá nhiều thứ. Trong trường hợp bạn có các thay đổi trong cả hai nhánh trong cùng một đoạn mã, bạn sẽ phải thực hiện hợp nhất thủ công. Mở tệp trong xung đột trong bất kỳ trình soạn thảo văn bản nào và bạn sẽ thấy cấu trúc sau.

(Code not in Conflict)
>>>>>>>>>>>
(first alternative for conflict starts here)
Multiple code lines here
===========
(second alternative for conflict starts here)
Multiple code lines here too    
<<<<<<<<<<<
(Code not in conflict here)

Chọn một trong các lựa chọn thay thế hoặc kết hợp cả hai theo cách bạn muốn mã mới, trong khi loại bỏ các dấu bằng và dấu ngoặc góc bằng nhau.

git commit -a -m "commit message"
git push origin master

17
git log --merge -p [[--] path]

Dường như không phải lúc nào cũng làm việc cho tôi và thường kết thúc hiển thị mọi cam kết khác nhau giữa hai nhánh, điều này xảy ra ngay cả khi sử dụng --để tách đường dẫn khỏi lệnh.

Những gì tôi làm để giải quyết vấn đề này là mở ra hai dòng lệnh và trong một lần chạy

git log ..$MERGED_IN_BRANCH --pretty=full -p [path]

và trong cái khác

git log $MERGED_IN_BRANCH.. --pretty=full -p [path]

Thay thế $MERGED_IN_BRANCHbằng nhánh tôi đã hợp nhất và [path]với tệp bị xung đột. Lệnh này sẽ ghi lại tất cả các xác nhận, ở dạng bản vá, giữa ( ..) hai lần xác nhận. Nếu bạn để trống một bên như trong các lệnh trên, git sẽ tự động sử dụng HEAD(nhánh bạn đang hợp nhất trong trường hợp này).

Điều này sẽ cho phép bạn xem những gì cam kết đã đi vào tệp trong hai nhánh sau khi chúng chuyển hướng. Nó thường làm cho nó dễ dàng hơn nhiều để giải quyết xung đột.


16

Sử dụng patience

Tôi ngạc nhiên không ai khác nói về việc giải quyết xung đột bằng patiencechiến lược đệ quy hợp nhất. Đối với một cuộc xung đột hợp nhất lớn, sử dụng patiencecung cấp kết quả tốt cho tôi. Ý tưởng là nó sẽ cố gắng khớp các khối chứ không phải các dòng riêng lẻ.

Ví dụ, nếu bạn thay đổi thụt lề của chương trình, chiến lược hợp nhất Git mặc định đôi khi khớp với các dấu ngoặc đơn {thuộc các chức năng khác nhau. Điều này được tránh với patience:

git merge -s recursive -X patience other-branch

Từ tài liệu:

With this option, merge-recursive spends a little extra time to avoid 
mismerges that sometimes occur due to unimportant matching lines 
(e.g., braces from distinct functions). Use this when the branches to 
be merged have diverged wildly.

So sánh với tổ tiên chung

Nếu bạn có xung đột hợp nhất và muốn xem những gì người khác nghĩ đến khi sửa đổi chi nhánh của họ, đôi khi việc so sánh trực tiếp chi nhánh của họ với tổ tiên chung (thay vì chi nhánh của chúng tôi) sẽ dễ dàng hơn. Cho rằng bạn có thể sử dụng merge-base:

git diff $(git merge-base <our-branch> <their-branch>) <their-branch>

Thông thường, bạn chỉ muốn xem các thay đổi cho một tệp cụ thể:

git diff $(git merge-base <our-branch> <their-branch>) <their-branch> <file>

Trong trường hợp của tôi, điều này không giải quyết tốt các xung đột hợp nhất, vì một số lý do, nó giữ các dòng cấu hình trùng lặp trong các dự án C #. Mặc dù nó thân thiện hơn ENTIRE FILE LÀ KHÁC BIỆT, mà tôi đã có trước đây
Mathijs Segers

15

Kể từ ngày 12 tháng 12 năm 2016, bạn có thể hợp nhất các chi nhánh và giải quyết xung đột trên github.com

Do đó, nếu bạn không muốn sử dụng dòng lệnh hoặc bất kỳ công cụ của bên thứ 3 nào được cung cấp ở đây từ các câu trả lời cũ hơn , hãy sử dụng công cụ gốc của GitHub.

Bài đăng trên blog này giải thích chi tiết, nhưng điều cơ bản là khi 'hợp nhất' hai chi nhánh thông qua giao diện người dùng, giờ đây bạn sẽ thấy tùy chọn 'giải quyết xung đột' sẽ đưa bạn đến một trình soạn thảo cho phép bạn xử lý các xung đột hợp nhất này.

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


Đây không phải là hỏi về github do đó tôi đã bỏ phiếu những gì tôi xem là một câu trả lời rất kém.
mschuett

1
@mschuett đã đúng, câu hỏi là "cách giải quyết xung đột trong git", chứ không phải "cách giải quyết xung đột trong github". Có một sự khác biệt và đã có quá nhiều người nghĩ rằng git và github là cùng một thứ, vì vậy bất cứ điều gì truyền bá cảm giác đó là sai.
Patrick Mevzek

15

Nếu bạn muốn hợp nhất từ ​​nhánh (kiểm tra) thành chủ, bạn có thể làm theo các bước sau:

Bước 1 : Đi đến chi nhánh

git checkout test

Bước 2 :

git pull --rebase origin master

Bước 3 : Nếu có một số xung đột, hãy đến các tệp này để sửa đổi nó.

Bước 4 : Thêm những thay đổi này

git add #your_changes_files

Bước 5 :

git rebase --continue

Bước 6 : Nếu vẫn còn xung đột, quay lại bước 3 một lần nữa. Nếu không có xung đột, hãy làm như sau:

git push origin +test

Bước 7 : Và sau đó không có xung đột giữa kiểm tra và chủ. Bạn có thể sử dụng hợp nhất trực tiếp.


13

Tôi luôn làm theo các bước dưới đây để tránh xung đột.

  • git checkout master (Đến chi nhánh chính)
  • git pull (Cập nhật chủ của bạn để lấy mã mới nhất)
  • git checkout -b mybranch (Thanh toán một chi nhánh mới và bắt đầu làm việc trên chi nhánh đó để chủ của bạn luôn luôn đứng đầu thân cây.)
  • git thêm. VÀ git cam kết VÀ git đẩy (trên chi nhánh địa phương của bạn sau khi thay đổi của bạn)
  • git checkout master (Quay lại với chủ của bạn.)

Bây giờ bạn có thể làm tương tự và duy trì bao nhiêu chi nhánh địa phương bạn muốn và làm việc đồng thời tôi chỉ cần thực hiện kiểm tra git cho chi nhánh của bạn khi cần thiết.


12

Hợp nhất xung đột có thể xảy ra trong các tình huống khác nhau:

  • Khi chạy "git fetch" và sau đó "git merge"
  • Khi chạy "git fetch" và sau đó "git rebase"
  • Khi chạy "git pull" (thực tế bằng với một trong các điều kiện nêu trên)
  • Khi chạy "git stash pop"
  • Khi bạn đang áp dụng các bản vá git (ví dụ như các cam kết được xuất sang các tệp sẽ được chuyển qua email)

Bạn cần cài đặt một công cụ hợp nhất tương thích với Git để giải quyết các xung đột. Cá nhân tôi sử dụng KDiff3 và tôi thấy nó rất hay và tiện dụng. Bạn có thể tải xuống phiên bản Windows của nó tại đây:

https://sourceforge.net/projects/kdiff3/files/

BTW nếu bạn cài đặt Tiện ích mở rộng Git, có một tùy chọn trong trình hướng dẫn thiết lập để cài đặt Kdiff3.

Sau đó thiết lập cấu hình git để sử dụng Kdiff làm mergetool của nó:

$ git config --global --add merge.tool kdiff3
$ git config --global --add mergetool.kdiff3.path "C:/Program Files/KDiff3/kdiff3.exe"
$ git config --global --add mergetool.kdiff3.trustExitCode false

$ git config --global --add diff.guitool kdiff3
$ git config --global --add difftool.kdiff3.path "C:/Program Files/KDiff3/kdiff3.exe"
$ git config --global --add difftool.kdiff3.trustExitCode false

(Hãy nhớ thay thế đường dẫn bằng đường dẫn thực tế của tệp exe Kdiff.)

Sau đó, mỗi khi bạn gặp một xung đột hợp nhất, bạn chỉ cần chạy lệnh này:

$git mergetool

Sau đó, nó sẽ mở Kdiff3 và đầu tiên cố gắng tự động giải quyết xung đột hợp nhất. Hầu hết các xung đột sẽ được giải quyết một cách tự nhiên và bạn cần khắc phục phần còn lại bằng tay.

Đây là những gì Kdiff3 trông giống như:

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

Sau đó, khi bạn đã hoàn tất, hãy lưu tệp và nó chuyển sang tệp tiếp theo có xung đột và bạn làm lại điều tương tự cho đến khi tất cả các xung đột được giải quyết.

Để kiểm tra xem mọi thứ có được hợp nhất thành công hay không, chỉ cần chạy lại lệnh mergetool, bạn sẽ nhận được kết quả này:

$git mergetool
No files need merging

8

Câu trả lời này là để thêm một giải pháp thay thế cho những người dùng VIM như tôi thích làm mọi thứ trong trình chỉnh sửa.


TL; DR

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


Tpope đã đưa ra plugin tuyệt vời này cho VIM được gọi là fugitive . Sau khi cài đặt, bạn có thể chạy :Gstatusđể kiểm tra các tệp có xung đột và :Gdiffđể mở Git theo cách hợp nhất 3 cách.

Khi đã hợp nhất 3 cách, fugitive sẽ cho phép bạn nhận được các thay đổi của bất kỳ nhánh nào bạn đang hợp nhất theo cách sau:

  • :diffget //2, nhận các thay đổi từ nhánh ban đầu ( HEAD ):
  • :diffget //3, nhận các thay đổi từ việc sáp nhập chi nhánh:

Khi bạn đã hoàn tất việc hợp nhất tệp, hãy nhập :Gwritevào bộ đệm đã hợp nhất. Vimcasts đã phát hành một video tuyệt vời giải thích chi tiết các bước này.


6

Gitlense cho mã VS

Bạn có thể dùng thử Gitlense cho VS Code, các tính năng chính của chúng là:

3. Dễ dàng giải quyết xung đột.

Tôi đã thích tính năng này:

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

2. Đổ lỗi hiện tại.

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

3. Đổ lỗi cho máng xối

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

4. Thanh trạng thái đổ lỗi

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

Và có nhiều tính năng bạn có thể kiểm tra chúng ở đây .


5

git fetch
git kiểm tra chi nhánh của bạn
git rebase master

Trong bước này, bạn sẽ cố gắng khắc phục xung đột bằng IDE ưa thích của mình

Bạn có thể theo liên kết này để kiểm tra ho để khắc phục xung đột trong tệp
https://help.github.com/articles/resolve-a-merge-conflict-USE-the-command-line/

git add
git rebase --continue
git commit --amend
git push origin HEAD: refs / dự thảo / master (đẩy như bản nháp)

Bây giờ mọi thứ đều ổn và bạn sẽ tìm thấy cam kết của mình trong gerrit

Tôi hy vọng rằng điều này sẽ giúp mọi người liên quan đến vấn đề này.


3

Hãy thử Visual Studio Code để chỉnh sửa nếu bạn chưa có. Những gì nó làm là sau khi bạn thử hợp nhất (và tìm ra xung đột hợp nhất) .VS mã tự động phát hiện các xung đột hợp nhất.

Nó có thể giúp bạn rất tốt bằng cách hiển thị những thay đổi được thực hiện cho bản gốc và bạn nên chấp nhận incominghoặc

current change(có nghĩa là bản gốc trước khi hợp nhất) '?.

Nó giúp tôi và nó cũng có thể làm việc cho bạn!

PS: Nó sẽ chỉ hoạt động nếu bạn đã cấu hình git với mã của bạn và Visual Studio Code.


2

Một cách an toàn hơn để giải quyết xung đột là sử dụng git-mediated (các giải pháp phổ biến được đề xuất ở đây là khá dễ bị lỗi imho).

Xem bài đăng này để giới thiệu nhanh về cách sử dụng nó.


2

Dành cho những ai đang sử dụng Visual Studio (2015 trong trường hợp của tôi)

  1. Đóng dự án của bạn trong VS. Đặc biệt trong các dự án lớn, VS có xu hướng kỳ dị khi hợp nhất sử dụng UI.

  2. Thực hiện hợp nhất trong dấu nhắc lệnh.

    kiểm tra git target_branch

    hợp nhất git source_branch

  3. Sau đó mở dự án trong VS và đi đến Team Explorer -> Branch. Bây giờ có một thông báo cho biết Hợp nhất đang chờ xử lý và các tệp xung đột được liệt kê ngay bên dưới tin nhắn.

  4. Nhấp vào tệp xung đột và bạn sẽ có tùy chọn Hợp nhất, So sánh, Lấy nguồn, Lấy mục tiêu. Công cụ hợp nhất trong VS rất dễ sử dụng.


Tôi đang sử dụng VS Code 2017 cho một dự án rất lớn và không có nhu cầu đóng dự án. Nó xử lý nó khá tốt :)
protoEveachion

2

Nếu bạn đang sử dụng intelliJ làm IDE Hãy thử hợp nhất cha mẹ với chi nhánh của bạn bằng cách

git checkout <localbranch>
git merge origin/<remotebranch>

Nó sẽ hiển thị tất cả các xung đột như thế này

A_MBPro: test anu $ git merge origin / Auto-merge src / test / java / com /.../ TestClass.java CONFLICT (nội dung): Hợp nhất xung đột trong src / test / java / com /.../ TestClass.java

Bây giờ lưu ý rằng tệp TestClass.java được hiển thị màu đỏ trong intelliJ Ngoài ra trạng thái git sẽ hiển thị

Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified:   src/test/java/com/.../TestClass.java

Mở tệp trong intelliJ, nó sẽ có các phần với

  <<<<<<< HEAD
    public void testMethod() {
    }
    =======
    public void testMethod() { ...
    }
    >>>>>>> origin/<remotebranch>

trong đó CHÍNH là thay đổi trên nhánh cục bộ của bạn và nguồn gốc / là thay đổi từ nhánh từ xa. Ở đây giữ những thứ bạn cần và loại bỏ những thứ bạn không cần. Sau đó, các bước thông thường nên làm. Đó là

   git add TestClass.java
   git commit -m "commit message"
   git push

2

Tôi đang sử dụng Mã hình ảnh của Microsoft để giải quyết xung đột. Nó rất đơn giản để sử dụng. Tôi giữ dự án của tôi mở trong không gian làm việc. Nó phát hiện và làm nổi bật các xung đột, hơn nữa cung cấp các tùy chọn GUI để chọn bất kỳ thay đổi nào tôi muốn giữ từ CHÍNH hoặc đến. nhập mô tả hình ảnh ở đây

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.