diff to klasyczne narzędzie Uniksa do porównywania dwóch plików (albo całych katalogów) linia po linii. Pokazuje dokładnie, co trzeba zmienić w pierwszym pliku, żeby stał się drugim: które linie usunąć, które dodać, a które przerobić. Jest sercem code review sprzed ery GUI i fundamentem komendy patch oraz całego systemu kontroli wersji. Jeśli kiedykolwiek widziałeś znaki < i > przy porównaniu konfigów, to właśnie robota diff.
Składnia i najważniejsze opcje
Podstawowa forma to diff [OPCJE] PLIK1 PLIK2. Domyślnie dostajesz tzw. format normalny (2c2, linie z < i >), ale w praktyce niemal zawsze używa się jednej z flag formatujących.
-u— format zunifikowany (unified), 3 linie kontekstu, dodania ze znakiem+, usunięcia z-; standard dlapatchi gita.-y— wyświetla pliki obok siebie w dwóch kolumnach; czytelne na szerokim terminalu.-r— rekurencyjnie porównuje całe drzewa katalogów (działa razem z podaniem dwóch katalogów).-q— tryb skrótowy: mówi tylko, czy pliki się różnią, bez wypisywania zmian.-i— ignoruje wielkość liter przy porównaniu.-w— ignoruje wszystkie białe znaki,-bignoruje tylko zmiany w ilości spacji/tabów.-N— traktuje brakujący plik jak pusty (przydatne przy-r, gdy plik istnieje tylko po jednej stronie).--color=auto— koloruje wynik (wartości:never,always,auto).
Przykłady użycia
diff stary.conf nowy.conf— pokazuje różnice w formacie normalnym między dwiema wersjami konfiguracji.diff -u app.js app.js.bak— generuje czytelny diff zunifikowany, gotowy do wklejenia w PR albo przekazania dopatch.diff -u plik.txt plik.new > zmiany.patch— zapisuje różnice do pliku łatki, który potem nałożysz przezpatch < zmiany.patch.diff -ry --suppress-common-lines kat_a kat_b— rekurencyjnie porównuje dwa katalogi w widoku kolumnowym, pokazując tylko to, co się różni.diff -q -r release-1 release-2— szybko listuje, które pliki w dwóch wydaniach w ogóle się różnią, bez zalewania Cię treścią.
Częste błędy i pułapki
Kolejność argumentów ma znaczenie: diff stary nowy i diff nowy stary dają odwrotne diffy, a + i - się zamienią. Pamiętaj, że pliki muszą być tekstowe, na binarnych diff powie tylko Binary files X and Y differ i tyle. Mylące bywają też zakończenia linii: plik z Windows (CRLF) pokaże się jako całkowicie różny od wersji uniksowej (LF), mimo że oczom wygląda identycznie, ratuje wtedy diff --strip-trailing-cr. Część flag (np. --color, -Z) to dodatki GNU diffutils, więc na macOS (BSD) albo w okrojonym busyboksie mogą nie zadziałać. I drobiazg: kod wyjścia 1 nie oznacza awarii, tylko że pliki się różnią (0 = identyczne, 2 = realny błąd) co bywa zaskoczeniem w skryptach.
Powiązane komendy: patch, diff3, cmp, comm, sdiff, vimdiff oraz git diff.