Syntax को समझने वाला संरचनात्मक अंतर विश्लेषण टूल Difftastic
(difftastic.wilfred.me.uk)- Difftastic एक CLI diff टूल है जो फाइलों की तुलना लाइन-दर-लाइन नहीं, बल्कि कोड की syntax structure के आधार पर करता है
- अंदरूनी तौर पर यह tree-sitter से कोड parse करता है, इसलिए formatting के कारण लाइनें बदल जाने पर भी वास्तव में बदले हुए expressions को बेहतर तरीके से अलग पहचानता है
- अगर code formatter आइटम्स को कई लाइनों में बांट दे या कोई wrapper जोड़ा गया हो, तब भी यह बदली हुई structure और जस की तस बची अंदरूनी सामग्री को अलग-अलग दिखा सकता है
- Git configuration गाइड और installation docs उपलब्ध हैं, और यह कई programming languages तथा JSON·YAML जैसे structured text formats को support करता है
- MIT License के तहत जारी होने की वजह से इसे download, modify और share किया जा सकता है, और यह मौजूदा diff workflow में structural comparison जोड़ने के लिए उपयुक्त है
लाइनों की बजाय syntax structure की तुलना करता है
- Difftastic एक CLI diff टूल है जो फाइलों की तुलना syntax के आधार पर करता है
- यह सामान्य line-based diff की तुलना में code structure को समझकर परिणाम दिखाने पर focus करता है
- कोड को tree-sitter से parse किया जाता है
- line-focused diff में जो internal expressions बदले हुए लग सकते हैं, उनके वास्तव में बदले होने या न होने को यह अलग पहचान सकता है
- code formatter द्वारा code को कई लाइनों में बांट देने की स्थिति में भी यह वास्तविक बदलाव दिखा सकता है
- wrapper जोड़े जाने पर यह delimiters को सही तरह match करता है
- अंदरूनी content साथ में बदलने पर भी जोड़ा गया wrapper दिखाया जा सकता है
@@ -5,6 +5,7 @@जैसी diff hunk syntax की बजाय, यह बदलाव से पहले और बाद वाली files के वास्तविक line numbers दिखाता है
समर्थित भाषाएं और Git integration
- Project सामग्री GitHub, Manual, Install पर उपलब्ध है
- समर्थित programming languages के उदाहरण इस प्रकार हैं
- C++, C#, Clojure, Dart, Erlang, Go, Haskell, Java, JavaScript, Kotlin, Lisp, Lua, OCaml, PHP, Python, R, Ruby, Rust, Scala, TypeScript
- पूरी सूची manual की समर्थित भाषाओं की सूची में देखी जा सकती है
- समर्थित file formats के उदाहरण इस प्रकार हैं
- HCL, HTML, JSON, YAML
- पूरी सूची manual की structured text formats की सूची में देखी जा सकती है
- इसे Git के साथ इस्तेमाल किया जा सकता है, और manual में Git configuration की गाइड उपलब्ध है
- Difftastic MIT License के तहत जारी है, इसलिए इसे download, modify और share किया जा सकता है
1 टिप्पणियां
Hacker News की रायें
कुछ लोगों को शायद पहले से पता होगा, लेकिन यह टूल tree-sitter(https://tree-sitter.github.io/tree-sitter/) पर बना है, और एक तरह से parsing के लिए वही करता है जो LSP ने analysis के लिए किया
यह code को abstract syntax tree(AST) में बदलता है, और उस AST को editor या diff tool जैसे clients के इस्तेमाल के लिए एक standard interface देता है
ऐसे tool को दर्जनों languages को सीधे support करने की जरूरत नहीं होती; अगर वह बस tree-sitter को support करे, तो tree-sitter द्वारा support की जाने वाली सभी languages में अपने-आप काम कर सकता है
अगर आप कोई नई language develop कर रहे हैं, तो tree-sitter parser बना सकते हैं, और फिर tree-sitter से काम करने वाले सभी tools उस language को support कर पाएंगे
इन दो बड़े innovations की वजह से ऐसे tools में improvements बहुत तेजी से बढ़ रहे हैं। अब editors, diff tools आदि एक ही काम बार-बार किए बिना दर्जनों से सैकड़ों languages support कर सकते हैं, जो वाकई कमाल है
संदर्भ के लिए, हमारी team के कुछ लोग OCaml tree-sitter bindings maintain करते हैं, और Semgrep पर काम के हिस्से के रूप में grammars में भी अक्सर contribute करते हैं। Semgrep code search और उन queries को AST matcher में parse करने के लिए tree-sitter इस्तेमाल करता है, जो खुद code snippets होती हैं
linter बनाते समय अक्सर target language का runtime साथ लाना पड़ता है। उदाहरण के लिए, Python में built-in
astmodule से parser बनाने पर language version और features match करने पड़ते हैं, इसलिए Python 2.7 पर चलने वाले Pylint से Python 3 code parse नहीं किया जा सकताकई languages को target करने पर यह शुरुआत में सोचे गए से कहीं ज्यादा झंझट भरा हो जाता है
tree-sitter से पहले, अक्सर language के built-in AST tools इस्तेमाल करना ही सबसे अच्छा विकल्प होता था, क्योंकि इससे latest syntax के साथ बने रहने की गारंटी मिलती थी
निजी तौर पर, मेरे हिसाब से tree-sitter की असली प्रतिभा यह है कि इसने traditional grammar approaches की तुलना में language parsers को up-to-date रखना काफी आसान बना दिया
अगर आप tree-sitter के design choices के बारे में और जानना चाहते हैं, तो Max Brunsfield की Strange Loop talk की जोरदार सिफारिश करूंगा: https://www.youtube.com/watch?v=Jes3bD6P0To
नतीजतन difftastic के अलावा neovim, Zed, Semgrep, GitHub code search जैसे कई नए tools tree-sitter पर बने हैं
मैंने VHDL के लिए tree-sitter grammar और highlighting queries का set लिखा है, और VHDL grammar को tree-sitter में express करने में काफी दिक्कतें आईं
LSP query-oriented compilers के लिए standard interface इस्तेमाल करके M editors और N languages के बीच जरूरी M×N integration problem को सच में solve करता है
tree-sitter उस problem को solve करने के बजाय editors या tools में N integrations लिखने का काम बहुत आसान बना देता है
Common Lisp को complete Lisp implementation के बिना parse नहीं किया जा सकता, Haskell grammar इतनी complex है कि grammar अधूरी है, C/C++ को सिर्फ preprocessor देखकर भी ठीक-ठीक parse करना मुश्किल है, और Perl parsing Turing-complete है
जैसा कि कहीं और सुझाया गया है, नए ecosystem में parser फिर से लिखवाने के बजाय, ऐसा format define करना बेहतर लगता है जिसे existing parsers additional output के रूप में generate कर सकें
तब difftastic से visual lines के बजाय sentences के आधार पर changes दिखाए जा सकेंगे
essays में visual line-based diff अजीब लगता है। आम तौर पर बदला हुआ sentence visual line के बीच से शुरू होता है
अगर आपने cargo से install किया है, तो difftastic और संबंधित tools update करने का तरीका यह है
cargo install cargo-updatecargo install-update --listcargo install-update --allcargo से install किए जा सकने वाले कुछ दिलचस्प Rust projects भी हैं
https://mise.jdx.dev/ mise-en-place, https://asdf-vm.com/ का तेज और flexible alternative है
https://github.com/ajeetdsouza/zoxide एक बेहतरीन
cdreplacement tool है, जो आपके गए हुए locations save रखता है और"z hel"जैसे partial match से"~/projects/helloworld"तक ले जा सकता हैhttps://github.com/bootandy/dust
duको complement करने वाला tool है, जो दिखाता है कि कौन-सी directories ज्यादा disk space इस्तेमाल कर रही हैंlsहै, https://github.com/ClementTsang/bottom graphs वालाhtopहै, और https://github.com/sharkdp/bat syntax highlighting वालाcatहैlsहैdu-जैसे tools में मुझे dua-cli सबसे ज्यादा पसंद है। यहncduका clone जैसा interactive terminal UI हैncduमें light mode नहीं था, इसलिए खोजते-खोजते यह मिलाncduनिस्संदेह सबसे अच्छाdureplacement tool हैयह बात लगभग समझ नहीं आती कि git जैसे टूल इसे default में क्यों नहीं देते
मैं लगभग 1 साल से difft इस्तेमाल कर रहा हूँ, और सबसे बड़ी शिकायत यह है कि यह मुझे ऐसे environment में किसी दूसरे diff टूल पर वापस जाना मुश्किल बना देता है जहाँ difft नहीं है
यह भी जानना चाहूँगा कि semantic diff टूल्स पर कोई research हुई है या नहीं। जैसे ऐसे मामले जहाँ syntax बदल गया हो लेकिन meaning वही हो
सामान्य problem के तौर पर यह कठिन लगती है, लेकिन छोटे DSL या कुछ languages के subset में यह संभव या उपयोगी हो सकता है
diffइस्तेमाल करना सही लगता हैgit चलाने वाले लगभग हर system में यह पहले से होता है, तेज़ है, छोटा है, और हर कोई इसकी basic usage जानता है
फिर भी अच्छा है कि उस default को आसानी से बदला जा सकता है
यह command-line utility नहीं है, बल्कि VS Code extension और GitHub App है
अगर जानना हो कि यह कैसे काम करता है और difftastic से कैसे अलग है, तो https://semanticdiff.com/blog/semanticdiff-vs-difftastic/ देख सकते हैं
फिर भी इसे default नहीं होना चाहिए, इसकी एक वजह यह है कि यह whitespace differences छिपा देता है। यह configurable है या नहीं, अभी मैंने जाँचा नहीं है
@@ -5,6 +5,7 @@syntax पढ़ना आता है या नहीं, यह पूछने और Difftastic के बदलाव से पहले/बाद की files के वास्तविक line numbers दिखाने वाली explanation से पूरी तरह सहमत हूँमैंने तुरंत इसे जोड़ा और
git diffचलाकर देखा, और यह बहुत अच्छे से काम करता हैGitHub ने ऐसा कुछ नहीं निकाला है, यह product innovation में एक बड़ा gap लगता है
सिर्फ indentation बदलने पर भी मदद करने वाली कोई feature नहीं है, और आम तौर पर इसे बड़े deletion और addition के रूप में दिखाता है
GitHub का diff viewer और smart हो सकता है और होना भी चाहिए
असल में यह
foo.cpp.inऔरfoo.mk.inके अलग होने तक को अलग नहीं पहचान पाताकोई भी
foo.tPerl घोषित कर दिया जाता है और इसे ठीक करने का कोई तरीका भी नहीं है। 10 साल पुराना ticket भी मौजूद हैअसल में TS के core developers भी सलाह देते हैं कि grammar की accuracy को लेकर बहुत चिंता न करें[1]
GitHub या ऐसी स्थिति वाली services के लिए यह constraint गंभीर हो सकता है
[1] https://github.com/tree-sitter/tree-sitter/issues/130#issuec...
मैंने इस टूल पर switch करने की कोशिश की, लेकिन unchanged parts में भी अजीब formatting लगाई गई थी, इसलिए यह बहुत शोर-शराबे वाला लगा
आखिरकार मैं icdiff[0] पर वापस चला गया
[0]: https://github.com/jeffkaufman/icdiff
पहले Semantic Merge[1] मिला था, लेकिन वह open source नहीं था
यह merge नहीं करता, सिर्फ diff करता है, लेकिन कम से कम open source है और diff कहीं ज्यादा readable है, इसलिए मैंने इसे पहले ही default बना लिया है
जानना चाहूँगा कि इसे merge feature तक expand करने की कोई योजना है या नहीं
[1] https://docs.plasticscm.com/semanticmerge
AST merge एक कठिन problem है और difftastic उसे handle नहीं करता
साथ ही AST diff, text diff के नजरिए से एक lossy process है। difftastic syntax की दृष्टि से meaningless whitespace को ignore करता है, लेकिन merge के लिए whitespace tracking चाहिए
जब बड़ी team में C# project की messy refactoring कर रहा था, तब यह सच में lifesaver जैसा tool था
पिछली चर्चाएँ:
https://news.ycombinator.com/item?id=27768861 (297 points | 3 years ago | 61 comments)
https://news.ycombinator.com/item?id=32746258 (698 points | 2 years ago | 90 comments)
https://news.ycombinator.com/item?id=30841244 (983 points | 2 years ago | 219 comments)
शानदार टूल लगता है, लेकिन कुछ बड़ी XML files पर जाँचने पर modified lines सामान्य हरे रंग में और modified attributes bold green में दिखे, इसलिए visual distinction करना मुश्किल था
docs में diff style बदलने या bold case में अलग color set करने का तरीका नहीं मिला
जानना चाहूँगा कि क्या किसी को तरीका पता है
मैंने इस feature के समर्थन में इस issue[1] पर comment किया है
अगर आपकी desired feature उसी category में आती है, तो वहाँ अपनी राय जोड़ सकते हैं; और अगर आपको लगता है कि यह काफी अलग feature है, तो नया issue खोल सकते हैं
[1]: https://github.com/Wilfred/difftastic/issues/611
यह दिलचस्प है कि Arch Linux पैकेज 7MB का है, लेकिन इंस्टॉल होने के बाद 80MB तक फैल जाता है, और सिर्फ
difftबाइनरी ही 78MB की हैLZ4 compression चालू किए हुए ZFS dataset पर
duइसे 17MB बताता हैमुझे उत्सुकता है कि बाइनरी के अंदर जो चीज इतनी अच्छी तरह compress हो जाती है, उसे बस compressed क्यों नहीं रखा जाता। RAM में decompress करने पर शायद यह और तेजी से load भी हो सकती है
Processed 1 file, 614 regular extents (614 refs), 0 inline.Type Perc Disk Usage Uncompressed ReferencedTOTAL 14% 10M 77M 77Mnone 100% 1.1M 1.1M 1.1Mzstd 12% 9.8M 76M 76Mलगता है Tree-sitter को बहुत ज्यादा code चाहिए, और उसका काफी हिस्सा duplicated या compressible लगता है
उसे memory-map किया जाता है और असल में इस्तेमाल होने वाले हिस्से ही जरूरत पड़ने पर load होते हैं
इसलिए बड़ी binary को compress करने से demand paging काम नहीं करती और उल्टा यह धीमी हो जाती है
कुछ साल पहले 280MB के Windows EXE पर test किया था; वह करीब 70MB तक compress तो हो गया, लेकिन original की तुलना में start होने में कुछ सेकंड ज्यादा लगे
कुछ scenarios, जैसे network के पार binary चलाना, में यह समझ में आ सकता है, लेकिन ज्यादातर मामलों में uncompressed binary ज्यादा तेजी से start होती है