Przejdź do pierwszej, poprzedniej, następnej, ostatniej sekcji, spisu treści.


7. Scalanie według wspólnego przodka

Gdy dwie osoby wprowadziły zmiany na kopiach tego samego pliku, diff3 potrafi utworzyć scalone wyjście, które zawiera oba zestawy poprawek razem z ostrzeżeniami o konfliktach.

Można sobie wyobrazić programy o nazwach typu diff4 i diff5 do porównywania więcej niż trzech plików równocześnie, ale w praktyce rzadko pojawia się taka potrzeba. Do połączenia więcej niż dwu zestawów zmian danego pliku można użyć diff3, scalając po dwa zestawy zmian na raz.

diff3 potrafi wcielić zmiany z dwu zmienionych wersji do wspólnej pierwotnej wersji. Pozwala to na scalanie zestawów zmian reprezentowanych przez dwa nowsze pliki. Podaje się wówczas wspólną, pierwotną wersję jako drugi argument, a dwie nowsze -- jako pierwszy i trzeci, w ten sposób:

diff3 mój starszy twój

Kolejność argumentów łatwo zapamiętać gdy zauważymy, że występują w kolejności alfabetycznej.

Możemy to interpretować jako odejmowanie starszego od twojego i dodanie wyniku do mojego, albo jako ujęcie w moim zmian, które przekształciłyby starszy w twój. Takie scalanie jest precyzyjnie zdefiniowane dopóki mój i twój pasują do siebie w sąsiedztwie takiej zmiany. Nie sprawdza się jednak gdy wszystkie trzy pliki różnią się od siebie lub gdy różni się tylko starszy; mówimy wówczas o konflikcie. Kiedy wszystkie trzy pliki są różne, konflikt taki nazywamy zakładką (overlap).

diff3 dostarcza kilku sposobów obsługi zakładek i konfliktów. Można je pominąć, wybrać tylko zakładki albo oznaczyć konflikty specjalnymi liniami `<<<<<<<' i `>>>>>>>'.

diff3 potrafi wypisać wyniki scalania w postaci skryptu ed, który można zastosować do pierwszego pliku, by uzyskać scalone wyjście. Jednak zwykle jest lepiej, gdy diff3 bezpośrednio tworzy scalone wyjście. Obchodzimy wówczas pewne problemy z ed.

7.1. Wybór zmian, jakie mają zostać wcielone

Za pomocą opcji `-e' lub `--ed' wybieramy do scalania w moim wszystkie niescalone zmiany między starszym a twoim. Opcją `-3' lub `--easy-only' wybieramy scalanie tylko nienakładających się niescalonych zmian, a opcją `-x' lub `--overlap-only' tylko zmian, które się nakładają.

W opcjach `-e', `-3' i `-x' wybierane są tylko niescalone zmiany, tj. zmiany, gdzie różnią się mój i twój; ignorowane są zmiany między starszym a twoim, gdzie mój i twój są identyczne, gdyż zakłada się, że takie zmiany zostały już scalone. Jeżeli takie założenie nie jest bezpieczne, powinniśmy użyć opcji `-A' lub `--show-all' (zob. 7.2. Oznaczanie konfliktów).

Oto wyjście polecenia diff3 z każdą z tych trzech opcji

(zob. 6.1. Trzeci przykładowy plik wejściowy, gdzie podano pełną postać użytych plików). Zauważ, że `-e' daje sumę rozłącznych zbiorów zmian wypisywanych przez `-3' i `-x'.

Wynik działania `diff3 -e lao tsy tao':

11a

  -- Lao-tsy, Tao-te-king (Księga Drogi i Cnoty)
.
8c
  może tylko ujrzeć skończoność rzeczy.
.

Wynik działania `diff3 -3 lao tsy tao':

8c
  może tylko ujrzeć skończoność rzeczy.
.

Wynik działania `diff3 -x lao tsy tao':

11a

  -- Lao-tsy, Tao-te-king (Księga Drogi i Cnoty)
.

7.2. Oznaczanie konfliktów

diff3 może zaznaczać konflikty w scalonym wyjściu, ujmując je między specjalne linie znacznikowe. Konflikt pomiędzy dwoma plikami A a B oznaczany jest tak:

<<<<<<< A
linie z A
=======
linie z B
>>>>>>> B

Konflikt między trzema plikami A, B i C jest oznaczany tak:

<<<<<<< A
linie z A
||||||| B
linie z B
=======
linie z C
>>>>>>> C

Opcja `-A' lub `--show-all' działa tak, jak opcja `-e', za wyjątkiem tego, że ujmuje konflikty między linie znacznikowe i wypisuje wszystkie zmiany między starszym a twoim, a nie tylko zmiany niescalone. Zatem, przy przykładowych plikach wejściowych (zob. 6.1. Trzeci przykładowy plik wejściowy), `diff3 -A lao tsy tao' wstawia nawiasy ostrokątne wokół konfliktów, gdzie różni się tylko `tsy':

<<<<<<< tsy
=======
Tao, które można wyrazić słowami, nie jest prawdziwym tao.
Nazwa, którą można je określić, nie jest niezmienną nazwą.
>>>>>>> tao

A konflikty trójstronne wypisuje tak:

<<<<<<< lao
||||||| tsy
To, co w nich wspólne, nazywamy wielką tajemnicą,
tajemnicą nad tajemnicami,
bramą do poznania wszelakich cudowności.
=======

  -- Lao-tsy, Tao-te-king (Księga Drogi i Cnoty)
>>>>>>> tao

Opcja `-E' lub `--show-overlap' wypisuje mniej informacji niż `-A' (`--show-all'), gdyż podaje tylko zmiany niescalone, a nigdy nie wypisuje zawartości drugiego pliku. Stąd też `-E' działa jak `-e', prócz tego, że ujmuje w znaczniki pierwszy i trzeci plik z trójstronnych nakładających się zmian. Podobnie, `-X' działa jak `-x', poza tym, że ujmuje w znaczniki wszystkie (niekoniecznie nakładające się) zmiany. Na przykład, dla powyższej trójstronnej nakładającej się zmiany, opcje `-E' i `-X' wypiszą:

<<<<<<< lao
=======

  -- Lao-tsy, Tao-te-king (Księga Drogi i Cnoty)
>>>>>>> tao

Porównując dwa pliki o nic nie mówiących lub niewiele mówiących nazwach, zapewne chcielibyśmy, by diff3 w nawiasach `<<<<<<<', `|||||||' i `>>>>>>>' pokazał jakieś ich nazwy zastępcze. Służy do tego opcja `-L etykieta' lub `--label=etykieta'. Może zostać podana do trzech razy, po jednym na każdy plik wejściowy. Zatem `diff3 -A -L X -L Y -L Z A B C' działa tak, jak `diff3 -A A B C', poza tym, że wyjście wygląda, jakby zostało otrzymane z plików o nazwach `X', `Y' i `Z', a nie `A', `B' i `C'.

7.3. Bezpośrednie tworzenie scalonego wyjścia

Z opcją `-m' lub `--merge' diff3 wprost wypisuje scalony plik. Jest to efektywniejsze niż stosowanie do jego utworzenia programu ed i działa nawet z plikami nie-tekstowymi, które ed by odrzucił. Jeśli podamy `-m' bez opcji skryptu ed, to przyjmowane jest `-A' (`--show-all').

Na przykład, polecenie `diff3 -m lao tsy tao' (zob. 6.1. Trzeci przykładowy plik wejściowy, gdzie pokazano pliki wejściowe) wypisze:

<<<<<<< tsy
=======
Tao, które można wyrazić słowami, nie jest prawdziwym tao.
Nazwa, którą można je określić, nie jest niezmienną nazwą.
>>>>>>> tao
Bezimienne jest początkiem nieba i ziemi,
Nazwane jest matką wszystkich rzeczy.
Przeto, kto trwale pozbawion jest pragnień wszelakich,
  potrafi dojrzeć subtelną istotę tao,
zaś, kto niezmiennie tkwi w pętach swych pragnień,
  może tylko ujrzeć skończoność rzeczy.
Te dwie strony tao wywodzą się
ze wspólnego źródła,
  lecz noszą odmienne nazwy.
<<<<<<< lao
||||||| tsy
To, co w nich wspólne, nazywamy wielką tajemnicą,
tajemnicą nad tajemnicami,
bramą do poznania wszelakich cudowności.
=======

  -- Lao-tsy, Tao-te-king (Księga Drogi i Cnoty)
>>>>>>> tao

7.4. Jak diff3 scala niekompletne linie

Z `-m', niekompletne linie (zob. 16. Niekompletne linie) są po prostu kopiowane na wyjście, tak jak je zastano. Jeśli scalane wyjście kończy się konfliktem, a jeden z plików wejściowych kończy się niekompletną linią, to następujące po niej znaczniki `|||||||', `=======' lub `>>>>>>>' pojawią się gdzieś indziej niż na początku linii, gdyż zostaną dopisane do niekompletnej linii.

Bez `-m', jeśli podano opcję skryptu ed a została napotkana niekompletna linia, diff3 generuje ostrzeżenie i działa tak, jakby znak nowej linii był obecny.

7.5. Zachowywanie zmienionego pliku

Tradycyjny uniksowy diff3 tworzy skrypt ed bez końcowych poleceń `w' i `q', które zapisują zmiany pliku. diff3 z System V generuje te dodatkowe polecenia. GNU diff3 normalnie zachowuje się tak, jak tradycyjna uniksowa wersja, ale z opcją `-i' działa jak diff3 z System V i dokłada `w' i `q'.

Opcja `-i' wymaga jednej z opcji tworzących skrypt ed: `-AeExX3', i jest nie współpracuje z opcją scalania wyjścia `-m'.


Przejdź do pierwszej, poprzedniej, następnej, ostatniej sekcji, spisu treści.