Oryginalna konfiguracja
Zmieniona konfiguracja

Diff Configa: Porównuj pliki INI, TOML, .env online

Wklej dwa pliki konfiguracyjne obok siebie i zobacz dokładnie, które klucze, wartości i komentarze się zmieniły. Działa dla .env, TOML, INI, .properties i .conf.

Czym jest narzędzie do diff konfiguracji?

Darmowe narzędzie w przeglądarce do diffowania plików konfiguracyjnych. Wklej staging .env po lewej, produkcyjny po prawej, a brakujące klucze, zmienione wartości i przestarzałe komentarze rozświetlają się natychmiast. Ten sam przepływ dla pyproject.toml przed i po update Poetry, dla nginx.conf tuż przed reloadem, czy javowego application.properties wędrującego między środowiskami.

Diff jest na poziomie znaków. Bez parsera, bez schematu, bez zdania o tym, jaki dialekt wklejasz. To celowe. Pliki konfiguracyjne nie dzielą jednej gramatyki. INI nie ma formalnej spec, a każdy parser inaczej traktuje cudzysłowy i escape'y. TOML 1.0 ma surową gramatykę, ale dodaje typowane wartości. Pliki .env nie mają spec w ogóle, tylko to, co dotenv albo Twój shell akurat zrobi.

Jeśli przyszedłeś po zwykły tekst, nasze narzędzie do diff tekstu jest właściwym wyborem. Dla konfiguracji YAML (manifesty Kubernetes, wartości Helm, playbooki Ansible) użyj diff YAML. Dla konfiguracji w JSON (ustawienia VS Code, npmowy package.json, terraformowy tfstate), diff JSON radzi sobie z przestawianiem obiektów czyściej niż diff tekstowy.

Jak diff naprawdę działa

Diff działa na poziomie znaków, a potem przebieg semantycznego post-processingu przesuwa podświetlenia tak, by trafiały na całe klucze, całe wartości i całe linie komentarza, a nie na szum w środku tokenu. Wstawienia widać na zielono w prawym panelu, usunięcia na czerwono po lewej. Licznik zmian w nagłówku każdej strony mówi, ile odrębnych edycji znalazł algorytm.

Formaty konfiguracyjne różnią się na tyle, że jeden parser nie wystarczy dla wszystkich, więc to narzędzie celowo pozostaje agnostyczne formatowo. .env jest najluźniejszy: większość loaderów traktuje całą prawą stronę jako string, ale niektóre rozwijają $VAR, a inne nie, niektóre honorują export, a cudzysłowy wokół wartości ze spacjami zależą od parsera. Pliki .properties (standard javowy, udokumentowany w API java.util.Properties) akceptują = lub : jako separator i wymagają unicode'owych escape'ów typu \u00e9 dla znaków spoza ASCII. Pliki INI w realu rozciągają się od konwencji Windows (sekcje w nawiasach kwadratowych, średniki dla komentarzy) po nieco inny dialekt, który akceptuje pythonowy moduł configparser.

Trzy realne pułapki, które warto znać, zanim zaufasz czystemu diffowi. Po pierwsze, spacje na końcu wiersza. Wartość typu API_KEY=abc z błąkającą się spacją na końcu linii to dla większości loaderów inny string, diff to oznaczy, ale ludzie rzadko zauważają winną spację. Po drugie, znaki końca linii. Plik commitnięty na Windowsie z CRLF i drugi napisany na Linuksie z LF mają tę samą zawartość, ale diff pokaże każdą linię jako zmienioną; sformatuj obie strony albo znormalizuj końce linii wcześniej. Po trzecie, znacznik kolejności bajtów UTF-8. Notatnik na Windowsie wesoło wciąż zapisuje BOM na początku zachowanego .env, na czym potyka się większość loaderów i co prezentuje się jako jednoznakowy diff-widmo w linii 1.

Jak porównać pliki configa w trzech krokach

Dwa panele tekstowe, jeden diff. Nic nie jest wysyłane. Nic nie jest logowane.

  1. 1

    Wklej lub wgraj swój config

    Wklej stary config po lewej, nowy po prawej. Lub kliknij Upload po którejś stronie, żeby załadować plik .env, .toml, .ini, .properties albo .conf bezpośrednio. Przycisk Sample wypełnia oba panele małym przykładem .env, żebyś zobaczył, jak renderują się zmiany wartości, nowe klucze i usunięte wpisy, zanim wkleisz własne.

  2. 2

    Sformatuj i znormalizuj

    Kliknij Format w każdym panelu, żeby przyciąć spacje na końcu i zastosować spójne końce linii. To zabija najczęstszą klasę fałszywych alarmów: dwa pliki, które wyglądają identycznie, ale diffują się jako kompletnie różne, bo jeden został zapisany w CRLF, a drugi w LF. Diff skupia się na realnych zmianach kluczy i wartości, gdy obie strony zgadzają się co do whitespace.

  3. 3

    Czytaj diff

    Usunięcia pojawiają się z czerwonym podświetleniem po lewej, wstawienia z zielonym po prawej. Przewiń jedną stronę, druga podąży. Komentarze i wykomentowane klucze są diffowane jak zwykły tekst, więc klucz, który usunąłeś, dodając przed nim #, pojawia się jako dodana linia komentarza, a nie jako usunięty klucz.

Kiedy diff configa jest właściwym narzędziem

Diffowanie plików .env między localem a stagingiem

Odpalasz feature branch lokalnie, działa, potem padają na stagingu, bo w stagingowym .env brakuje STRIPE_WEBHOOK_SECRET. Wklej działający plik lokalny przeciw stagingowemu i brakujący klucz, zmieniony host DATABASE_URL i przestarzały LOG_LEVEL=debug wyłonią się w jednym przebiegu. Szybciej niż przechodzić oba pliki linia po linii i znacznie bezpieczniej niż odpalać skrypt, który drukuje oba zestawy zmiennych do terminala.

Porównywanie pyproject.toml po upgradzie zależności

Poetry albo uv właśnie przepisało Twój pyproject.toml po poetry update. Diffuj poprzednią zacommitowaną wersję przeciw working tree, żeby potwierdzić rzeczywiste upgrade'y: fastapi przeszło z 0.110.0 na 0.115.4, pojawiła się nowa tabela [tool.ruff.lint], a pin build-system.requires się przesunął. Spec TOML 1.0 jest na tyle surowa, że diff zwykle wychodzi czysty i łatwy do czytania.

Przegląd zmian w nginx.conf przed reloadem

Reload nginx z zepsutym configiem zwala stronę produkcyjną szybciej niż prawie cokolwiek innego na serwerze. Przed nginx -s reload wklej działający nginx.conf przeciw proponowanemu i potwierdź, że zmiana jest dokładnie tym, co zamierzałeś: nowy blok upstream, zaktualizowany cel proxy_pass, zmiana TLS cipher suite. Diff za każdym razem łapie przypadkowo zgubiony średnik.

Audyt unit systemd albo configa supervisord

Serwis restartuje się w pętli po deployu. Diffuj działający foo.service przeciw nowemu i zwykle znajdujesz przyczynę w trzydzieści sekund: zmienione ExecStart, wypadnięta linia Environment=, zacieśnione NoNewPrivileges. Ten sam przepływ dla bloków .conf supervisord, run-skryptów runit i różnych initów w stylu .ini, które wciąż widzisz na starszych maszynach.

Porównywanie plików configa infrastructure-as-code

Zmienne Terraform w terraform.tfvars, configi stacka Pulumi, ansible'owe group_vars, helmowe wartości dla ConfigMapów Kubernetes. Każde środowisko ma swoją kopię i jedyny bezpieczny sposób ich łączenia to diffowanie. Wklej proda przeciw stagingowi i drift wyskakuje: region przypięty do us-east-1 w jednym i us-west-2 w drugim, instance type, który ktoś podbił podczas incydentu i nigdy nie cofnął, ARN roli IAM wskazujący na zły konto.

Sprawdzenie, czy plik środowiskowy CI zgadza się z udokumentowanym templateem

Nowy inżynier dołącza, kopiuje .env.example z repo i build wciąż mu pada na pierwszym PR, bo template odjechał od tego, czego naprawdę oczekuje pipeline CI. Diffuj zacommitowany .env.example przeciw znanemu-dobremu .env kogoś, komu buildy przechodzą, a brakujące klucze pokażą się jako czerwone po lewej lub zielone po prawej. Ta sama sztuczka działa dla bloków env Taskfile, sekcji env: GitHub Actions i plików .envrc direnv.

Szybka referencja formatów configa

Krótka ściąga po formatach, które to narzędzie widuje najczęściej. Konfiguracja jest bardziej rozgardiaszowa niż sugeruje jej reputacja, a różnice poniżej to miejsca, w których większość diffów wykoleja się.

TopicWhat this tool does
Dialekty formatuINI (brak formalnej spec, dialekty na parser), TOML 1.0 (surowy, typowany), .env (brak spec, zdefiniowany przez parser), .properties (Java, zob. java.util.Properties), .conf (per aplikacja: nginx, Apache, sshd_config różnią się wszystkie).
Znaki komentarzaINI: ; lub #. TOML: tylko #. .env: tylko #, i tylko na początku linii w większości loaderów. .properties: # lub !. nginx .conf: tylko #.
Nagłówki sekcjiINI i TOML używają [section]. TOML dodaje zagnieżdżone tabele przez [a.b.c] i tablice tabel przez [[a]]. .env i .properties są płaskie, bez sekcji. nginx używa bloków { ... } zamiast nagłówków.
Typy wartościTOML ma typowane wartości: stringi, inty, floaty, boole, daty, tablice, tabele. INI, .env i .properties są tylko stringowe; aplikacja decyduje, jak parsować true czy 42.
Interpolacja i ekspansjaWiększość loaderów dotenv nie rozwija $VAR domyślnie. Niektóre tak (dotenv-expand, direnv, sourcing shellem przez source .env). TOML nigdy nie rozwija. INI rzadko; pythonowy configparser wspiera ${section:key}, jeśli się włączy.
Spacje na końcuRealne źródło bugów. FOO=bar z końcową spacją ustawia w większości loaderów FOO na "bar ", co fail-uje sprawdzenia równości stringów dalej. Zawsze przycinaj albo cytuj.
Końce liniiCRLF (Windows) vs LF (Unix). Dwa identyczne pliki zapisane na różnych OS-ach diffują się jako każda-linia-zmieniona. Użyj przycisku Format albo znormalizuj końce linii (dos2unix, git config core.autocrlf) przed diffowaniem.
Kodowanie i BOMTOML wymusza UTF-8. .properties historycznie wymagało ISO-8859-1 z escape'ami \uXXXX, ale współczesna Java akceptuje UTF-8 przez Properties.load(Reader). UTF-8 BOM na początku .env to klasyczna przyczyna diff-widma; Notatnik na Windowsie wciąż go domyślnie zapisuje.

Diff configa: często zadawane pytania

Czy narzędzie rozumie typy wartości?

Nie. To diff tekstowy. TOML rozróżnia stringi, intgery, floaty, booleany, daty i tablice, ale diff traktuje każdą linię jako zwykły tekst i pokazuje, które znaki się zmieniły. Zwykle to wystarcza, bo zmiany w konfiguracji i tak są zmianami znaków. Jeśli naprawdę potrzebujesz porównania typowanego, sparsuj oba pliki w wybranym języku (pythonowe tomllib, rustowy crate toml, gowy pelletier/go-toml) i porównaj wynikowe mapy. W 95% przypadków diff tekstowy łapie to, co masz złapać.

Jak postępować z wykomentowanymi liniami, które „różnią się", ale są równoważne?

Zwykle nie postępujesz, i powinieneś być zadowolony, że narzędzie to zaznaczyło. Linia, która przechodzi z API_KEY=abc w #API_KEY=abc, jest semantycznie istotna: klucz jest teraz wyłączony. Diff podświetla zmianę prefiksu komentarza, czyli dokładnie to, co ludzki reviewer powinien zobaczyć podczas przeglądu configa. Jeśli naprawdę chcesz ignorować szum komentarzy, sformatuj obie strony tak, by porzucić linie wyłącznie komentarzowe przed wklejaniem, ale to rzadko właściwy ruch dla pliku istotnego dla bezpieczeństwa.

Jak sprawdzić, czy klucz brakuje po którejś stronie?

Wklej oba pliki, odpal diff, a każdy klucz obecny po jednej stronie i nieobecny po drugiej pojawi się jako czerwone usunięcie albo zielona wstawka całej linii. Diff nie próbuje wyrównywać kluczy strukturalnie, więc klucz przeniesiony na inną pozycję pojawi się raz jako usunięcie i raz jako wstawka. Dla porównania całkowicie nieczułego na kolejność, posortuj najpierw oba pliki po kluczu (sort .env na Uniksie) i potem diffuj. Podejście agnostyczne formatowo łapie brakujące klucze bez parsera.

Czy bezpiecznie jest wklejać pliki .env z prawdziwymi sekretami?

Tak, Twój input nigdy nie opuszcza przeglądarki. Diff działa w całości po stronie klienta. Bez uploadu na serwer, bez telemetrii zawartości paneli, bez analytics, które łapią to, co napisałeś. Jest to celowe, bo diffy .env należą do najbardziej zaufaniowych przepływów na tej stronie. Jeśli jesteś paranoikiem (i powinieneś być po trochu), otwórz devtools przeglądarki i potwierdź, że zakładka sieci pozostaje pusta podczas wklejania. Dla organizacji, które wolą narzędzie w pełni air-gapped: otwórz stronę raz offline, a zacacheowane assety działają bez dalszego dostępu do sieci.

Jaka jest różnica między TOML a INI?

INI to konwencja; TOML to specyfikacja. INI wyrosło na Windowsie, nie ma formalnej gramatyki, a każdy parser obsługuje przypadki brzegowe (cudzysłowy, escape'y, wartości listowe, zagnieżdżone sekcje) trochę inaczej. TOML 1.0 to surowa, wersjonowana spec używana przez Cargo, Poetry, Hugo i coraz częściej przez pythonowy packaging poprzez pyproject.toml. Oba używają nagłówków [section] i par key = value, więc wyglądają podobnie na pierwszy rzut oka, ale TOML dodaje typowane wartości, literały datetime i inline tables, których klasyczne pliki INI nie mają.

Czy diff normalizuje wielkość liter w kluczach albo whitespace?

Nie. API_KEY=abc i api_key=abc są dla diffa różnymi liniami, bo to różne bajty. Większość loaderów też rozróżnia wielkość liter (dotenv, java.util.Properties, configparser domyślnie), więc to pasuje do rzeczywistości. Whitespace wokół = jest zachowywany jak jest, co ma znaczenie, bo kilka surowszych parserów (zwłaszcza niektóre wzorce sourcingu Bash) odrzuca FOO = bar ze spacjami i akceptuje tylko FOO=bar. Przycisk Format przycina spacje na końcu każdej linii, i to jedyny krok normalizacji, jaki stosuje.

Prywatność i jak to działa

Twoje pliki konfiguracyjne nigdy nie opuszczają przeglądarki. Diff, formatter i każdy bajt Twojego inputu zostają lokalnie na Twojej maszynie. Bez analytics na zawartość paneli, bez logów, bez uploadu. To liczy się tu bardziej niż w większości narzędzi diff, bo pliki .env rutynowo zawierają hasła do baz danych, klucze API i sekrety klientów OAuth, a wklejanie ich w narzędzie, które przepuszcza je przez serwer, byłoby realnym incydentem bezpieczeństwa. Lektura tła o formatach: TOML 1.0, pliki INI oraz uniksowe pojęcie zmiennych środowiskowych. Dla sekretów, które w ogóle nie powinny żyć w pliku, zerknij na sops, HashiCorp Vault albo AWS Parameter Store.