Git diff --name-only और उस सूची को कॉपी करें


151

मैं केवल दो संशोधनों के बीच परिवर्तित फ़ाइलों की एक सूची प्राप्त करना चाहता हूं, जो सरल है:

git diff -–name-only commit1 commit2 > /path/to/my/file

लेकिन, मुझे क्या लिखना चाहिए, अगर मैं उस सभी सूचीबद्ध फाइलों को दूसरी जगह कॉपी करना चाहता हूं? और मुझे कॉपी किए गए फ़ाइलों के लिए पूरी तरह से समान निर्देशिका संरचना की आवश्यकता है।

उदाहरण के लिए, मैंने फ़ाइलों को संशोधित और जोड़ा है:

/protected/texts/file1.txt
/protected/scripts/index.php
/public/pics/pic1.png

मैं /home/changes/उन सभी परिवर्तित और जोड़ी गई फ़ाइलों में रखना चाहता हूं :

/home/changes/protected/texts/file1.txt
/home/changes/protected/scripts/index.php
/home/changes/public/pics/pic1.png

1
मुझे यह समझ में नहीं आ रहा है कि आप क्या हासिल करने की कोशिश कर रहे हैं ... विभिन्न क्लोन में परिवर्तन का प्रचार? पैच बनाने? एक गिट्टी भंडार के बाहर फ़ाइलें पैचिंग?
knittl

पैच नहीं, लेकिन बदली हुई फ़ाइलों की सटीक प्रतिलिपि संरचना। पैच की तरह, लेकिन ठोस फ़ाइलों के साथ
बाज़ी

और हाँ, git रिपॉजिटरी के बाहर फाइलें पैच करना - मेरे लिए निकटतम लक्ष्य :)
BazZy

3
माफ़ करना। क्या? आप फ़ाइलों को बदलने और पेड़ों में परिवर्तन को फिर से खेलना चाहते हैं? यह एक पैच है। git format-patchप्रतिबद्ध श्रेणियों के लिए ऐसा कर सकते हैं।
knittl

1
git diff commit1 commit2 > my.patchऔर फिर cd other/path; patch -p1 < my.patch। इसे फाइलों की पूरी प्रतियों के साथ क्यों करना पड़ता है? यदि ऐसा है क्योंकि आपको लगता है कि पैच लागू नहीं हो सकता है, और इसलिए अन्य निर्देशिका वास्तव में commit1राज्य में नहीं है , तो आपको वास्तव में राज्य से सब कुछ कॉपी करना चाहिए commit2...
Cascabel

जवाबों:


118

निम्नलिखित कमांड का प्रयास करें, जिसे मैंने परीक्षण किया है:

$ cp -pv --parents $(git diff --name-only) DESTINATION-DIRECTORY

2
cp --parentsसंकेत के लिए धन्यवाद , मैं वर्षों से उस विकल्प को चाहता था और यह कभी नहीं जानता था कि यह अस्तित्व में है! ..obviously मैं कभी नहीं = \ या तो इसे देखने के लिए परेशान
स्टीफ़न हेनिंगसन

2
ध्यान दें कि यह मैक पर काम नहीं करता है, क्योंकि --parentsविकल्प cpउपलब्ध नहीं है।
एम। जस्टिन

यदि फ़ाइलों में असामान्य वर्ण हैं, तो इसका उपयोग करने के लिए कोई सुझाव? व्हॉट्सएप, नॉर्डिक कैरेक्टर।
हैलवर होल्स्टेन स्ट्रैंड

@ हेलोरस्ट्रैंड, मैंने इसका परीक्षण नहीं किया है, लेकिन सेटिंग IFS=$'\n'पहले कर सकती है। (अधिमानतः एक उपधारा में ताकि अपने मूल IFS मूल्य को गड़बड़ाने के लिए नहीं।)
वाइल्डकार्ड

मुझे cp: cannot stat 'git diff --name-only': No such file or directoryविंडोज़ पर गिट बैश की त्रुटि मिल रही है । मैं क्या गलत कर रहा हूं? गंतव्य-निर्देशिका मौजूद है
शिव

14

निम्नलिखित ठीक काम करना चाहिए:

git diff -z --name-only commit1 commit2 | xargs -0 -IREPLACE rsync -aR REPLACE /home/changes/protected/

आगे समझाने के लिए:

  • -zसाथ करने के लिए git diff --name-onlyउत्पादन के लिए साधन NUL साथ अलग फ़ाइलों की सूची नई-पंक्तियों के बजाय बाइट्स, अगर आपके फ़ाइलनामों उन में असामान्य वर्ण की है।

  • -0करने के लिए xargsमानकों का एक NUL अलग की गई सूची के रूप में मानक इनपुट व्याख्या करने के लिए कहते हैं।

  • -IREPLACEजरूरत है डिफ़ॉल्ट रूप से के बाद से xargsके अंत में पैरामीटर संलग्न करेंगे rsyncआदेश। इसके बजाय, यह कहता है कि उन्हें बाद REPLACEमें कहां रखा जाए । (यह इस सर्वर दोष उत्तर से एक अच्छा संकेत है ।)

  • -aकरने के लिए पैरामीटर rsyncसाधन अनुमतियाँ, स्वामित्व, आदि यदि संभव हो संरक्षित करने के लिए। -Rजब गंतव्य में फ़ाइलों को बनाना है, जिसका पूर्ण रिश्तेदार पथ का उपयोग करने के लिए।

अद्यतन: यदि आपके पास एक पुराना संस्करण है xargs, तो आपको -iइसके बजाय विकल्प का उपयोग करना होगा -I। (पूर्व के बाद के संस्करणों में पदावनत किया गया है findutils।)


यह अजीब है - आप किस ऑपरेटिंग सिस्टम का उपयोग कर रहे हैं? यदि यह लिनक्स वितरण है, तो कौन सा, और क्या xargs --versionकहता है?
मार्क लोंगेयर

1
आह, xargs के उस संस्करण में आपको -iइसके बजाय उपयोग करने की आवश्यकता है , जिसे बाद के संस्करणों में हटा दिया गया है - 4.1 अब काफी पुराना है। मैं अपना जवाब अपडेट करूंगा।
मार्क लॉन्गेयर

@ मर्क: मुझे याद है कि कहीं न कहीं आपको -Iकुछ संस्करणों के बाद एक स्थान की आवश्यकता है , इसलिए शायद -I REPLACEइसके बजाय प्रयास करें ।
मिकेल

कोई बात नहीं। वह भी काम नहीं करता है। -Iकेवल findutils४.२.१० के बाद से समर्थित है , दिसंबर २००४ को जारी किया गया।
मिकेल

आपको --diff-filter=dसूची से हटाई गई फ़ाइलों को बाहर करने के लिए जोड़ना चाहिए । अन्यथा आप परिवर्तन फ़ोल्डर में उन्हें कॉपी करने का प्रयास करते समय त्रुटियों को समाप्त करेंगे। अन्यथा महान जवाब। धन्यवाद!
taymless

11

यहाँ एक लाइनर है:

परिवर्तित फ़ाइलों को सूचीबद्ध करें और उन्हें * .zip के रूप में पैक करें:

git diff --name-only | zip patched.zip -@

अंतिम रूप से परिवर्तित फ़ाइलों की सूची बनाएं और उन्हें * .zip के रूप में पैक करें:

git diff --name-only HEAD~ HEAD | zip patched.zip -@

यदि आप विंडोज़ का उपयोग कर रहे हैं तो आप sourceforge.net/projects/gnuwin32/files/zip
Radon8472

@ Radon8472 जो स्थापित करता है sed.exe? मैं अभी भी zipखिड़कियों पर नहीं मिल रहा हूँ ।
शिव

नहीं, लिंक sed के लिए zip.exe के लिए डाउनलोड की ओर इशारा कर रहा है। यदि आप कमांडलाइन में ज़िप का उपयोग नहीं कर सकते हैं, तो आपको उस फ़ोल्डर को जोड़ना चाहिए जहां zip.exe आपके PATHएनवी चर पर स्थापित है ।
रादोन .४ Rad२



2

यह पूरी तरह से काम करता है।

git diff 1526043 82a4f7d --name-only | xargs zip update.zip

git diff 1526043 82a4f7d --name-only |xargs -n 10 zip update.zip

1

किसी ने भी उल्लेख नहीं किया है cpioजो टाइप करना आसान है, हार्ड लिंक बनाता है और फ़ाइल नाम में रिक्त स्थान संभालता है:

git diff --name-only $from..$to  | cpio -pld outdir
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.