Jujutsu - सरल और शक्तिशाली Git-संगत वितरित version control system
(github.com/martinvonz)- Jujutsu एक version control system है जिसका उपयोग सॉफ़्टवेयर प्रोजेक्ट्स के कोड की प्रतिलिपि बनाने, बदलावों को ट्रैक करने और बदलाव प्रकाशित करने के लिए किया जाता है, और इसे नए उपयोगकर्ताओं व अनुभवी लोगों, व्यक्तिगत नए प्रोजेक्ट्स व बड़े इतिहास और टीमों—सभी को ध्यान में रखकर उपयोग में आसान बनाने के लिए डिज़ाइन किया गया है
- यह user interface और version control algorithm को कंटेंट प्रदान करने वाले storage system से आंतरिक रूप से अलग करता है, और फिलहाल स्टोरेज लेयर के रूप में Git repository का उपयोग करता है, इसलिए Git-आधारित टूल्स के साथ संगत है
- Git में केवल commit और files स्टोर होते हैं, जबकि bookmark(branch) और अन्य उच्च-स्तरीय metadata Git के बाहर एक custom repository में स्टोर किए जाते हैं
- डिफ़ॉल्ट Git backend gitoxide Rust लाइब्रेरी का उपयोग करता है, Git remote repository से branch ला सकता है और remote पर push कर सकता है, और ऐसे commit बनाता है जो सामान्य Git commit जैसे दिखते हैं
- यह वास्तविक commit के रूप में working copy को दर्शाने वाला working-copy-as-a-commit मॉडल उपयोग करता है, और file changes अपने-आप सामान्य commit के रूप में रिकॉर्ड हो जाते हैं तथा बाद के हर बदलाव पर amend होते रहते हैं
- dirty working copy की वजह से command fail नहीं होते
git stashकी ज़रूरत नहीं होती- काम पूरा होने से पहले भी working copy commit पर commit message सेट किया जा सकता है
- repository में होने वाला हर काम, उस काम के बाद की repository state snapshot के साथ रिकॉर्ड किया जाता है, इसलिए पिछली repository state को restore करना, किसी एक operation को undo करना, और सबसे हालिया operation के बजाय किसी खास operation को revert करना संभव है
- यह conflicts को commit की तरह first-class object के रूप में रिकॉर्ड करता है, इसलिए conflict पैदा करने वाले operations भी सफल होते हैं और बाद में एक single conflict-resolution workflow में उन्हें संभाला जा सकता है
- जब किसी commit को बदला जाता है, तो उसके सभी मौजूदा descendant अपने-आप नए commit के ऊपर rebase हो जाते हैं, conflict resolution के नतीजे भी descendants तक propagate होते हैं, और rebased commit को इंगित करने वाले bookmark व working copy भी अपडेट हो जाते हैं
- इसमें explicit index या staging area नहीं है, commit selection के लिए revset language का उपयोग होता है, और output format को user-configurable template language से संभाला जाता है
- history rewriting के लिए यह
jj describeसे किसी भी commit का message edit करना,jj diffeditसे checkout किए बिना commit changes edit करना,jj splitसे commit split करना, औरjj squash -i --from X --into Yसे कुछ बदलावों को दूसरे commit में ले जाना जैसी सुविधाएँ देता है - सुरक्षित concurrent replication एक experimental feature है, और Dropbox तथा
rsyncजैसे distributed file system या backup tools के साथ उपयोग होने पर repository को corrupted state में जाने से रोकने के लिए डिज़ाइन किया गया है; सबसे खराब स्थिति में इसका लक्ष्य local और remote state के बीच conflict को उजागर करना है jjएक experimental version control system है; Git compatibility स्थिर है, लेकिन कुछ features अभी विकास में हैं, UX हर जगह सर्वोत्तम नहीं हो सकता, और कुछ उपयोग पैटर्न में workflow gaps हो सकते हैं- features काफ़ी हद तक पूरे हैं, लेकिन Git submodule support अभी पूरा नहीं हुआ है, कई performance bugs मौजूद हैं, और email-आधारित workflow के लिए native support नहीं है
- 1.0.0 से पहले workflow में बदलाव और on-disk format में backward-incompatible changes होने की संभावना है, और format changes के लिए यह transparent upgrade या अनुरोध पर upgrade command/script देने की कोशिश करता है
- यह Apache 2.0 लाइसेंस के तहत उपलब्ध open source software है, Google का supported product नहीं है, और support community द्वारा प्रदान किया जाता है
2 टिप्पणियां
Jujutsu - सरल और शक्तिशाली Git-संगत DVCS
मैंने इसे डेढ़ साल पहले पोस्ट किया था, और अब यह फिर से HN पर एक मुद्दे के रूप में आया है।
Hacker News की राय
इसे यहाँ देखकर अच्छा लगा। लगभग 2–3 हफ्ते पहले jj पर शिफ्ट हुआ हूँ, और वापस जाने का मन नहीं है। दिमाग में काम करने का तरीका काफी बदलना पड़ा, लेकिन
jjजो flow देता है वह मुझे काफी पसंद हैक्या commit करना है, इस पर अलग से सोचने में लगने वाला समय खत्म हो गया है, और files में हुए सभी बदलाव अपने-आप working copy commit में reflect हो जाते हैं। बेशक, कभी-कभी यह नहीं चाहिए होता, इसलिए commit को दो हिस्सों में बाँटने या बदलावों को move करने की सुविधाएँ हैं, और यह बात अच्छी लगती है कि हर operation commit को target करके काम करता है
jj logकई branches का पूरा map देखने के लिए शानदार है, conflicts को आंशिक रूप से resolve करके किसी दूसरी branch पर जा सकते हैं, और short changeset ID भी सुविधाजनक हैं। उदाहरण के लिएjj logमें rebase करने वाला changeset देखकरjj rebase -s qr -d masterजैसे चला सकते हैं, जो branch name पूरा type करने से तेज हैकहा गया है कि इसे Dropbox जैसे backend के साथ इस्तेमाल किया जा सकता है, लेकिन IPFS के साथ आसानी से इस्तेमाल हो सकने वाला system आए तो अच्छा होगा। बड़े data के मामले में GitHub पर 1TB store नहीं कर सकते, और LFS paid है इसलिए उसे अलग मानता हूँ
जो लोग dataset इस्तेमाल करना चाहते हैं, उनके पास वह वैसे भी local में होता है, इसलिए download source एक नहीं बल्कि हजारों हो जाने वाला IPFS natural solution है। अगर data repository के लिए IPFS इस्तेमाल हो तो मैं तुरंत shift करूँगा, वरना देखने लायक value कम लगती है
Jujutsu लेखक के personal project के रूप में शुरू हुआ था, और अब Google में लेखक का full-time project बन गया है। Git Merge 2022 में इस पर presentation हो चुका है
Jujutsu: A Git-Compatible VCS - Git Merge 2022:
Video:
https://youtu.be/bx_LGilOuE4
Slides:
https://docs.google.com/presentation/d/1F8j9_UOOSGUN9MvHxPZX...
लगभग 1 साल से jj रोज़ इस्तेमाल कर रहा हूँ, और यह Git user experience से निश्चित रूप से काफी बेहतर लगता है। मैं changes को atomic commits में बाँटने को लेकर काफी particular हूँ, इसलिए automatic rebase core feature है
conflicts को commit में record किया जा सकता है, इसलिए Git या Mercurial की तरह rebase के बीच में रुककर conflict ठीक करने की जरूरत नहीं होती। commit को modify या delete करने पर भी jj सभी descendant commits को अपने-आप rebase कर देता है, और Git rebase के उलट, Mercurial evolve की तरह multiple children भी handle करता है
commit history संभालने के basic commands भी अच्छे हैं।
jj move|restoreसे किसी एक commit के changes को दूसरे commit में move या copy कर सकते हैं,jj splitसे commit को तोड़ सकते हैं, औरjj rebaseसे commit को move कर सकते हैं। working tree या index के बिना सब कुछ commit history के अंदर होता है, इसलिए उसी command और flags से handle किया जा सकता हैoperation log भी शानदार है, इसलिए ज्यादातर काम बिना दिक्कत undo किए जा सकते हैं। इसकी तुलना Git से करें, जहाँ खराब rebase या
commit --amendको ठीक करने के लिए reflog में सही commit खोजनी पड़ती है और ref को manually ठीक करना पड़ता हैसबसे असुविधाजनक बात यह है कि automatic working copy commit कभी-कभी ऐसे files भी commit करने की कोशिश करता है जिन्हें आप नहीं चाहते, और rename detection नहीं है, इसलिए merges को Git जितनी elegant तरह से handle नहीं कर पाता। फिर भी टूटे हुए commits को
jj split|restoreसे अपेक्षाकृत आसानी से ठीक किया जा सकता है, और jj developers भी rename वाली समस्या पर विचार कर रहे हैंकाम के नतीजे में conflict आए तब भी उस जानकारी को commit में record करके operation को सफल मानता है, और बाद में conflict resolve कर सकते हैं—यह बात अच्छी लगी। पिछले करीब 10 साल से collaborative editing algorithms पर काम किया है, और ideally Git जैसे tools अंततः CRDT-based approach से replace हो जाएँ तो अच्छा होगा
CRDT इस्तेमाल करने पर उसी tool से pair programming की जा सकती है, और Git में हो सकने वाले self-conflict जैसे complex merges को भी बेहतर तरीके से handle करता है। यह ज्यादा शक्तिशाली model भी है
हालांकि modern text CRDT simultaneous editing को अपने-आप बिना conflict के resolve कर देते हैं, लेकिन offline code collaboration करते समय आम तौर पर हम चाहते हैं कि conflict सामने आए और इंसान उसे खुद resolve करे। CRDT के पास Git से ज्यादा editing history information होती है, इसलिए theoretically यह संभव है, लेकिन इसे सही तरह करने के लिए शायद conflict को ही text file के data model में डालना पड़ेगा, और यह modern editors के साथ कैसे fit होगा, यह अच्छी तरह नहीं पता
लगता है जैसे jj ने भी वही तरीका खोज लिया है, इसलिए यह practically कितना अच्छा काम करेगा, इसे लेकर उत्सुक हूँ। CRDT-based code repository के सपने के एक कदम करीब महसूस होता है
git bisectमें value महसूस नहीं हुई?अगर reproducible bug है और cause complex है, तो किस commit ने bug introduce किया यह ढूँढकर कौन-सा change वजह है, देखना उपयोगी नहीं होगा क्या? कम से कम क्या ठीक करना है, इसका पहला अंदाज़ा लगाने के लिए अच्छा होता है
अभी
git bisectसबसे अच्छा तब काम करता है जब सभी commits build और run हो सकते हों। अगर किसी commit में conflict markers हैं और वह build या run नहीं होता, तो बहुत ज्यादा manual intervention की जरूरत पड़ जाती हैऐसे scenario में
git bisectके equivalent feature को कैसे adapt किया जा सकेगा, यह जानना चाहता हूँ। सिर्फ conflict marker strings scan करना शायद सही न हो। क्योंकि docs में conflict markers explain किए जा सकते हैं, या किसी markup language में=======underline के रूप में legally इस्तेमाल हो सकता हैयह उस विचार से टकराता दिखता है कि source management history एक meaningful artifact है, और patches का bundle development machine छोड़ने से पहले incremental और atomic changes की series में साफ-सुथरा होना चाहिए
हालांकि मेरे आसपास के ज्यादातर developers पहले से ही Git history को editor की infinite undo history की तरह treat करते हैं, इसलिए यह approach शायद उस बात को पक्का कर देगी
long-term history कैसे काम करती दिखती है, और यह अभी से ज्यादा उपयोगी होगी या कम, यह जानना चाहता हूँ
वर्किंग कॉपी अपने-आप commit हो जाती है, यह शुरुआत में अच्छा लगता है, लेकिन कई स्थितियों में ठीक नहीं होता
कोई नया artifact file बन गया और उसे अभी
.gitignoreमें डालने से पहले ही वह auto commit हो गया; फिर एक branch में ignored file जोड़ने के बाद दूसरी branch पर switch करें तो वह working copy में तो रहता है, लेकिन.gitignoreमें नहीं होता, इसलिए auto commit हो सकता हैऔर बाद में commit को split करने की तुलना में, सिर्फ कुछ files stage करके commit करना कहीं ज्यादा आसान है
मेरे दिमाग में भी यही बात बैठी हुई है, लेकिन सच में सही है या नहीं, पता नहीं। असल में index ठीक करना और बाद में commit को amend करना काफी बार होता है, और यह पहले भी किया जा सकता है
अगर बाद की editing से पूरी तरह बचा ही नहीं जा सकता, तो ऐसी editing के लिए एक single workflow बेहतर नहीं होगा? अभी मैंने इसे इस्तेमाल नहीं किया है, लेकिन यह तरीका काफी plausible लगता है कि जिन conventions को हम स्वाभाविक मानते आए हैं, वे शायद वाकई मददगार न हों
ऐसा कोई use case मेरे पास नहीं है जहां हर generated/modified file हमेशा commit में जाए
दूसरी branch पर जाने पर file working copy में रह जाए लेकिन
.gitignoreमें न हो, इसे मैं Git की failure मानता हूं।.gitignoreके अलावा.local.gitignoreजैसा कुछ होना चाहिए। सिर्फ मुझे चाहिए ऐसी ignored files बहुत आम हैं और project के.gitignoreमें जाने वाली चीज नहीं हैं। तरीके हैं, लेकिन सब awkward हैं, इसलिए यह default में सरलता से मिलना चाहिएफिर भी दिलचस्प है। मुझे Git का staging कभी पसंद नहीं रहा, लेकिन यहां बताई गई स्थिति मैंने झेली नहीं थी, इसलिए अब समझ आया कि file system और commit के बीच एक intermediate step की जरूरत क्यों है
.gitignoreमें add करें, तो अगले auto commit पर वह anonymous working-copy commit से फिर निकल जाती हैfile शुरू से add न होने के बजाय anonymous working-copy commit में जाकर फिर निकलने वाला flow intuitive नहीं है, लेकिन अगर वह anonymous commit ज्यादातर users को दिखता ही नहीं, तो फर्क नहीं पड़ना चाहिए
docs देखें तो जिन कई cases की चिंता की जा रही है, उन्हें स्पष्ट रूप से cover किया गया है:
https://github.com/martinvonz/jj/blob/main/docs/git-comparis...
कुछ खास cases छोड़ दें तो कई सालों से command line पर Git लगभग इस्तेमाल नहीं करता। रोजमर्रा में IntelliJ जैसे IDE built-in integration पर निर्भर रहता हूं, और समझना मुश्किल है कि लोग इसे manually क्यों झेलते हैं
editor के अंदर line-by-line चुनकर partial commits कर सकता हूं, सभी branches देख सकता हूं, merge और cherry-pick कर सकता हूं, commit या amend कर सकता हूं, updates pull कर सकता हूं, tags edit कर सकता हूं—सब shortcuts से एक बार में
हालांकि यहां शायद मैं minority में हूं। यह सोच भी जोड़ लें कि Git एक जरूरी skill है और असली programmer को आंख बंद करके commands टाइप कर आनी चाहिए, तो और भी ज्यादा; मुझे जानना है कि ऐसा क्यों है
यह skill environment-independent है: remote machine में login करके repository देखना local जैसा ही रहता है, हर editor का VCS integration अलग से सीखने की जरूरत नहीं पड़ती, और familiar tools वैसे ही इस्तेमाल कर सकते हैं
जिन tasks का उदाहरण दिया गया है, वे command line पर भी उतनी ही आसानी से हो जाते हैं, इसलिए editor integration को मैं खास नहीं मानता। reflog छेड़ने जैसे अजीब और advanced काम चाहिए हों तो आखिरकार command line खोलनी पड़ने की संभावना ज्यादा है
हां, GUI इस्तेमाल करने वालों से मुझे कोई शिकायत नहीं। अगर tool से productivity आती है तो judge करने की बात नहीं; आपने पूछा कि क्यों, इसलिए जवाब दिया, यह दावा नहीं कि मेरा तरीका बेहतर है
लोग “Git CLI सीखनी चाहिए” सबसे आम तौर पर इसी context में कहते हैं
कुछ दिन पहले भी Git commands सीखने से बचने के लिए GitHub Desktop इस्तेमाल करने का उदाहरण था: https://www.reddit.com/r/learnprogramming/comments/15b7pra/s...
Git compatibility को पहले सामने रखने वाले approach की वजह से Jujutsu अब तक देखे गए Git replacement candidates में ज़्यादा मजबूत लगता है
Git compatibility की explanation पढ़कर जो बात जानने की उत्सुकता हुई, वह यह है कि ऐसा लगता है कि focus मुख्य रूप से उस use case पर है जहाँ Jujutsu users GitHub वगैरह पर hosted Git repositories को jj से access करते हैं। उल्टा, क्या native Jujutsu repositories को Git से access करने का तरीका भी support होता है, यह जानना चाहूँगा
ज़्यादातर developers पहले से ही Git CLI से परिचित हैं, इसलिए real operations में ऐसा लगता है कि एक ही codebase में jj और Git दोनों इस्तेमाल करने वाले developers दिखेंगे। या फिर realistic operations scenario यह है कि दोनों तरफ CLI access के लिए हमेशा native Jujutsu database नहीं, बल्कि Git को backend repository के तौर पर इस्तेमाल किया जाए?
यह backend मुख्य रूप से इसलिए मौजूद है ताकि बाद में ऐसी features जोड़ पाने की गारंटी रहे जिन्हें Git backend में आसानी से add नहीं किया जा सकता
अगर पहले से Jujutsu इस्तेमाल कर रहे किसी project पर काम और contribution करना हो, तो project को मेरे workflow के मुताबिक ढालने के बजाय मेरा project के मुताबिक ढलना reasonable है
Git compatibility first approach की वजह से Jujutsu अब तक देखे गए Git replacement candidates में ज़्यादा मजबूत लगता है
conflict management को लेकर उत्सुकता है। मुझे पता है कि pmeunier ने Pijul के लिए patch theory को formally整理 करने में काफी ध्यान दिया था, और unsound या problematic patch/conflict concepts बड़े problems पैदा कर सकते हैं। शायद Darcs की performance problems इसी तरह आई थीं
repository wiki का comparison page अगर Pijul की conflict handling को “similar” कहने से थोड़ा ज़्यादा detail में explain करे तो अच्छा होगा
इस तरह conflicts को symbolically store करने से बाद में conflict reproduce किए जा सकते हैं और कुछ specific conflicts को automatically resolve भी किया जा सकता है, लेकिन यह actual conflict content को resolve करने की समस्या तक नहीं जाता
अगर कोई implement करे, तो Pijul को jj backend के रूप में इस्तेमाल करके दोनों तरफ के benefits मिल सकते हैं
rsync, Dropbox, distributed file systems के जरिए safe replication — यह अच्छा है। आजकल मैं increasingly simple-sync-friendly systems की तरफ झुक रहा हूँ
क्योंकि इन्हें कहीं भी किसी भी tool से डाल दो, ये बस काम कर जाते हैं। कोई नया tool इस direction में जाता है तो हमेशा अच्छा लगता है
सुना है कि ऐसी problem होती है, लेकिन खुद अनुभव नहीं किया। Git और rsync/Dropbox जैसे tools के बीच कौन-सी race condition बनती है जिससे problem होती है, यह जानना चाहूँगा
working copy automatically commit होती है, यह राहत की बात है। यह feature बहुत पहले से चाहिए था
एक elegant tool बनाने में मेहनत करने के लिए Martin को सलाम