आपको दी गई सलाह त्रुटिपूर्ण है। बिना किसी सेटिंग के GIT_AUTHOR_DATE --env-filter
को हर प्रतिबद्धता की तारीख को फिर से लिखना होगा। इसके अलावा, अंदर git कमिट का उपयोग करना असामान्य होगा --index-filter
।
आप यहां कई, स्वतंत्र समस्याओं से निपट रहे हैं।
अन्य तिथियों को "अब" निर्दिष्ट करना
प्रत्येक कमिट में दो तारीखें होती हैं: लेखक की तारीख और कमिट डेट। आप किसी नए आदेश को लिखने वाले किसी भी आदेश के लिए GIT_AUTHOR_DATE और GIT_COMMITTER_DATE के पर्यावरण चर के माध्यम से मूल्यों की आपूर्ति करके प्रत्येक को ओवरराइड कर सकते हैं। देखें "दिनांक प्रारूप" में Git-लिखें (1) या नीचे:
Git internal format = <unix timestamp> <time zone offset>, e.g. 1112926393 +0200
RFC 2822 = e.g. Thu, 07 Apr 2005 22:13:13 +0200
ISO 8601 = e.g. 2005-04-07T22:13:13
केवल आदेश लिखते हैं कि सामान्य उपयोग के दौरान एक नया प्रतिबद्ध है प्रतिबद्ध Git । इसमें एक --date
विकल्प भी है जो आपको लेखक की तारीख को सीधे निर्दिष्ट करता है। आपके प्रत्याशित उपयोग में git filter-branch --env-filter
ऊपर उल्लिखित पर्यावरण चर का उपयोग भी शामिल है (ये "env" का हिस्सा हैं जिसके बाद विकल्प का नाम दिया गया है; git-filter-branch (1) में "विकल्प" देखें और अंतर्निहित "प्लंबिंग" कमांड git-प्रतिबद्ध) —तीन (१) ।
इतिहास में एक एकल रेफरी में एक फ़ाइल सम्मिलित करना
यदि आपकी रिपॉजिटरी बहुत सरल है (यानी आपके पास केवल एक ही शाखा है, कोई टैग नहीं है), तो आप शायद कार्य करने के लिए गिट रिबास का उपयोग कर सकते हैं।
निम्नलिखित आदेशों में, "ए" के बजाय कमिट के ऑब्जेक्ट नाम (SHA-1 हैश) का उपयोग करें। जब आप git कमिट करते हैं तो "डेट ओवरराइड" विधियों में से एक का उपयोग करना न भूलें ।
---A---B---C---o---o---o master
git checkout master
git checkout A~0
git add path/to/file
git commit --date='whenever'
git tag ,new-commit -m'delete me later'
git checkout -
git rebase --onto ,new-commit A
git tag -d ,new-commit
---A---N (was ",new-commit", but we delete the tag)
\
B'---C'---o---o---o master
यदि आप नई फ़ाइल को शामिल करने के लिए ए को अपडेट करना चाहते हैं (जहां इसे जोड़ा गया था, तो एक नई प्रतिबद्ध बनाने के बजाय), तो git commit --amend
इसके बजाय का उपयोग करें git commit
। परिणाम इस तरह दिखेगा:
---A'---B'---C'---o---o---o master
उपरोक्त कार्य तब तक करता है जब तक आप उस कमिट को नाम दे सकते हैं जो आपकी नई कमेटी का जनक होना चाहिए। यदि आप वास्तव में चाहते हैं कि आपकी नई फ़ाइल एक नई रूट कमिट (कोई माता-पिता) के माध्यम से जोड़ी जाए, तो आपको कुछ अलग करने की आवश्यकता है:
B---C---o---o---o master
git checkout master
git checkout --orphan new-root
git rm -rf .
git add path/to/file
GIT_AUTHOR_DATE='whenever' git commit
git checkout -
git rebase --root --onto new-root
git branch -d new-root
N (was new-root, but we deleted it)
\
B'---C'---o---o---o master
git checkout --orphan
अपेक्षाकृत नया है (Git 1.7.2), लेकिन वही काम करने के अन्य तरीके हैं जो Git के पुराने संस्करणों पर काम करते हैं।
एक मल्टी- रेफरी इतिहास में एक फ़ाइल सम्मिलित करना
यदि आपकी रिपॉजिटरी अधिक जटिल है (यानी इसमें एक से अधिक रेफरी (शाखाएं, टैग आदि) हैं), तो आपको शायद गिट फ़िल्टर-शाखा का उपयोग करने की आवश्यकता होगी । गिट फ़िल्टर-शाखा का उपयोग करने से पहले , आपको अपनी संपूर्ण रिपॉजिटरी की एक बैकअप प्रतिलिपि बनानी चाहिए। आपके पूरे वर्किंग ट्री (.गित डायरेक्टरी सहित) का एक साधारण टार आर्काइव पर्याप्त है। git फ़िल्टर-शाखा बैकअप रीफ़ बनाती है, लेकिन अक्सर अपनी .git
निर्देशिका को हटाकर और इसे अपने बैकअप से पुनर्स्थापित करके, एक बहुत-से-सही फ़िल्टरिंग से पुनर्प्राप्त करना आसान होता है ।
नोट: नीचे दिए गए उदाहरण निम्न-स्तरीय कमांड का git update-index --add
उपयोग करते हैं git add
। आप git ऐड का उपयोग कर सकते हैं , लेकिन आपको पहले फ़ाइल को किसी बाहरी स्थान से अपेक्षित पथ पर कॉपी करना होगा ( --index-filter
अस्थायी GIT_WORK_TREE में इसका कमांड चलाता है जो खाली है)।
यदि आप चाहते हैं कि आपकी नई फ़ाइल को हर मौजूदा कमेटी में जोड़ा जाए, तो आप ऐसा कर सकते हैं:
new_file=$(git hash-object -w path/to/file)
git filter-branch \
--index-filter \
'git update-index --add --cacheinfo 100644 '"$new_file"' path/to/file' \
--tag-name-filter cat \
-- --all
git reset --hard
मुझे वास्तव में मौजूदा कमिट की तारीखों को बदलने का कोई कारण नहीं दिखता है --env-filter 'GIT_AUTHOR_DATE=…'
। यदि आप इसका उपयोग करते हैं, तो आप इसे सशर्त बना देंगे ताकि यह हर प्रतिबद्ध के लिए तारीख को फिर से लिखे।
यदि आप चाहते हैं कि आपकी नई फ़ाइल कुछ मौजूदा प्रतिबद्धताओं ("ए") के बाद केवल कमिट में दिखाई दे, तो आप ऐसा कर सकते हैं:
file_path=path/to/file
before_commit=$(git rev-parse --verify A)
file_blob=$(git hash-object -w "$file_path")
git filter-branch \
--index-filter '
if x=$(git rev-list -1 "$GIT_COMMIT" --not '"$before_commit"') &&
test -n "$x"; then
git update-index --add --cacheinfo 100644 '"$file_blob $file_path"'
fi
' \
--tag-name-filter cat \
-- --all
git reset --hard
आप चाहते हैं फ़ाइल को एक नए के माध्यम से जोड़े जाने के लिए तो प्रतिबद्ध है कि अपने इतिहास के बीच में डाला जा रहा है, तो आप नए उत्पन्न करने के लिए प्रतिबद्ध की आवश्यकता होगी उपयोग करने से पहले Git फिल्टर शाखा और जोड़ने --parent-filter
के लिए Git फिल्टर शाखा :
file_path=path/to/file
before_commit=$(git rev-parse --verify A)
git checkout master
git checkout "$before_commit"
git add "$file_path"
git commit --date='whenever'
new_commit=$(git rev-parse --verify HEAD)
file_blob=$(git rev-parse --verify HEAD:"$file_path")
git checkout -
git filter-branch \
--parent-filter "sed -e s/$before_commit/$new_commit/g" \
--index-filter '
if x=$(git rev-list -1 "$GIT_COMMIT" --not '"$new_commit"') &&
test -n "$x"; then
git update-index --add --cacheinfo 100644 '"$file_blob $file_path"'
fi
' \
--tag-name-filter cat \
-- --all
git reset --hard
आप फ़ाइल को पहली बार एक नई रूट कमेटी में जोड़ने की व्यवस्था भी कर सकते हैं: अपने नए रूट कमिट को "रीथेन" विधि के माध्यम से बनाइए जो कि रीट रिबेस सेक्शन से है (इसे कैप्चर new_commit
करें), बिना शर्त का उपयोग करें --index-filter
, और एक --parent-filter
तरह "sed -e \"s/^$/-p $new_commit/\""
।