diff
diff
je v informatice nástroj, který se používá pro zjištění rozdílů mezi dvěma textovými soubory tak, že vypíše řádky, kterými se zadané soubory liší. Nalezneme jej v Unix a operačních systémech unixového typu. Nástroj je využíván zejména programátory, kteří tak mohou snadno prohlédnout změny, ke kterým ve zdrojovém kódu programu došlo. Příbuzným nástrojem je diff3, který porovnává tři soubory. Výstup programu diff označujeme jako patch (záplata) a lze ho použít k aplikaci na původní soubor pomocí stejnojmenného nástroje patch.
Vývojář | Bellovy laboratoře a Douglas McIlroy |
---|---|
Typ softwaru | počítačový program, standardní UNIXová utilita či příkaz a file comparison software |
Některá data mohou pocházet z datové položky. |
Popis činnosti
Nástroj diff
slouží k zjištění rozdílů mezi dvěma soubory, které jsou zadány na vstupu (starý a nový). Na rozdíl od nástroje cmp (který jen ohlásí, zda jsou soubory stejné nebo rozdílné) je výstupem nástroje diff
seznam změn, ke kterým došlo (přidaný řádek, smazaný řádek, změněný řádek). Změny jsou obvykle doplněny také okolními (nezměněnými) řádky textu (tzv. kontext), který slouží k lepšímu pochopení změn a pro kontrolu umístění popsaných změn.
Při posuzování změn je možné ignorovat změny založené na přidání nebo odebrání prázdných řádků, bílých znaků (mezery a tabulátory), ale i určitých řádků, takže i pro různé soubory může být nástrojem diff
zjištěno, že se neliší.
Výstupem programu je seznam změn, který je zapsán v jednom z dostupných formátů (viz dále). Tento výstup označujeme pojmem patch (záplata). Máme-li k dispozici původní verzi souboru (který byl použit při porovnání jako starý – viz výše) a záplatu, můžeme pomocí stejnojmenného nástroje patch
na něj aplikovat změny a získat tak novou verzi souboru (viz nový výše). Nástroj patch
pracuje inverzně vůči nástroji diff
. Programátoři proto nemusí při spolupráci posílat neustále celé změněné soubory, ale stačí poslat jen seznam změn k poslední všeobecně známé verzi, tj. záplatu (patch).
diff [volby] stary_soubor novy_soubor
Příkaz diff
porovnává obsah souboru stary_soubor s obsahem souboru novy_soubor. Je-li místo jména souboru použit znak „-“, čte se místo něj standardní vstup. Pokud je jeden z argumentů adresář a druhý je soubor, potom příkaz porovnává obsah uvedeného souboru se stejnojmenným souborem v uvedeném adresáři. V tomto případě se soubor nesmí nahradit znakem minus. Jsou-li oba argumenty jména adresářů, potom se porovnávají obsahy souborů v uvedených adresářích v abecedním pořadí. Potřebujeme-li adresáře prohledávat rekurzivně (tj. včetně podadresářů), zadáme volbu -r (nebo --recursive). Příkaz neporovnává obsahy adresářů jakožto souborů s adresářovou informací.
Porovnání binárních a textových souborů
Příkaz diff
je primárně určen na porovnávání textových souborů po řádcích. Na začátku porovnávání se však vždy zjišťuje, o jaký typ souboru jde. Pokud se v prvních několika KiB souboru nenajde jediný null znak, potom se soubor považuje za textový. V opačném případě jde o binární soubor, diff je porovná bajt po bajtu a pouze oznámí, že se soubory liší (nebo neoznámí nic, potom jsou soubory shodné). Příkaz můžeme volbou -a nebo --text násilně vnutit, že jde o textové soubory. Diff potom tyto soubory bude porovnávat textově. Naopak zadáním volby --brief spustíme binární porovnávání opět bez ohledu na skutečný typ souboru. K dispozici je rovněž volba --binary, která však v systémech vyhovujících normám POSIX (např. Linux) nemá význam. Význam má tam, kde se řádky ukončují dvojicí znaků CR, LF. Normálně se v takovém systému znak CR na vstupu vynechává a na výstupu se přidává. Po uvedení --binary se CR na vstupu přečte jako každý jiný znak a na výstupu se nepřidává.
Formáty výstupů
Příkaz diff
umí údaje předávat na výstup v několika formátech. Normální (implicitní) je takový, ve kterém se vypisují pouze ty řádky, které jsou v jednom či druhém souboru navíc nebo se liší. Tento formát se však pro vytváření záplat běžně nepoužívá.
Obecný formát normálního výpisu je následující:
popis změny <řádek z prvního souboru <řádek z prvního souboru… --- >řádek ze druhého souboru >řádek ze druhého souboru…
Možné popisy změny jsou tři. Obsahují vždy číslo řádku nebo interval čísel řádků (čísla se v intervalu oddělují čárkou) z prvního souboru (vztahuje se k pořadí jmen souborů uvedených na příkazovém řádku při spuštění diff), dále pak identifikátor změny (a, c, d) a číslo řádku nebo interval řádků ze druhého souboru.
- LaR
- Ve druhém souboru jsou navíc řádky R patřící za řádek L prvního souboru. Např. 8a12, 15 znamená, že ve druhém souboru jsou navíc řádky 12–15 a patří za řádek 8 v prvním souboru.
- FcT
- Řádky F z prvního souboru byly změněny. Ve druhém souboru jsou jim odpovídající řádky T. Např. popis 5,7c8,10 znamená, že se liší řádky 5–7 v prvním souboru a jim odpovídající jsou řádky 8–10 ve druhém souboru.
- RdL
- Ve druhém souboru chybí řádky R z prvního souboru. Tyto řádky by patřily za řádek L druhého souboru. Např. 5,7d3 znamená, že za řádkem 3 ve druhém souboru chybějí řádky 5–7 prvního souboru.
Další možný výstupní formát je kontextový. Zde diff změny zobrazí spolu s okolními řádky. Uživatel tak lépe pochopí význam změn. Kontextový výstupní formát zapínáme jednou z voleb -c, -C a --context. Dvěma posledním volbám zadáváme jako parametr počet řádků vypisovaného okolí. Nástroj patch typicky vyžaduje pro kontrolu aplikovaných změn dva řádky okolí.
Řádky obsahující okolí začínají dvěma mezerami. Rozdílné řádky obsahují v prvním sloupci jeden z následujících znaků a ve druhém sloupci mezeru:
- !
- Řádek je ze skupiny jednoho nebo více změněných řádků. Ve výpise jsou řádky označené „!“ jak pro první soubor, tak i pro druhý soubor.
- +
- Řádky navíc ve druhém souboru nemají svůj obraz v prvním souboru.
- -
- Řádky navíc v prvním souboru nemají svůj obraz ve druhém souboru.
Pokud jsou změny pouze typu + a -, potom se okolí v opačném souboru nevypisuje.
Dalším typem výstupního formátu je unifikovaný (sjednocený) kontextový formát. Jeho výhodou proti kontextovému způsobu výpisu je odstranění nadbytečných opakujících se řádků. Výpis v tomto tvaru se získá volbami -u, -U nebo -unified.