इसे प्राप्त करने के लिए 2 चरण हैं:
- एक नई खाली प्रतिबद्ध बनाएँ
- इस खाली प्रतिबद्ध से शुरू करने के लिए इतिहास को फिर से लिखना
हम नई खाली प्रतिबद्ध newroot
सुविधा के लिए एक अस्थायी शाखा पर रख देंगे ।
1. एक नई खाली प्रतिबद्ध बनाएँ
ऐसा करने के कई तरीके हैं।
सिर्फ नलसाजी का उपयोग करना
सबसे साफ तरीका यह है कि Git की प्लंबिंग का उपयोग सीधे एक कमिट बनाने के लिए किया जाए, जो कि वर्किंग कॉपी या इंडेक्स को छूने से बचता है या किस ब्रांच को चेक किया जाता है, आदि।
खाली निर्देशिका के लिए ट्री ऑब्जेक्ट बनाएं:
tree=`git hash-object -wt tree --stdin < /dev/null`
इसके चारों ओर एक आवरण लपेटें:
commit=`git commit-tree -m 'root commit' $tree`
इसके लिए एक संदर्भ बनाएँ:
git branch newroot $commit
यदि आप अपने शेल को अच्छी तरह से जानते हैं तो आप पूरी प्रक्रिया को एक-लाइनर में बदल सकते हैं।
बिना प्लंबिंग के
नियमित रूप से चीनी मिट्टी के बरतन आदेशों के साथ, आप बिना newroot
किसी अच्छे कारण के, शाखा की जाँच और सूचकांक को अद्यतन करने और बार-बार कॉपी करने के बिना एक खाली प्रतिबद्ध नहीं बना सकते हैं । लेकिन कुछ को समझने में यह आसान लग सकता है:
git checkout --orphan newroot
git rm -rf .
git clean -fd
git commit --allow-empty -m 'root commit'
ध्यान दें कि Git के बहुत पुराने संस्करणों पर --orphan
स्विच की कमी है checkout
, आपको इसके साथ पहली पंक्ति को बदलना होगा:
git symbolic-ref HEAD refs/heads/newroot
2. इस खाली प्रतिबद्ध से शुरू करने के लिए इतिहास को फिर से लिखना
आपके पास यहां दो विकल्प हैं: रिबासिंग, या एक स्वच्छ इतिहास फिर से लिखना।
रिबेसिंग
git rebase --onto newroot --root master
इसमें सादगी का गुण है। हालांकि, यह शाखा पर हर अंतिम प्रतिबद्ध पर कमिट नाम और तारीख को भी अपडेट करेगा।
इसके अलावा, कुछ एज केस हिस्ट्री के साथ, यह मर्ज संघर्ष के कारण भी विफल हो सकता है - इस तथ्य के बावजूद कि आप एक ऐसी प्रतिबद्धता पर रिबास कर रहे हैं जिसमें कुछ भी नहीं है।
इतिहास फिर से लिखना
क्लीनर दृष्टिकोण शाखा को फिर से लिखना है। इसके विपरीत git rebase
, आपको यह देखना होगा कि आपकी शाखा किस से शुरू होती है:
git replace <currentroot> --graft newroot
git filter-branch master
पुनर्लेखन दूसरे चरण में होता है, जाहिर है; यह पहला कदम है जिसे स्पष्टीकरण की आवश्यकता है। यह क्या git replace
बताता है कि Git बताता है कि जब भी वह किसी ऑब्जेक्ट का संदर्भ देखता है जिसे आप प्रतिस्थापित करना चाहते हैं, तो Git को उस ऑब्जेक्ट के प्रतिस्थापन को देखना चाहिए।
--graft
स्विच के साथ , आप इसे सामान्य से थोड़ा अलग बता रहे हैं। आप कह रहे हैं कि आपके पास अभी तक एक प्रतिस्थापन वस्तु नहीं है, लेकिन आप चाहते हैं कि <currentroot>
वस्तु वस्तु को स्वयं की एक सटीक प्रति के साथ प्रतिस्थापित किया जाए, सिवाय इसके कि प्रतिस्थापन के माता-पिता के प्रतिबद्ध (ओं) को आप सूचीबद्ध करें (यानी newroot
प्रतिबद्ध) )। फिर git replace
आगे बढ़ता है और आपके लिए यह प्रतिबद्ध बनाता है, और फिर घोषणा करता है कि आपकी मूल प्रतिबद्ध के लिए यह प्रतिस्थापन है।
अब यदि आप एक करते हैं git log
, तो आप देखेंगे कि चीजें पहले से ही दिख रही हैं जैसा कि आप उन्हें चाहते हैं: शाखा से शुरू होता है newroot
।
हालांकि, ध्यान दें कि git replace
वास्तव में इतिहास को संशोधित नहीं करता है - और न ही यह आपके भंडार से बाहर प्रचारित करता है। यह केवल एक वस्तु से दूसरी वस्तु में आपके भंडार में एक स्थानीय पुनर्निर्देशन जोड़ता है। इसका मतलब यह है कि कोई और इस प्रतिस्थापन के प्रभाव को नहीं देखता है - केवल आप।
इसलिए filter-branch
कदम जरूरी है। साथ git replace
आप रूट के लिए समायोजित माता पिता प्रतिबद्ध के साथ एक सटीक प्रतिलिपि बनाने के लिए प्रतिबद्ध; git filter-branch
फिर इस प्रक्रिया को निम्नलिखित सभी कमिटों के लिए भी दोहराता है। यही वह जगह है जहां इतिहास वास्तव में फिर से लिखा जाता है ताकि आप इसे साझा कर सकें।