Ursprunglig konfiguration
Ändrad konfiguration

Config-diff: jämför INI-, TOML-, .env-filer online

Klistra in två konfigurationsfiler sida vid sida och se exakt vilka nycklar, värden och kommentarer som ändrats. Fungerar för .env, TOML, INI, .properties och .conf.

Vad är config-diff-verktyget?

Ett gratis verktyg i webbläsaren för att diffa konfigurationsfiler. Klistra in en staging-.env till vänster, produktionsversionen till höger, och saknade nycklar, ändrade värden och föråldrade kommentarer lyser upp direkt. Samma flöde för en pyproject.toml före och efter en Poetry-uppdatering, en nginx.conf du är på väg att reloada, eller en Java-application.properties som flyttas mellan miljöer.

Diffen är på teckennivå. Ingen parser, inget schema, ingen åsikt om vilken dialekt du klistrar in. Det är medvetet. Konfigurationsfiler delar inte en gemensam grammatik. INI har ingen formell spec och varje parser är oense om quoting och escapes. TOML 1.0 har en strikt grammatik men lägger till typade värden. .env-filer har ingen spec alls, bara det som dotenv eller ditt skal råkar göra.

Om du kom hit för vanlig prosa är vårt text-diff-verktyg rätt val. För YAML-konfiguration (Kubernetes-manifest, Helm-values, Ansible-playbooks) använd YAML-diff. För config som levereras som JSON (VS Code-inställningar, npm-package.json, Terraform-tfstate) hanterar JSON-diff objektomordning renare än en text-diff.

Hur diffen faktiskt fungerar

Diffen körs på teckennivå, sedan flyttar ett semantiskt efterbearbetningssteg highlightsen så att de hamnar på hela nycklar, hela värden och hela kommentarsrader istället för brus mitt i en token. Tillägg visas i grönt i högerpanelen, borttagningar i rött till vänster. Ändringsräknaren i varje sidhuvud talar om hur många distinkta redigeringar algoritmen hittade.

Konfigurationsformat varierar tillräckligt för att en enda parser inte kan tjäna alla, så det här verktyget förblir avsiktligt formatagnostiskt. .env är det luddigaste: de flesta loaders behandlar hela högersidan som en sträng, men vissa expanderar $VAR och andra inte, vissa hedrar export, och quoting kring värden med mellanslag är parser-specifik. .properties-filer (Java-standarden, dokumenterad i java.util.Properties API) accepterar antingen = eller : som separator och kräver Unicode-escapes som \u00e9 för icke-ASCII-tecken. INI-filer i naturen sträcker sig från Windows-konventionen (sektioner i hakparenteser, semikolon för kommentarer) till den något annorlunda dialekten som Pythons configparser-modul accepterar.

Tre verkliga fallgropar att känna till innan du litar på en ren diff. För det första, blanksteg i slutet av raden. Ett värde som API_KEY=abc med ett vilset mellanslag i slutet av raden är en annan sträng för de flesta loaders, och diffen flaggar det men människor ser sällan det skyldiga mellanslaget. För det andra, radbrytningar. En fil incheckad på Windows med CRLF och en skriven på Linux med LF har samma innehåll men diffen visar varje rad som ändrad; formatera båda sidor eller normalisera radbrytningarna först. För det tredje, UTF-8 byte order mark. Notepad på Windows skriver fortfarande glatt en BOM i början av en sparad .env, vilket de flesta loaders snubblar på och som visar sig som en spöktecken-diff på rad 1.

Hur du jämför config-filer i tre steg

Två textpaneler, en diff. Inget laddas upp. Inget loggas.

  1. 1

    Klistra in eller ladda upp din config

    Klistra in den gamla configen till vänster, den nya till höger. Eller klicka Upload på någondera sidan för att ladda en .env-, .toml-, .ini-, .properties- eller .conf-fil direkt. Sample-knappen fyller båda panelerna med ett litet .env-exempel så att du ser hur värdeförändringar, nya nycklar och borttagna poster renderas innan du klistrar in din egen.

  2. 2

    Formatera och normalisera

    Klicka Format på varje panel för att klippa bort blanksteg i slutet och tillämpa konsekventa radbrytningar. Det dödar den vanligaste klassen av falska positiv: två filer som ser identiska ut men diffas som helt olika eftersom den ena sparats med CRLF och den andra med LF. Diffen fokuserar på riktiga nyckel- och värdeförändringar när båda sidor är överens om blanksteg.

  3. 3

    Läs diffen

    Borttagningar visas med röd highlight till vänster, tillägg med grön highlight till höger. Scrolla en sida och den andra följer med. Kommentarer och utkommenterade nycklar diffas som vanlig text, så en nyckel du tagit bort genom att lägga # framför visas som den tillagda kommentarsraden snarare än som den raderade nyckeln.

När config-diff är rätt verktyg

Diffa .env-filer mellan local och staging

Du startar en feature branch lokalt, det fungerar bra, sedan kraschar det på staging för att STRIPE_WEBHOOK_SECRET saknas i stagings .env. Klistra in den fungerande lokala filen mot stagings och den saknade nyckeln, den ändrade DATABASE_URL-hosten och den föråldrade LOG_LEVEL=debug dyker alla upp i en omgång. Snabbare än att gå igenom båda filerna rad för rad, och mycket säkrare än att köra ett skript som skriver båda variabeluppsättningarna till en terminal.

Jämföra pyproject.toml efter en dependency-uppgradering

Poetry eller uv har precis skrivit om din pyproject.toml efter en poetry update. Diffa den tidigare incheckade versionen mot working tree för att bekräfta de faktiska uppgraderingarna: fastapi gick från 0.110.0 till 0.115.4, en ny [tool.ruff.lint]-tabell dök upp, och build-system.requires-pinen flyttade sig. TOML 1.0-specen är strikt nog för att diffen normalt ska vara ren och lättläst.

Granska nginx.conf-ändringar före reload

Att reloada nginx med en trasig config sänker en produktionssajt snabbare än nästan allt annat på en server. Före nginx -s reload: klistra in den körande nginx.conf mot den föreslagna och bekräfta att ändringen är exakt det du avsåg: ett nytt upstream-block, ett uppdaterat proxy_pass-mål, ett TLS-cipher-suite-byte. Diffen fångar det oavsiktligt bortglömda semikolonet varje gång.

Granska en systemd-unit eller supervisord-config

En tjänst startar om i loop efter en deploy. Diffa den fungerande foo.service mot den nya och du hittar oftast orsaken inom trettio sekunder: en ändrad ExecStart, en bortfallen Environment=-rad, en åtdragen NoNewPrivileges. Samma flöde för supervisord-.conf-block, runit run-skript och de olika .ini-liknande init-configar du fortfarande ser på äldre maskiner.

Jämföra infrastructure-as-code-config-filer

Terraform-variabler i terraform.tfvars, Pulumi-stack-configar, Ansible-group_vars, Helm-values för Kubernetes ConfigMaps. Varje miljö har sin egen kopia och det enda säkra sättet att merge:a dem är att diffa. Klistra in prod mot staging och driften hoppar fram: en region pinned till us-east-1 i en och us-west-2 i den andra, en instance-typ som någon höjde under en incident och aldrig återställde, ett IAM-role-ARN som pekar på fel konto.

Kontrollera att en CI-environment-fil matchar den dokumenterade mallen

En ny ingenjör börjar, kopierar .env.example från repot, och builden faller fortfarande på hennes första PR eftersom mallen drivit isär från det CI-pipelinen faktiskt förväntar sig. Diffa den incheckade .env.example mot en känt-bra .env från någon vars builds går igenom, och de saknade nycklarna visar sig som rött till vänster eller grönt till höger. Samma trick fungerar för Taskfile-env-block, GitHub Actions env:-sektioner och direnv-.envrc-filer.

Snabbreferens config-format

Ett kort fusklapp över de format det här verktyget ser oftast. Konfiguration är rörigare än ryktet antyder, och skillnaderna nedan är där de flesta diffar går snett.

TopicWhat this tool does
FormatdialekterINI (ingen formell spec, dialekter per parser), TOML 1.0 (strikt, typad), .env (ingen spec, parser-definierad), .properties (Java, se java.util.Properties), .conf (per applikation: nginx, Apache, sshd_config skiljer sig alla).
KommentarsteckenINI: ; eller #. TOML: bara #. .env: bara #, och bara i början av raden i de flesta loaders. .properties: # eller !. nginx .conf: bara #.
SektionsrubrikerINI och TOML använder [section]. TOML lägger till nästade tables via [a.b.c] och arrayer av tables via [[a]]. .env och .properties är platta, utan sektioner. nginx använder { ... }-block istället för rubriker.
VärdetyperTOML har typade värden: strängar, ints, floats, bools, datum, arrayer, tables. INI, .env och .properties är bara sträng; applikationen bestämmer hur true eller 42 ska parsas.
Interpolation och expansionDe flesta dotenv-loaders expanderar inte $VAR som standard. Vissa gör det (dotenv-expand, direnv, shell-sourcing via source .env). TOML expanderar aldrig. INI sällan; Pythons configparser stödjer ${section:key} om du opt-in:ar.
Blanksteg i slutetEn riktig buggkälla. FOO=bar med ett efterföljande mellanslag sätter FOO till "bar " i de flesta loaders, vilket misslyckas i strängjämförelser nedströms. Klipp alltid bort eller cita.
RadbrytningarCRLF (Windows) vs LF (Unix). Två identiska filer sparade på olika OS diffas som varje-rad-ändrad. Använd Format-knappen eller normalisera radbrytningarna (dos2unix, git config core.autocrlf) före diffning.
Encoding och BOMTOML föreskriver UTF-8. .properties krävde historiskt ISO-8859-1 med \uXXXX-escapes, men modern Java accepterar UTF-8 via Properties.load(Reader). En UTF-8 BOM i början av en .env är en klassisk spök-diff-orsak; Notepad på Windows skriver fortfarande en som standard.

Config-diff: vanliga frågor

Förstår verktyget värdetyper?

Nej. Det är en text-diff. TOML skiljer på strängar, heltal, flyttal, booleans, datum och arrayer, men diffen behandlar varje rad som vanlig text och visar vilka tecken som ändrats. Det är oftast okej eftersom konfigurationsändringar är teckenändringar i alla fall. Om du verkligen behöver en typad jämförelse, parsa båda filerna i ditt språk efter eget val (Pythons tomllib, Rusts toml-crate, Gos pelletier/go-toml) och jämför de resulterande mappningarna. För 95%-fallet fångar text-diffen vad du behöver fånga.

Hur hanterar jag utkommenterade rader som "skiljer sig" men är likvärdiga?

Du gör oftast inte det, och du borde vara glad att verktyget flaggade det. En rad som går från API_KEY=abc till #API_KEY=abc är semantiskt betydelsefull: nyckeln är nu inaktiverad. Diffen lyfter fram kommentarsprefix-ändringen, vilket är exakt vad en mänsklig granskare borde se under en config-granskning. Om du verkligen vill ignorera kommentarsbrus, formatera båda sidor för att ta bort rader med bara kommentar innan du klistrar in, men det är sällan rätt drag för en säkerhetsrelevant fil.

Hur kontrollerar jag om en nyckel saknas på ena sidan?

Klistra in båda filerna, kör diffen, och varje nyckel som finns på ena sidan och saknas på den andra visas som en röd borttagning eller en grön infogning av hela raden. Diffen försöker inte rikta upp nycklar strukturellt, så en nyckel som flyttats till en annan position visas en gång som borttagning och en gång som infogning. För en helt ordningsoberoende jämförelse, sortera båda filerna på nyckel först (sort .env på Unix) och diffa sedan. Den formatagnostiska metoden fångar saknade nycklar utan att behöva en parser.

Är det säkert att klistra in .env-filer med riktiga secrets?

Ja, din input lämnar aldrig webbläsaren. Diffen körs helt på klienten. Ingen serveruppladdning, ingen telemetri på panelinnehåll, ingen analytics som fångar det du skrivit. Det är avsiktligt eftersom .env-differ hör till de mest förtroendekrävande flödena på den här sajten. Om du är paranoid (och det borde du vara lite), öppna webbläsarens devtools och bekräfta att nätverksfliken förblir tom medan du klistrar in. För organisationer som föredrar ett helt air-gapped verktyg: öppna sajten offline en gång och de cachade resurserna fungerar utan vidare nätverksåtkomst.

Vad är skillnaden mellan TOML och INI?

INI är en konvention; TOML är en specifikation. INI växte upp på Windows, har ingen formell grammatik, och varje parser hanterar gränsfall (quoting, escapes, listvärden, nästade sektioner) lite annorlunda. TOML 1.0 är en strikt, versionerad spec som används av Cargo, Poetry, Hugo och alltmer av Python-paketering via pyproject.toml. Båda använder [section]-headers och key = value-par, så de ser lika ut vid första anblicken, men TOML lägger till typade värden, datetime-literaler och inline tables som klassiska INI-filer inte har.

Normaliserar diffen nyckelversaler eller blanksteg?

Nej. API_KEY=abc och api_key=abc är olika rader för diffen eftersom de är olika bytes. De flesta loaders är också skiftlägeskänsliga (dotenv, java.util.Properties, configparser som standard), så detta matchar verkligheten. Blanksteg runt = bevaras som det är, vilket spelar roll eftersom några striktare parsers (särskilt vissa Bash-sourcing-mönster) avvisar FOO = bar med mellanslag och bara accepterar FOO=bar. Format-knappen klipper bort blanksteg i slutet av varje rad, vilket är det enda normaliseringssteg den tillämpar.

Sekretess och hur det här fungerar

Dina konfigurationsfiler lämnar aldrig din webbläsare. Diffen, formateraren och varje byte av din input stannar lokalt på din maskin. Ingen analytics på panelinnehåll, inga loggar, ingen uppladdning. Det betyder mer här än för de flesta diff-verktyg, eftersom .env-filer rutinmässigt innehåller databaslösenord, API-nycklar och OAuth-client-secrets, och att klistra in dem i ett verktyg som åker fram och tillbaka till en server skulle vara en riktig säkerhetsincident. Bakgrundsläsning om formaten: TOML 1.0, INI-filer och Unix-konceptet miljövariabler. För secrets som inte alls borde leva i en fil, titta på sops, HashiCorp Vault eller AWS Parameter Store.