उद्देश्य
- का प्रयोग करें (से प्रेरित Smar , से उधार Exherbo )
git am
- कॉपी / स्थानांतरित फ़ाइलों की प्रतिबद्ध इतिहास जोड़ें
- एक डायरेक्टरी से दूसरी में
- या एक रिपॉजिटरी से दूसरे में
सीमा
- टैग और शाखाएँ नहीं रखी जाती हैं
- इतिहास पथ फ़ाइल नाम (निर्देशिका नाम बदलें) पर कट जाता है
सारांश
- ईमेल प्रारूप का उपयोग करके इतिहास निकालें
git log --pretty=email -p --reverse --full-index --binary
- फ़ाइल ट्री को पुनर्गठित करें और फ़ाइल नाम अपडेट करें
- नए इतिहास का उपयोग कर जोड़ें
cat extracted-history | git am --committer-date-is-author-date
1. ईमेल प्रारूप में इतिहास निकालें
उदाहरण: का इतिहास निकालें file3
, file4
औरfile5
my_repo
├── dirA
│ ├── file1
│ └── file2
├── dirB ^
│ ├── subdir | To be moved
│ │ ├── file3 | with history
│ │ └── file4 |
│ └── file5 v
└── dirC
├── file6
└── file7
गंतव्य सेट / साफ़ करें
export historydir=/tmp/mail/dir # Absolute path
rm -rf "$historydir" # Caution when cleaning the folder
ईमेल प्रारूप में प्रत्येक फ़ाइल का इतिहास निकालें
cd my_repo/dirB
find -name .git -prune -o -type d -o -exec bash -c 'mkdir -p "$historydir/${0%/*}" && git log --pretty=email -p --stat --reverse --full-index --binary -- "$0" > "$historydir/$0"' {} ';'
दुर्भाग्य से विकल्प --follow
या --find-copies-harder
के साथ जोड़ा नहीं जा सकता --reverse
। यही कारण है कि जब फ़ाइल का नाम बदला जाता है (या जब एक मूल निर्देशिका का नाम बदला जाता है) तो इतिहास कट जाता है।
ईमेल प्रारूप में अस्थायी इतिहास:
/tmp/mail/dir
├── subdir
│ ├── file3
│ └── file4
└── file5
Dan Bonachea इस पहले चरण में git लॉग जनरेशन कमांड के छोरों को पलटने का सुझाव देता है: प्रति फ़ाइल एक बार git लॉग चलाने के बजाय, इसे कमांड लाइन पर फ़ाइलों की सूची के साथ ठीक एक बार चलाएं और एक एकीकृत लॉग जेनरेट करें। यह तरीका बताता है कि परिणाम में एक से अधिक फ़ाइलों को संशोधित करने के लिए एक ही प्रतिबद्ध है, और सभी नए कमिट अपने मूल सापेक्ष क्रम को बनाए रखते हैं। ध्यान दें कि नीचे (अब एकीकृत) लॉग में फ़ाइल नाम को पुन: लिखने पर दूसरे चरण में भी बदलाव की आवश्यकता है।
2. फ़ाइल ट्री को पुनर्गठित करें और फ़ाइल नाम अपडेट करें
मान लीजिए आप इन तीन फाइलों को इस अन्य रेपो में स्थानांतरित करना चाहते हैं (वही रेपो हो सकता है)।
my_other_repo
├── dirF
│ ├── file55
│ └── file56
├── dirB # New tree
│ ├── dirB1 # from subdir
│ │ ├── file33 # from file3
│ │ └── file44 # from file4
│ └── dirB2 # new dir
│ └── file5 # from file5
└── dirH
└── file77
इसलिए अपनी फ़ाइलों को पुनर्गठित करें:
cd /tmp/mail/dir
mkdir -p dirB/dirB1
mv subdir/file3 dirB/dirB1/file33
mv subdir/file4 dirB/dirB1/file44
mkdir -p dirB/dirB2
mv file5 dirB/dirB2
आपका अस्थायी इतिहास अब है:
/tmp/mail/dir
└── dirB
├── dirB1
│ ├── file33
│ └── file44
└── dirB2
└── file5
इतिहास के भीतर फ़ाइल नाम भी बदलें:
cd "$historydir"
find * -type f -exec bash -c 'sed "/^diff --git a\|^--- a\|^+++ b/s:\( [ab]\)/[^ ]*:\1/$0:g" -i "$0"' {} ';'
3. नया इतिहास लागू करें
आपका अन्य रेपो है:
my_other_repo
├── dirF
│ ├── file55
│ └── file56
└── dirH
└── file77
अस्थायी इतिहास फ़ाइलों से लागू करें:
cd my_other_repo
find "$historydir" -type f -exec cat {} + | git am --committer-date-is-author-date
--committer-date-is-author-date
मूल प्रतिबद्ध समय-टिकटों ( डैन बोनासिया की टिप्पणी) को संरक्षित करता है ।
आपका अन्य रेपो अब है:
my_other_repo
├── dirF
│ ├── file55
│ └── file56
├── dirB
│ ├── dirB1
│ │ ├── file33
│ │ └── file44
│ └── dirB2
│ └── file5
└── dirH
└── file77
git status
धकेले जाने के लिए तैयार कमिट्स की मात्रा देखने के लिए उपयोग करें :-)
एक्स्ट्रा ट्रिक: अपने रेपो के अंदर बदला हुआ / स्थानांतरित फ़ाइलों की जाँच करें
फ़ाइलों का नाम बदलने के लिए:
find -name .git -prune -o -exec git log --pretty=tformat:'' --numstat --follow {} ';' | grep '=>'
अधिक अनुकूलन: आप git log
विकल्पों का उपयोग करके कमांड को पूरा कर सकते हैं --find-copies-harder
या --reverse
। आप cut -f3-
पूर्ण पैटर्न '{*। * =>। *}} का उपयोग करके और पहले वाले दो कॉलम भी निकाल सकते हैं ।
find -name .git -prune -o -exec git log --pretty=tformat:'' --numstat --follow --find-copies-harder --reverse {} ';' | cut -f3- | grep '{.* => .*}'
git mv
: stackoverflow.com/questions/1094269/whats-the-purpose-of-git-mv