Tôi cũng quan tâm. Tôi không biết câu trả lời, nhưng ...
Một hệ thống phức tạp hoạt động luôn được phát hiện là đã phát triển từ một hệ thống đơn giản hoạt động
Tôi nghĩ việc hợp nhất git rất phức tạp và sẽ rất khó hiểu - nhưng một cách để tiếp cận điều này là từ các tiền thân của nó và tập trung vào trọng tâm mối quan tâm của bạn. Nghĩa là, với hai tệp không có chung tổ tiên, việc hợp nhất git sẽ làm cách nào để hợp nhất chúng và xung đột ở đâu?
Chúng ta hãy thử tìm một số tiền chất. Từ git help merge-file
:
git merge-file is designed to be a minimal clone of RCS merge; that is,
it implements all of RCS merge's functionality which is needed by
git(1).
Từ wikipedia: http://en.wikipedia.org/wiki/Git_%28software%29 -> http://en.wikipedia.org/wiki/Three-way_merge#Three-way_merge -> http://vi.wikipedia .org / wiki / Diff3 -> http://www.cis.upenn.edu/~bcpierce/papers/diff3-short.pdf
Liên kết cuối cùng đó là bản pdf của bài báo mô tả diff3
chi tiết thuật toán. Đây là phiên bản google pdf-browser . Nó chỉ dài 12 trang và thuật toán chỉ dài một vài trang - nhưng là một phép toán học đầy đủ. Điều đó có vẻ hơi quá trang trọng, nhưng nếu bạn muốn hiểu hợp nhất của git, trước tiên bạn cần hiểu phiên bản đơn giản hơn. Tôi chưa kiểm tra, nhưng với một cái tên như vậy diff3
, bạn có thể cũng cần hiểu khác biệt (sử dụng thuật toán dãy con chung dài nhất ). Tuy nhiên, có thể có một lời giải thích trực quan hơn diff3
, nếu bạn có ...
Bây giờ, tôi vừa thực hiện một thử nghiệm so sánh diff3
và git merge-file
. Họ đi cùng ba tập tin đầu vào version1 oldversion version2 và xung đột dấu cách giống nhau, với <<<<<<< version1
, =======
, >>>>>>> version2
( diff3
cũng có ||||||| oldversion
), cho thấy di sản chung của họ.
Tôi đã sử dụng một tập tin rỗng cho oldversion , và các tập tin gần như giống hệt nhau cho version1 và version2 chỉ với một cú thêm dòng thêm vào version2 .
Kết quả: git merge-file
xác định dòng thay đổi duy nhất là xung đột; nhưng diff3
coi toàn bộ hai tệp là xung đột. Vì vậy, phức tạp như diff3, hợp nhất của git thậm chí còn phức tạp hơn, ngay cả đối với trường hợp đơn giản nhất này.
Đây là kết quả thực tế (tôi đã sử dụng câu trả lời của @ twalberg cho văn bản). Lưu ý các tùy chọn cần thiết (xem các trang tương ứng).
$ git merge-file -p fun1.txt fun0.txt fun2.txt
You might be best off looking for a description of a 3-way merge algorithm. A
high-level description would go something like this:
Find a suitable merge base B - a version of the file that is an ancestor of
both of the new versions (X and Y), and usually the most recent such base
(although there are cases where it will have to go back further, which is one
of the features of gits default recursive merge) Perform diffs of X with B and
Y with B. Walk through the change blocks identified in the two diffs. If both
sides introduce the same change in the same spot, accept either one; if one
introduces a change and the other leaves that region alone, introduce the
change in the final; if both introduce changes in a spot, but they don't match,
mark a conflict to be resolved manually.
<<<<<<< fun1.txt
=======
THIS IS A BIT DIFFERENT
>>>>>>> fun2.txt
The full algorithm deals with this in a lot more detail, and even has some
documentation (/usr/share/doc/git-doc/technical/trivial-merge.txt for one,
along with the git help XXX pages, where XXX is one of merge-base, merge-file,
merge, merge-one-file and possibly a few others). If that's not deep enough,
there's always source code...
$ diff3 -m fun1.txt fun0.txt fun2.txt
<<<<<<< fun1.txt
You might be best off looking for a description of a 3-way merge algorithm. A
high-level description would go something like this:
Find a suitable merge base B - a version of the file that is an ancestor of
both of the new versions (X and Y), and usually the most recent such base
(although there are cases where it will have to go back further, which is one
of the features of gits default recursive merge) Perform diffs of X with B and
Y with B. Walk through the change blocks identified in the two diffs. If both
sides introduce the same change in the same spot, accept either one; if one
introduces a change and the other leaves that region alone, introduce the
change in the final; if both introduce changes in a spot, but they don't match,
mark a conflict to be resolved manually.
The full algorithm deals with this in a lot more detail, and even has some
documentation (/usr/share/doc/git-doc/technical/trivial-merge.txt for one,
along with the git help XXX pages, where XXX is one of merge-base, merge-file,
merge, merge-one-file and possibly a few others). If that's not deep enough,
there's always source code...
||||||| fun0.txt
=======
You might be best off looking for a description of a 3-way merge algorithm. A
high-level description would go something like this:
Find a suitable merge base B - a version of the file that is an ancestor of
both of the new versions (X and Y), and usually the most recent such base
(although there are cases where it will have to go back further, which is one
of the features of gits default recursive merge) Perform diffs of X with B and
Y with B. Walk through the change blocks identified in the two diffs. If both
sides introduce the same change in the same spot, accept either one; if one
introduces a change and the other leaves that region alone, introduce the
change in the final; if both introduce changes in a spot, but they don't match,
mark a conflict to be resolved manually.
THIS IS A BIT DIFFERENT
The full algorithm deals with this in a lot more detail, and even has some
documentation (/usr/share/doc/git-doc/technical/trivial-merge.txt for one,
along with the git help XXX pages, where XXX is one of merge-base, merge-file,
merge, merge-one-file and possibly a few others). If that's not deep enough,
there's always source code...
>>>>>>> fun2.txt
Nếu bạn thực sự quan tâm đến điều này, đó là một lỗ thỏ. Đối với tôi, nó có vẻ sâu sắc như các biểu thức chính quy, thuật toán con chung dài nhất của diff, ngữ pháp tự do ngữ cảnh hoặc đại số quan hệ. Nếu bạn muốn đi đến tận cùng của nó, tôi nghĩ bạn có thể, nhưng sẽ cần một số nghiên cứu quyết tâm.