Saya tertarik juga. Saya tidak tahu jawabannya, tapi ...
Sistem kompleks yang berhasil selalu ditemukan telah berevolusi dari sistem sederhana yang berfungsi
Saya pikir penggabungan git sangat canggih dan akan sangat sulit untuk dipahami - tetapi salah satu cara untuk mendekatinya adalah dari pendahulunya, dan dengan fokus pada inti perhatian Anda. Yaitu, mengingat dua file yang tidak memiliki leluhur yang sama, bagaimana git menggabungkan cara menggabungkannya, dan di mana konflik terjadi?
Mari kita coba mencari beberapa prekursor. Dari 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).
Dari wikipedia: http://en.wikipedia.org/wiki/Git_%28software%29 -> http://en.wikipedia.org/wiki/Three-way_merge#Three-way_merge -> http: //en.wikipedia .org / wiki / Diff3 -> http://www.cis.upenn.edu/~bcpierce/papers/diff3-short.pdf
Tautan terakhir adalah pdf dari makalah yang menjelaskan diff3
algoritme secara rinci. Ini adalah versi google pdf-viewer . Panjangnya hanya 12 halaman, dan algoritmanya hanya beberapa halaman - tetapi perawatan matematis lengkap. Itu mungkin tampak agak terlalu formal, tetapi jika Anda ingin memahami penggabungan git, Anda harus memahami versi yang lebih sederhana terlebih dahulu. Saya belum memeriksanya, tetapi dengan nama seperti diff3
, Anda mungkin juga perlu memahami diff (yang menggunakan algoritma urutan umum terpanjang ). Namun, mungkin ada penjelasan yang lebih intuitif di diff3
luar sana, jika Anda memiliki google ...
Sekarang, saya baru saja melakukan percobaan membandingkan diff3
dan git merge-file
. Mereka mengambil tiga file yang sama masukan version1 OldVersion version2 dan konflik tanda jalan yang sama, dengan <<<<<<< version1
, =======
, >>>>>>> version2
( diff3
juga memiliki ||||||| oldversion
), menunjukkan warisan bersama mereka.
Saya menggunakan file kosong untuk versi lama , dan file yang hampir identik untuk versi1 dan versi2 hanya dengan satu baris tambahan ditambahkan ke versi2 .
Hasil: git merge-file
mengidentifikasi satu baris yang diubah sebagai konflik; tetapi diff3
memperlakukan kedua file secara keseluruhan sebagai konflik. Jadi, secanggih diff3, penggabungan git bahkan lebih canggih, bahkan untuk kasus yang paling sederhana ini.
Inilah hasil sebenarnya (saya menggunakan jawaban @ twalberg untuk teksnya). Perhatikan opsi yang diperlukan (lihat halaman manual masing-masing).
$ 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
Jika Anda benar-benar tertarik dengan ini, ini sedikit lubang kelinci. Bagi saya, ini tampaknya sedalam ekspresi reguler, algoritme urutan umum terpanjang dari diff, tata bahasa bebas konteks, atau aljabar relasional. Jika Anda ingin membacanya, saya rasa Anda bisa, tetapi itu akan membutuhkan studi yang pasti.