Config Diff: INI, TOML, .env Dosyalarını Online Karşılaştır
İki yapılandırma dosyasını yan yana yapıştırın ve hangi anahtarların, değerlerin ve yorumların değiştiğini tam olarak görün. .env, TOML, INI, .properties ve .conf için çalışır.
Config diff aracı nedir?
Yapılandırma dosyalarını diff etmek için ücretsiz, tarayıcı içi bir araç. Sola staging .env, sağa production sürümünü yapıştırın; eksik anahtarlar, değişen değerler ve eski yorumlar anında yanar. Aynı akış Poetry güncellemesi öncesi ve sonrası bir pyproject.toml, az sonra reload edeceğiniz bir nginx.conf veya ortamlar arası taşınan bir Java application.properties için de geçerlidir.
Diff karakter düzeyindedir. Parser yok, şema yok, hangi lehçeyi yapıştırdığınıza dair bir kanı yok. Bu kasıtlı. Yapılandırma dosyaları ortak bir gramer paylaşmaz. INI'nin resmi spec'i yoktur ve her parser tırnaklama ve escape'lerde farklı düşünür. TOML 1.0 sıkı bir gramere sahiptir ama tipli değerler ekler. .env dosyalarının hiç spec'i yok, sadece dotenv'in veya kabuğunuzun o an yaptığı şey vardır.
Düz metin için geldiyseniz, metin diff aracımız doğru seçim. YAML yapılandırması (Kubernetes manifestleri, Helm değerleri, Ansible playbook'ları) için YAML diff kullanın. JSON olarak gelen yapılandırma için (VS Code ayarları, npm package.json, Terraform tfstate), JSON diff nesne yeniden sıralamasını metin diff'inden daha temiz işler.
Diff gerçekte nasıl çalışıyor
Diff karakter düzeyinde çalışır, ardından semantik bir son işleme geçişi vurguları token ortasındaki gürültüye değil, anahtarların, değerlerin ve yorum satırlarının tamamına denk gelecek şekilde kaydırır. Eklemeler sağ panelde yeşil, silmeler solda kırmızı görünür. Her başlıktaki değişiklik sayacı algoritmanın bulduğu farklı düzenleme sayısını gösterir.
Yapılandırma formatları tek bir parser'ın hepsine yetmesine izin vermeyecek kadar farklılaştığı için bu araç bilinçli olarak format-bağımsız kalır. .env en gevşek olanıdır: çoğu loader sağ tarafın tamamını string olarak ele alır ama bazıları $VAR genişletir, bazıları genişletmez, bazıları export'a saygı gösterir ve boşluklu değerlerin tırnaklanması parser'a özgüdür. .properties dosyaları (java.util.Properties API'da belgelenen Java standardı) ayırıcı olarak = veya : kabul eder ve ASCII dışı karakterler için \u00e9 gibi Unicode escape'leri ister. Vahşi doğadaki INI dosyaları, Windows alışkanlığından (köşeli parantezde bölümler, yorumlar için noktalı virgül) Python'un configparser modülünün kabul ettiği biraz farklı lehçeye kadar uzanır.
Temiz bir diff'e güvenmeden önce bilmek gereken üç gerçek tuzak. Birincisi, sondaki boşluk. API_KEY=abc gibi bir değerin satır sonunda kaçak bir boşluğu olması çoğu loader için farklı bir string demektir; diff bunu işaretler ama insanlar suçlu boşluğu nadiren görür. İkincisi, satır sonları. Windows'ta CRLF ile commit edilen ve Linux'ta LF ile yazılan bir dosya aynı içerikle diff'lenir ama her satır değişmiş gibi görünür; iki tarafı da formatlayın veya satır sonlarını önce normalize edin. Üçüncüsü, UTF-8 byte order mark. Windows'taki Notepad kaydedilen bir .env'nin başına hâlâ neşeyle BOM yazar; çoğu loader takılır ve bu, 1. satırda tek karakterlik bir hayalet diff olarak görünür.
Config dosyalarını üç adımda karşılaştırın
İki metin paneli, tek diff. Hiçbir şey yüklenmez. Hiçbir şey loglanmaz.
- 1
Configinizi yapıştırın veya yükleyin
Eski configi sola, yenisini sağa yapıştırın. Veya iki taraftan birinde Upload'a tıklayarak doğrudan bir .env, .toml, .ini, .properties veya .conf dosyası yükleyin. Sample butonu iki paneli küçük bir .env örneğiyle doldurur, böylece kendi dosyanızı yapıştırmadan önce değer değişikliklerinin, yeni anahtarların ve kaldırılmış girdilerin nasıl render edildiğini görebilirsiniz.
- 2
Formatlayın ve normalize edin
Sondaki boşluğu kırpmak ve tutarlı satır sonları uygulamak için her panelde Format'a tıklayın. Bu, en yaygın yanlış pozitif sınıfını öldürür: aynı görünen ama biri CRLF, diğeri LF ile kaydedildiği için tamamen farklı diff'lenen iki dosya. İki taraf boşluk konusunda anlaştıktan sonra diff gerçek anahtar ve değer değişikliklerine odaklanır.
- 3
Diff'i okuyun
Silmeler solda kırmızı vurgu ile, eklemeler sağda yeşil vurgu ile görünür. Bir tarafı kaydırırsanız diğeri takip eder. Yorumlar ve yorum satırı yapılmış anahtarlar sıradan metin gibi diff'lenir, bu yüzden başına # koyarak kaldırdığınız bir anahtar, silinen anahtar olarak değil eklenen yorum satırı olarak görünür.
Config diff'in doğru araç olduğu durumlar
Local ile staging arasında .env dosyalarını diff'lemek
Lokalde bir feature branch açıyorsunuz, gayet iyi çalışıyor, sonra staging'in .env'inde STRIPE_WEBHOOK_SECRET eksik olduğu için staging'de çöküyor. Çalışan lokal dosyayı staging'inkine karşı yapıştırın; eksik anahtar, değişmiş DATABASE_URL host'u ve eski LOG_LEVEL=debug tek geçişte yüze çıkar. İki dosyayı satır satır gezmekten daha hızlı ve iki değişken kümesini terminale yazdıran bir script çalıştırmaktan çok daha güvenli.
Bir bağımlılık yükseltmesinden sonra pyproject.toml'u karşılaştırmak
Poetry veya uv, poetry update'ten sonra az önce pyproject.toml'unuzu yeniden yazdı. Önceki commit edilmiş sürümü working tree ile diff'leyerek gerçek yükseltmeleri doğrulayın: fastapi 0.110.0'dan 0.115.4'e geçti, yeni bir [tool.ruff.lint] tablosu çıktı ve build-system.requires pin'i kaydı. TOML 1.0 spec diff'in genelde temiz ve okunabilir olması için yeterince sıkı.
Reload öncesi nginx.conf değişikliklerini gözden geçirmek
Bozuk bir configle nginx'i reload etmek bir production sitesini bir sunucudaki neredeyse her şeyden hızlı düşürür. nginx -s reload'dan önce çalışan nginx.conf'u önerilenle yapıştırıp karşılaştırın ve değişikliğin tam olarak istediğiniz şey olduğunu doğrulayın: yeni bir upstream bloğu, güncellenmiş bir proxy_pass hedefi, bir TLS cipher suite değişikliği. Diff yanlışlıkla atlanmış noktalı virgülü her seferinde yakalar.
Bir systemd unit'ini veya supervisord configini denetlemek
Bir servis bir deploy'dan sonra döngüde yeniden başlıyor. Çalışan foo.service'i yenisiyle diff'leyin; nedeni genelde otuz saniye içinde bulursunuz: değişmiş bir ExecStart, düşmüş bir Environment= satırı, sıkıştırılmış bir NoNewPrivileges. Aynı akış supervisord .conf blokları, runit run-script'leri ve eski makinalarda hâlâ gördüğünüz çeşitli .ini tarzı init configleri için de geçerli.
Infrastructure-as-code config dosyalarını karşılaştırmak
terraform.tfvars içindeki Terraform değişkenleri, Pulumi stack configleri, Ansible group_vars'ı, Kubernetes ConfigMap'leri için Helm değerleri. Her ortamın kendi kopyası var ve onları birleştirmenin tek güvenli yolu diff. Prod'u staging'e karşı yapıştırın; drift gözünüze çarpar: birinde us-east-1'e, diğerinde us-west-2'ye sabitlenmiş bir region, biri bir incident sırasında yükseltip hiç geri almadığı bir instance type, yanlış hesaba işaret eden bir IAM role ARN.
Bir CI environment dosyasının belgelenen şablona uyduğunu kontrol etmek
Yeni bir mühendis geliyor, repo'dan .env.example'ı kopyalıyor ve şablon CI pipeline'ının gerçekten beklediğinden saptığı için ilk PR'sinde build hâlâ başarısız oluyor. Commit edilmiş .env.example'ı build'leri geçen birinin bilinen-iyi .env'siyle diff'leyin; eksik anahtarlar solda kırmızı veya sağda yeşil olarak çıkar. Aynı numara Taskfile env blokları, GitHub Actions env: bölümleri ve direnv .envrc dosyaları için de işe yarar.
Config formatı hızlı referansı
Bu aracın en sık gördüğü formatlar üzerine kısa bir kopya kâğıdı. Yapılandırma, ününün ima ettiğinden daha dağınıktır ve aşağıdaki farklar çoğu diff'in raydan çıktığı yerlerdir.
| Topic | What this tool does |
|---|
| Format lehçeleri | INI (formal spec yok, parser başına lehçeler), TOML 1.0 (sıkı, tipli), .env (spec yok, parser tanımlı), .properties (Java, bkz. java.util.Properties), .conf (uygulama başına: nginx, Apache, sshd_config hepsi farklı). |
|---|
| Yorum karakterleri | INI: ; veya #. TOML: yalnızca #. .env: yalnızca #, çoğu loader'da yalnızca satır başında. .properties: # veya !. nginx .conf: yalnızca #. |
|---|
| Bölüm başlıkları | INI ve TOML [section] kullanır. TOML [a.b.c] ile iç içe tablolar, [[a]] ile tablo dizileri ekler. .env ve .properties düzdür, bölüm yoktur. nginx başlıklar yerine { ... } blokları kullanır. |
|---|
| Değer tipleri | TOML'un tipli değerleri var: stringler, intler, floatlar, bool'lar, tarihler, diziler, tablolar. INI, .env ve .properties yalnızca string'dir; true veya 42'nin nasıl parse edileceğine uygulama karar verir. |
|---|
| Interpolasyon ve genişletme | Çoğu dotenv loader'ı $VAR'ı varsayılan olarak genişletmez. Bazıları genişletir (dotenv-expand, direnv, source .env üzerinden kabuk sourcing). TOML asla genişletmez. INI nadiren; Python'un configparser'ı opt-in ederseniz ${section:key}'i destekler. |
|---|
| Sondaki boşluk | Gerçek bir bug kaynağı. Sonunda boşluk olan FOO=bar çoğu loader'da FOO'yu "bar " yapar, bu da downstream string eşitlik kontrollerini başarısız kılar. Her zaman kırpın veya tırnaklayın. |
|---|
| Satır sonları | CRLF (Windows) ve LF (Unix). Farklı OS'lerde kaydedilen iki özdeş dosya her-satır-değişti olarak diff'lenir. Diff'lemeden önce Format butonunu kullanın veya satır sonlarını normalize edin (dos2unix, git config core.autocrlf). |
|---|
| Encoding ve BOM | TOML UTF-8'i zorunlu kılar. .properties tarihsel olarak \uXXXX escape'leri ile ISO-8859-1 gerektiriyordu ama modern Java Properties.load(Reader) üzerinden UTF-8'i kabul eder. .env'nin başındaki UTF-8 BOM klasik bir hayalet diff sebebidir; Windows'taki Notepad varsayılan olarak hâlâ yazıyor. |
|---|
Config diff: sık sorulan sorular
Araç değer tiplerini anlıyor mu?
Hayır. Bu bir metin diff'i. TOML stringleri, integerları, floatları, boolean'ları, tarihleri ve dizileri ayırt eder ama diff her satırı düz metin olarak ele alır ve hangi karakterlerin değiştiğini gösterir. Yapılandırma değişiklikleri zaten karakter değişiklikleri olduğu için bu genelde yeterlidir. Gerçekten tipli bir karşılaştırma gerekiyorsa, dilerseniz tercih ettiğiniz dilde her iki dosyayı parse edin (Python'un tomllib'i, Rust'un toml crate'i, Go'nun pelletier/go-toml'u) ve elde edilen mapleri karşılaştırın. %95'lik vakada metin diff'i yakalamanız gerekeni yakalar.
"Farklı görünen" ama eşdeğer yorum satırlarıyla nasıl başa çıkarım?
Genelde başa çıkmazsınız ve aracın bunu işaretlemiş olmasına memnun olmalısınız. API_KEY=abc'den #API_KEY=abc'ye geçen bir satır anlamsal olarak önemlidir: anahtar artık devre dışı. Diff yorum öneki değişikliğini vurgular, ki bir config incelemesi sırasında insan reviewer'ın görmesi gereken tam olarak budur. Yorum gürültüsünü gerçekten görmezden gelmek istiyorsanız, yapıştırmadan önce iki tarafı yalnızca yorum olan satırları atacak şekilde formatlayın ama güvenlik açısından hassas bir dosya için bu nadiren doğru hamledir.
Bir tarafta bir anahtarın eksik olup olmadığını nasıl kontrol ederim?
İki dosyayı yapıştırın, diff'i çalıştırın; bir tarafta var olup diğer tarafta olmayan herhangi bir anahtar tüm satırın kırmızı silmesi veya yeşil eklemesi olarak görünür. Diff anahtarları yapısal olarak hizalamaya çalışmaz, bu yüzden farklı bir konuma yeniden sıralanan bir anahtar bir kez silme, bir kez ekleme olarak görünür. Sırayla ilgisi olmayan tam karşılaştırma için önce iki dosyayı anahtara göre sıralayın (Unix'te sort .env) ve sonra diff'leyin. Format-bağımsız yaklaşım eksik anahtarları bir parser'a ihtiyaç duymadan yakalar.
Gerçek secret içeren .env dosyalarını yapıştırmak güvenli mi?
Evet, girdiniz tarayıcıyı asla terk etmez. Diff tamamen istemcide çalışır. Sunucuya yükleme yok, panel içerikleri üzerinde telemetri yok, yazdıklarınızı yakalayan analitik yok. Bu kasıtlı çünkü .env diff'leri bu sitedeki en yüksek güven gerektiren akışlardan biridir. Paranoyaksanız (ki biraz olmalısınız), tarayıcı devtools'u açın ve yapıştırırken network sekmesinin boş kaldığını doğrulayın. Tamamen air-gapped bir araç tercih eden organizasyonlar için: siteyi bir kez offline açın; cache'lenmiş varlıklar daha fazla ağ erişimi olmadan çalışır.
TOML ile INI arasındaki fark nedir?
INI bir alışkanlık; TOML bir spesifikasyondur. INI Windows'ta büyüdü, formal bir grameri yok ve her parser sınır durumlarını (tırnaklama, escape'ler, liste değerleri, iç içe bölümler) biraz farklı işler. TOML 1.0 Cargo, Poetry, Hugo ve giderek pyproject.toml üzerinden Python paketlemesi tarafından kullanılan sıkı, sürümlenmiş bir spec'tir. İkisi de [section] başlıkları ve key = value çiftleri kullanır, bu yüzden ilk bakışta benzer görünür ama TOML klasik INI dosyalarında olmayan tipli değerler, datetime literal'ları ve inline tablolar ekler.
Diff anahtar büyük/küçük harfini veya boşluğu normalize ediyor mu?
Hayır. API_KEY=abc ve api_key=abc diff için farklı satırlardır çünkü farklı byte'lardır. Çoğu loader da büyük/küçük harfe duyarlıdır (dotenv, java.util.Properties, varsayılan configparser), bu yüzden bu gerçeklikle örtüşür. = etrafındaki boşluk olduğu gibi korunur, bu da önemli çünkü daha katı bazı parser'lar (özellikle bazı Bash sourcing kalıpları) boşluklu FOO = bar'ı reddedip yalnızca FOO=bar'ı kabul eder. Format butonu her satırda sondaki boşluğu kırpar, uyguladığı tek normalleştirme adımı budur.
Gizlilik ve bunun nasıl çalıştığı
Yapılandırma dosyalarınız tarayıcınızdan asla çıkmaz. Diff, formatlayıcı ve girdinizin her byte\'ı yerel olarak makinenizde kalır. Panel içerikleri üzerinde analitik yok, log yok, yükleme yok. Bu, çoğu diff aracında olduğundan daha çok burada önemli çünkü .env dosyaları rutin olarak veritabanı parolaları, API anahtarları ve OAuth client secret\'leri içerir; bunları sunucu üzerinden gidip gelen bir araca yapıştırmak gerçek bir güvenlik olayı olur. Formatlar üzerine arka plan okuması: TOML 1.0, INI dosyaları ve Unix\'in ortam değişkenleri kavramı. Hiçbir dosyada yaşamaması gereken secret\'lar için sops, HashiCorp Vault veya AWS Parameter Store\'a bakın.