diff

Pokazuje różnice między dwoma plikami lub katalogami linia po linii.

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 dla patch i 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, -b ignoruje 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 do patch.
  • diff -u plik.txt plik.new > zmiany.patch — zapisuje różnice do pliku łatki, który potem nałożysz przez patch < 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.