आप जो करना चाहते हैं, इसमें दो चरणों को शामिल किया जाएगा: एक उपयुक्त .gitignore
के साथ एक नई रूट जोड़ें और उन फ़ाइलों को निकालने के लिए अपने इतिहास को साफ़ करें जो जोड़ा नहीं जाना चाहिए था। git filter-branch
कमांड दोनों कर सकते हैं।
सेटअप
अपने इतिहास के प्रतिनिधि पर विचार करें।
$ git lola --name-status
* f1af2bf (HEAD, bar-feature) Add bar
| A .gitignore
| A bar.c
| D main.o
| D module.o
| * 71f711a (master) Add foo
|/
| A foo.c
| A foo.o
* 7f1a361 Commit 2
| A module.c
| A module.o
* eb21590 Commit 1
A main.c
A main.o
स्पष्टता के लिए, *.c
फ़ाइलें सी स्रोत फ़ाइलों का प्रतिनिधित्व करते हैं और *.o
वस्तु फ़ाइलों को नजरअंदाज कर दिया गया है चाहिए संकलित कर रहे हैं।
बार-फीचर शाखा पर, आपने एक उपयुक्त .gitignore
और हटाए गए ऑब्जेक्ट फ़ाइलों को जोड़ा जो ट्रैक नहीं किया जाना चाहिए था, लेकिन आप चाहते हैं कि यह नीति आपके आयात में हर जगह दिखाई दे।
ध्यान दें कि git lola
non-standard है लेकिन उपयोगी उपनाम है।
git config --global alias.lola \
'log --graph --decorate --pretty=oneline --abbrev-commit --all'
नए रूट प्रतिबद्ध
नया रूट बनाने के रूप में इस के लिए प्रतिबद्ध।
$ git checkout --orphan new-root
Switched to a new branch 'new-root'
git checkout
प्रलेखन नई अनाथ शाखा के एक संभव अप्रत्याशित राज्य नोटों।
आप डिस्कनेक्ट इतिहास है कि रास्तों का एक सेट है कि में से एक start_point से पूरी तरह से अलग है रिकॉर्ड शुरू करने के लिए चाहते हैं, तो आप सही चलाकर अनाथ शाखा बनाने के बाद सूचकांक और काम कर पेड़ को स्पष्ट करना चाहिए काम करने वाले पेड़ के शीर्ष स्तर से git rm -rf .
।बाद में आप अपने नए फ़ाइलें तैयार करने के लिए, काम कर पेड़ repopulating तैयार हो जाएगा, कहीं और से उन्हें कॉपी करने एक टारबॉल निकालने, आदि
को जारी रखते हुए हमारे उदाहरण के द्वारा:
$ git rm -rf .
rm 'foo.c'
rm 'foo.o'
rm 'main.c'
rm 'main.o'
rm 'module.c'
rm 'module.o'
$ echo '*.o' >.gitignore
$ git add .gitignore
$ git commit -m 'Create .gitignore'
[new-root (root-commit) 00c7780] Create .gitignore
1 file changed, 1 insertion(+)
create mode 100644 .gitignore
अब इतिहास की तरह दिखता है
$ git lola
* 00c7780 (HEAD, new-root) Create .gitignore
* f1af2bf(bar-feature) Add bar
| * 71f711a (master) Add foo
|/
* 7f1a361 Commit 2
* eb21590 Commit 1
कि थोड़ा भ्रामक है क्योंकि यह बनाता है नई-रूट देखो की तरह यह बार-सुविधा का वंशज है, लेकिन यह वास्तव में कोई पैरेंट है।
$ git rev-parse HEAD^
HEAD^
fatal: ambiguous argument 'HEAD^': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
अनाथ के लिए एसएचए नोट करें क्योंकि आपको बाद में इसकी आवश्यकता होगी। इस उदाहरण में, यह
$ git rev-parse HEAD
00c778087723ae890e803043493214fb09706ec7
इतिहास
नए सिरे से लिखना है हम git filter-branch
मोटे तौर पर तीन परिवर्तन करना चाहते हैं।
- नई रूट प्रतिबद्धता में विभाजन।
- सभी अस्थायी फ़ाइलों को हटाएं।
- नई रूट से
.gitignore
का उपयोग करें जब तक कि कोई पहले से मौजूद न हो।
कमांड लाइन पर, कि के रूप में
git filter-branch \
--parent-filter '
test $GIT_COMMIT = eb215900cd15ca2cf9ded74f1a0d9d25f65eb2bf && \
echo "-p 00c778087723ae890e803043493214fb09706ec7" \
|| cat' \
--index-filter '
git rm --cached --ignore-unmatch "*.o"; \
git ls-files --cached --error-unmatch .gitignore >/dev/null 2>&1 ||
git update-index --add --cacheinfo \
100644,$(git rev-parse new-root:.gitignore),.gitignore' \
--tag-name-filter cat \
-- --all
स्पष्टीकरण incanted है:
--parent-filter
अपने नए रूट में विकल्प हुक के लिए प्रतिबद्ध।
eb215...
पुरानी रूट प्रतिबद्धता का पूर्ण SHA है, सीएफ।
git rm
चल रहा है के रूप में ऊपर पूरे पेड़ से *.o
मिलान क्योंकि ग्लोब पैटर्न उद्धृत और खोल के बजाय Git से व्याख्या की है कुछ भी हटाता है:git rev-parse eb215
--index-filter
विकल्प के दो भाग हैं।
- के साथ
git ls-files
के साथ मौजूदा .gitignore
के लिए जांचें, और यदि यह नहीं है, तो नए रूट में से किसी को इंगित करें।
- यदि आपके पास कोई टैग है, तो उन्हें पहचान ऑपरेशन,
cat
के साथ मैप किया जाएगा।
- अकेला
--
विकल्पों को समाप्त करता है, और --all
सभी रेफरी के लिए शॉर्टेंड है।
उत्पादन जैसा कि आप देख
Rewrite eb215900cd15ca2cf9ded74f1a0d9d25f65eb2bf (1/5)rm 'main.o'
Rewrite 7f1a361ee918f7062f686e26b57788dd65bb5fe1 (2/5)rm 'main.o'
rm 'module.o'
Rewrite 71f711a15fa1fc60542cc71c9ff4c66b4303e603 (3/5)rm 'foo.o'
rm 'main.o'
rm 'module.o'
Rewrite f1af2bf89ed2236fdaf2a1a75a34c911efbd5982 (5/5)
Ref 'refs/heads/bar-feature' was rewritten
Ref 'refs/heads/master' was rewritten
WARNING: Ref 'refs/heads/new-root' is unchanged
आपकी मूल अभी भी सुरक्षित हैं जैसे लगते हैं जाएगा। मास्टर शाखा अब उदाहरण के लिए refs/original/refs/heads/master
के तहत रहता है। अपनी नई पुनर्लेखित शाखाओं में हुए बदलावों की समीक्षा करें।जब आप बैकअप नष्ट करने के लिए तैयार कर रहे हैं, को चलाने
git update-ref -d refs/original/refs/heads/master
आप एक आदेश में सभी बैकअप refs कवर करने के लिए एक कमांड अप पकाना सकता है, लेकिन मैं हर एक के लिए सावधानी से समीक्षा करें।
निष्कर्ष
अंत में, नया इतिहास
$ git lola --name-status
* ab8cb1c (bar-feature) Add bar
| M .gitignore
| A bar.c
| * 43e5658 (master) Add foo
|/
| A foo.c
* 6469dab Commit 2
| A module.c
* 47f9f73 Commit 1
| A main.c
* 00c7780 (HEAD, new-root) Create .gitignore
A .gitignore
का निरीक्षण करें कि सभी वस्तु फ़ाइलें चला रहे हैं। बार-फीचर में .gitignore
में संशोधन इसलिए है क्योंकि मैंने यह सुनिश्चित करने के लिए विभिन्न सामग्री का उपयोग किया है कि यह संरक्षित होगा। पूर्णता के लिए:
$ git diff new-root:.gitignore bar-feature:.gitignore
diff --git a/new-root:.gitignore b/bar-feature:.gitignore
index 5761abc..c395c62 100644
--- a/new-root:.gitignore
+++ b/bar-feature:.gitignore
@@ -1 +1,2 @@
*.o
+*.obj
नए रूट रेफरी नहीं रह गया है उपयोगी है, इसलिए साथ
$ git checkout master
$ git branch -d new-root
आप मेरे फ्लिपिन हीरो हैं! – Aren
@ एरेन आपका स्वागत है! मदद करने में खुशी। –