3 पॉइंट द्वारा GN⁺ 2024-03-22 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • 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 के उदाहरण इस प्रकार हैं
  • समर्थित file formats के उदाहरण इस प्रकार हैं
  • इसे Git के साथ इस्तेमाल किया जा सकता है, और manual में Git configuration की गाइड उपलब्ध है
  • Difftastic MIT License के तहत जारी है, इसलिए इसे download, modify और share किया जा सकता है

1 टिप्पणियां

 
GN⁺ 2024-03-22
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 कर सकते हैं, जो वाकई कमाल है

    • पूरी तरह सहमत हूं, और पिछले साल लिखी अपनी comment को फिर से लाते हुए कहूंगा कि tree-sitter का dependency-free architecture भी खास तौर पर उल्लेखनीय है
      संदर्भ के लिए, हमारी 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 ast module से 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 पर बने हैं
    • मैं सहमत हूं कि tree-sitter एक शानदार tool है, लेकिन सीधे grammar लिखना बेहद मुश्किल हो सकता है
      मैंने VHDL के लिए tree-sitter grammar और highlighting queries का set लिखा है, और VHDL grammar को tree-sitter में express करने में काफी दिक्कतें आईं
    • मुझे लगता है यह explanation सही नहीं है। tree-sitter बोलना जैसी कोई common interface नहीं है, और हर tree-sitter parser standard abstract syntax tree के बजाय अलग-अलग concrete syntax tree output करता है
      LSP query-oriented compilers के लिए standard interface इस्तेमाल करके M editors और N languages के बीच जरूरी M×N integration problem को सच में solve करता है
      tree-sitter उस problem को solve करने के बजाय editors या tools में N integrations लिखने का काम बहुत आसान बना देता है
    • tree-sitter में जो बात सबसे खटकती है, वह यह है कि जिन कई languages में मेरी रुचि है, उनमें यह approach काम नहीं करती
      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 कर सकें
    • क्या English जैसी natural languages के लिए tree-sitter grammar बनाकर हर sentence को एक sentence unit के रूप में label किया जा सकता है?
      तब difftastic से visual lines के बजाय sentences के आधार पर changes दिखाए जा सकेंगे
      essays में visual line-based diff अजीब लगता है। आम तौर पर बदला हुआ sentence visual line के बीच से शुरू होता है
  • अगर आपने cargo से install किया है, तो difftastic और संबंधित tools update करने का तरीका यह है
    cargo install cargo-update
    cargo install-update --list
    cargo install-update --all
    cargo से install किए जा सकने वाले कुछ दिलचस्प Rust projects भी हैं
    https://mise.jdx.dev/ mise-en-place, https://asdf-vm.com/ का तेज और flexible alternative है
    https://github.com/ajeetdsouza/zoxide एक बेहतरीन cd replacement tool है, जो आपके गए हुए locations save रखता है और "z hel" जैसे partial match से "~/projects/helloworld" तक ले जा सकता है
    https://github.com/bootandy/dust du को complement करने वाला tool है, जो दिखाता है कि कौन-सी directories ज्यादा disk space इस्तेमाल कर रही हैं

    • तीन और साफ-सुथरे tools की बात करें तो https://github.com/eza-community/eza visually ज्यादा अच्छा ls है, https://github.com/ClementTsang/bottom graphs वाला htop है, और https://github.com/sharkdp/bat syntax highlighting वाला cat है
    • मुझे zoxide वाकई बहुत पसंद है। इस list में lsd भी जोड़ने लायक है। यह ज्यादा सुंदर ls है
    • मैंने mise-en-place install करके देखा, और यह ठीक वैसा ही है जैसा मैं चाहता था कि asdf बने
    • नए du-जैसे tools में मुझे dua-cli सबसे ज्यादा पसंद है। यह ncdu का clone जैसा interactive terminal UI है
      ncdu में light mode नहीं था, इसलिए खोजते-खोजते यह मिला
    • ncdu निस्संदेह सबसे अच्छा du replacement tool है
  • यह बात लगभग समझ नहीं आती कि git जैसे टूल इसे default में क्यों नहीं देते
    मैं लगभग 1 साल से difft इस्तेमाल कर रहा हूँ, और सबसे बड़ी शिकायत यह है कि यह मुझे ऐसे environment में किसी दूसरे diff टूल पर वापस जाना मुश्किल बना देता है जहाँ difft नहीं है
    यह भी जानना चाहूँगा कि semantic diff टूल्स पर कोई research हुई है या नहीं। जैसे ऐसे मामले जहाँ syntax बदल गया हो लेकिन meaning वही हो
    सामान्य problem के तौर पर यह कठिन लगती है, लेकिन छोटे DSL या कुछ languages के subset में यह संभव या उपयोगी हो सकता है

    • default के तौर पर पुराना diff इस्तेमाल करना सही लगता है
      git चलाने वाले लगभग हर system में यह पहले से होता है, तेज़ है, छोटा है, और हर कोई इसकी basic usage जानता है
      फिर भी अच्छा है कि उस default को आसानी से बदला जा सकता है
    • मैं https://semanticdiff.com/ बना रहा हूँ, जो decimal literal को hexadecimal में बदलने या JSON object के अंदर keys का order बदलने जैसी basic semantic changes detect करता है
      यह command-line utility नहीं है, बल्कि VS Code extension और GitHub App है
      अगर जानना हो कि यह कैसे काम करता है और difftastic से कैसे अलग है, तो https://semanticdiff.com/blog/semanticdiff-vs-difftastic/ देख सकते हैं
    • Difftastic उपयोगी टूल है, लेकिन मेरे अनुभव में git जैसे व्यापक रूप से इस्तेमाल होने वाले टूल का default option बनने के लिए यह बहुत धीमा है
    • ऐसा करने के लिए diff टूल असल में compiler बन जाता है
    • अभी मैं git के साथ difft जोड़कर इस्तेमाल कर रहा हूँ और यह काफी पसंद आ रहा है
      फिर भी इसे default नहीं होना चाहिए, इसकी एक वजह यह है कि यह whitespace differences छिपा देता है। यह configurable है या नहीं, अभी मैंने जाँचा नहीं है
  • @@ -5,6 +5,7 @@ syntax पढ़ना आता है या नहीं, यह पूछने और Difftastic के बदलाव से पहले/बाद की files के वास्तविक line numbers दिखाने वाली explanation से पूरी तरह सहमत हूँ
    मैंने तुरंत इसे जोड़ा और git diff चलाकर देखा, और यह बहुत अच्छे से काम करता है

    • क्या लोग वह syntax नहीं पढ़ पाते?
  • GitHub ने ऐसा कुछ नहीं निकाला है, यह product innovation में एक बड़ा gap लगता है
    सिर्फ indentation बदलने पर भी मदद करने वाली कोई feature नहीं है, और आम तौर पर इसे बड़े deletion और addition के रूप में दिखाता है
    GitHub का diff viewer और smart हो सकता है और होना भी चाहिए

    • GitHub तो semantic diff छोड़िए, syntax awareness भी ठीक से नहीं कर पाता
      असल में यह foo.cpp.in और foo.mk.in के अलग होने तक को अलग नहीं पहचान पाता
      कोई भी foo.t Perl घोषित कर दिया जाता है और इसे ठीक करने का कोई तरीका भी नहीं है। 10 साल पुराना ticket भी मौजूद है
    • tree-sitter accuracy के लिए नहीं, बल्कि editor में इस्तेमाल के लिए performance के हिसाब से optimized है
      असल में TS के core developers भी सलाह देते हैं कि grammar की accuracy को लेकर बहुत चिंता न करें[1]
      GitHub या ऐसी स्थिति वाली services के लिए यह constraint गंभीर हो सकता है
      [1] https://github.com/tree-sitter/tree-sitter/issues/130#issuec...
    • GitHub में diff में whitespace ignore करने का option है
  • मैंने इस टूल पर 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

    • GitHub README के मुताबिक difftastic merge नहीं करता
      AST merge एक कठिन problem है और difftastic उसे handle नहीं करता
      साथ ही AST diff, text diff के नजरिए से एक lossy process है। difftastic syntax की दृष्टि से meaningless whitespace को ignore करता है, लेकिन merge के लिए whitespace tracking चाहिए
    • मैं भी Semantic Merge recommend करने वाला था
      जब बड़ी 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 करने का तरीका नहीं मिला
    जानना चाहूँगा कि क्या किसी को तरीका पता है

    • अफसोस, लगता है अभी color customization support नहीं है
      मैंने इस 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 भी हो सकती है

    • Compression की बात निकली तो जिज्ञासा में जांचा, btrfs zstd:1 पर यह लगभग 10MB है
      Processed 1 file, 614 regular extents (614 refs), 0 inline.
      Type Perc Disk Usage Uncompressed Referenced
      TOTAL 14% 10M 77M 77M
      none 100% 1.1M 1.1M 1.1M
      zstd 12% 9.8M 76M 76M
    • शायद इसका संबंध उस comment से है जिसमें कहा गया था कि Nim parser merge न हो सकने वाली 60MB की C file है
      लगता है Tree-sitter को बहुत ज्यादा code चाहिए, और उसका काफी हिस्सा duplicated या compressible लगता है
    • Executable file को शुरू होने से पहले पूरा का पूरा RAM में load नहीं किया जाता
      उसे memory-map किया जाता है और असल में इस्तेमाल होने वाले हिस्से ही जरूरत पड़ने पर load होते हैं
      इसलिए बड़ी binary को compress करने से demand paging काम नहीं करती और उल्टा यह धीमी हो जाती है
      कुछ साल पहले 280MB के Windows EXE पर test किया था; वह करीब 70MB तक compress तो हो गया, लेकिन original की तुलना में start होने में कुछ सेकंड ज्यादा लगे
      कुछ scenarios, जैसे network के पार binary चलाना, में यह समझ में आ सकता है, लेकिन ज्यादातर मामलों में uncompressed binary ज्यादा तेजी से start होती है