एक दूरस्थ गिट रिपॉजिटरी से विशिष्ट प्रतिबद्धता को पुनः प्राप्त करें


189

क्या मेरे पीसी पर क्लोनिंग के बिना रिमोट गिट रेपो से केवल एक विशिष्ट कमिटमेंट प्राप्त करने का कोई तरीका है? रिमोट रेपो की संरचना बिल्कुल मेरी जैसी ही है और इसलिए कोई टकराव नहीं होगा, लेकिन मुझे नहीं पता कि यह कैसे करना है और मैं उस विशाल भंडार का क्लोन नहीं बनाना चाहता।

मैं गित में नया हूं, क्या कोई रास्ता है?


1
क्या आपका मौजूदा रेपो पहले से ही रिमोट का क्लोन है, या यह पूरी तरह से अलग है?
चार्ल्स

खैर, रेपो लिनक्स कर्नेल स्रोत है, और इसका बहुत ही समान है
वरुण चित्रे

तो यह एक क्लोन है या नहीं?
चार्ल्सबी

1
बिल्कुल नहीं। इस पर विचार करें, रिमोट रेपो डी पर है और मेरा सिर ए पर है और बी, सी, डी के पीछे है। मैं एक रेपो और सी से दूसरे और डी से एक और बी से बी, सी के रूप में प्रतिबद्ध मर्ज करना चाहता हूं, इन रिपोज में डी अपनी खुद की विशेषताओं के साथ अलग हैं
वरुण चित्रे

1
@VarunChitre क्या आप VonC के दूसरे उत्तर को स्वीकार कर सकते हैं?
चार्ल्सब

जवाबों:


109

Git संस्करण 2.5+ (Q2 2015) से शुरू होकर, एक एकल कमिट (पूर्ण रेपो की क्लोनिंग के बिना) प्राप्त करना वास्तव में संभव है।

फ्रेड्रिक मेडले द्वारा प्रतिबद्ध 68ee628 देखें ( moroten) , 21 मई 2015 ( जूनियो सी हमानो द्वारा
विलय - gitster- in a9d3493 , 01 जून 2015)

अब आपके पास एक नया कॉन्फ़िगरेशन है (सर्वर की तरफ)

uploadpack.allowReachableSHA1InWant

upload-packकिसी ऐसे रेफरी के अनुरोध को स्वीकार करने की अनुमति दें जो किसी भी रेफ टिप से पहुंच योग्य वस्तु के लिए पूछता है। हालांकि, ध्यान दें कि ऑब्जेक्ट की वास्तविकता की गणना करना कम्प्यूटेशनल रूप से महंगा है।
के लिए चूक false

यदि आप उस सर्वर-साइड कॉन्फ़िगरेशन को एक उथले क्लोन ( git fetch --depth=1) के साथ जोड़ते हैं , तो आप एक सिंगल कमिट के लिए पूछ सकते हैं (देखें t/t5516-fetch-push.sh:

git fetch --depth=1 ../testrepo/.git $SHA1

आप यह git cat-fileदेखने के लिए आदेश का उपयोग कर सकते हैं कि कमिट किया गया है:

git cat-file commit $SHA1

" git upload-pack" वह कार्य करता है " git fetch" उन कमिटों की सेवा करने के लिए कहा जा सकता है जो किसी भी रेफरी की नोक पर नहीं हैं, जब तक कि वे uploadpack.allowReachableSHA1InWant कॉन्फ़िगरेशन वेरिएबल के साथ एक रेफ से पहुंच से बाहर हैं ।


पूर्ण प्रलेखन है:

upload-pack: वैकल्पिक रूप से पुनः प्राप्त करने की अनुमति देना sha1

uploadpack.allowReachableSHA1InWantसर्वर साइड पर सेट किए गए कॉन्फ़िगरेशन विकल्प के साथ , " git fetch" एक "वांट" लाइन के साथ एक अनुरोध कर सकता है जो एक ऑब्जेक्ट का नाम देता है जिसे विज्ञापित नहीं किया गया है (संभवतः बैंड से या सबमॉड्यूल पॉइंटर से प्राप्त किया गया है)।
केवल शाखा युक्तियों से प्राप्य वस्तुएं, अर्थात विज्ञापित शाखाओं और शाखाओं के संघ द्वारा छिपी हुई transfer.hideRefs, संसाधित की जाएंगी।
ध्यान दें कि रीचैबिलिटी की जांच करने के लिए इतिहास को वापस चलने की एक संबद्ध लागत है।

इस सुविधा का उपयोग एक निश्चित प्रतिबद्ध की सामग्री प्राप्त करते समय किया जा सकता है, जिसके लिए sha1 ज्ञात है, पूरे रिपॉजिटरी की क्लोनिंग की आवश्यकता के बिना, खासकर अगर एक उथले लाने का उपयोग किया जाता है

उपयोगी मामले उदाहरण के लिए हैं

  • इतिहास में बड़ी फ़ाइलों वाली रिपॉजिटरी,
  • सबमॉड्यूल चेकआउट के लिए केवल आवश्यक डेटा प्राप्त करना,
  • जब यह बताए बिना कि सही संख्या में परिवर्तन संख्याओं के बजाए Gerrit में कौन सी और किस शाखा में है, बिना बताए sha1 साझा करना।
    (गेरिट मामले को पहले ही हल कर लिया गया है allowTipSHA1InWantक्योंकि हर गेरिट परिवर्तन में एक रेफरी है।)

Git 2.6 (Q3 2015) उस मॉडल में सुधार करेगा।
देखें 2bc31d1 प्रतिबद्ध , cc118a6 प्रतिबद्ध द्वारा (28 जुला 2015) जेफ राजा ( peff)
(द्वारा विलय Junio सी Hamano - gitster- में प्रतिबद्ध 824a0be , 19 अगस्त 2015)

refs: नकारात्मक का समर्थन करें transfer.hideRefs

यदि आप transfer.hideRefsकॉन्फ़िगरेशन का उपयोग करके रेफरी की पदानुक्रम छिपाते हैं , तो बाद में उस कॉन्फ़िगरेशन को "अनहाइड" करने के लिए ओवरराइड करने का कोई तरीका नहीं है।
यह पैच एक "नकारात्मक" छिपाने का कारण बनता है, जिसके कारण मैच को तुरंत अस्वीकार कर दिया जाता है, भले ही दूसरा मैच इसे छिपाए।
हम मैच को रिवर्स-ऑर्डर में लागू करने के लिए ध्यान रखते हैं कि कैसे वे हमें कॉन्फ़िगर मशीनरी द्वारा खिलाए जाते हैं, क्योंकि इससे हमारे सामान्य "पिछले एक" कॉन्फ़िगरेशन की पूर्ववर्ती जीत (और प्रविष्टियों में .git/config, उदाहरण के लिए, ओवरराइड हो जाएगी /etc/gitconfig)।

तो आप अब कर सकते हैं:

git config --system transfer.hideRefs refs/secret
git config transfer.hideRefs '!refs/secret/not-so-secret'

refs/secretसभी रेपो में छिपाने के लिए, एक विशिष्ट रेपो में एक सार्वजनिक बिट को छोड़कर।


Git 2.7 (नवंबर / दिसंबर 2015) में फिर से सुधार होगा:

प्रतिबद्ध देखें 948bfa2 , प्रतिबद्ध 00b293e (05 नवंबर 2015), 78a766a के लिए प्रतिबद्ध , 92cab49 के लिए , 92cab49 के लिए प्रतिबद्ध , 92cab49 (03 नवंबर 2015) के लिए, 00b293e के लिए प्रतिबद्ध करें , 00b293e (05 नवंबर 2015) के लिए, और 92cab49 के लिए , 92cab49 के लिए प्रतिबद्ध हैंLukas Fleischer ( ) द्वारा 92cab49 (03 नवंबर 2015) प्रतिबद्ध है । मदद-द्वारा: एरिक सनशाइन ( )(द्वारा विलय जेफ राजा - - में dbba85e प्रतिबद्ध , 20 नवंबर 2015)lfos
sunshineco
peff

config.txt: hideRefsनाम स्थान के साथ शब्दार्थ का दस्तावेज

अभी, कोई स्पष्ट परिभाषा नहीं है कि transfer.hideRefsनाम स्थान सेट होने पर व्यवहार कैसे करना चाहिए।
बता दें कि hideRefsउपसर्ग उस मामले में छीन लिए गए नामों से मेल खाते हैं। इस तरह से hideRefsपैटर्न वर्तमान में प्राप्त-पैक में संभाला जाता है।

HideRefs: पूर्ण रेफरी मिलान के लिए समर्थन जोड़ें

hideRefsस्ट्रिप्ड रेफ के मिलान के अलावा, अब एक पैटर्न जोड़ सकते हैं कि पूर्ण (अनस्ट्रिप्ड) रेफ के विरुद्ध मिलान किया जाता है।
छीनने और पूर्ण मैचों के बीच अंतर करने के लिए, उन नए पैटर्न को एक परिधि ( ^) के साथ उपसर्ग करना चाहिए ।

इसलिए नया दस्तावेज़ :

transfer.hideRefs:

यदि कोई नामस्थान उपयोग में है, तो प्रत्येक संदर्भ से नाम स्थान उपसर्ग छीन लिया जाता है, इससे पहले कि वह transfer.hiderefsपैटर्न से मेल खाता हो ।
उदाहरण के लिए, यदि refs/heads/masterमें निर्दिष्ट किया जाता transfer.hideRefsहै और वर्तमान नाम स्थान है foo, तो refs/namespaces/foo/refs/heads/master विज्ञापनों से छोड़ दिया जाता है, लेकिन refs/heads/masterऔर refs/namespaces/bar/refs/heads/masterअभी भी तथाकथित "है" लाइनों के रूप में विज्ञापित कर रहे हैं।
स्ट्रिपिंग से पहले Refs से मिलान करने के लिए, ^Ref नाम के सामने एक जोड़ दें । यदि आप संयोजन करते हैं !और ^, !पहले निर्दिष्ट किया जाना चाहिए।


आर .. में टिप्पणियों का उल्लेख हैuploadpack.allowAnySHA1InWant , जो कि किसी भी वस्तु के लिए पूछने वाले अनुरोध upload-packको स्वीकार करने की अनुमति देता है fetch। (चूक false)।

डेविड "नोवलिस" टर्नर ( ) द्वारा देखें प्रतिबद्ध f8edeaa (Nov. 2016, Git v2.11.1) देखें :novalis

upload-pack: वैकल्पिक रूप से किसी भी sha1 को लाने की अनुमति दें

यह उस मामले में एक रीचबिलिटी चेक करने के लिए थोड़ा मूर्खतापूर्ण लगता है जहां हम उपयोगकर्ता को रिपॉजिटरी में पूरी तरह से सब कुछ एक्सेस करने के लिए भरोसा करते हैं।

इसके अलावा, यह एक वितरित प्रणाली में दोष है - शायद एक सर्वर एक रेफरी का विज्ञापन करता है, लेकिन दूसरे ने तब से उस रेफरी को एक बल-धक्का दिया है, और शायद दो HTTP अनुरोध इन अलग-अलग सर्वरों को निर्देशित करते हैं।


4
क्या आप इस एकल वचन के साथ रेपो क्लोन बनाने के बारे में अधिक संपूर्ण उदाहरण दे सकते हैं? मैंने कोशिश की लेकिन असफल रहा .. धन्यवाद!
लार्स बिल्के

1
मैं गिटहब को धक्का देना चाहता हूं। शायद वे इसकी अनुमति नहीं देते।
लार्स बिल्के

2
@LarsBilke हम यहाँ क्लोन या पुल के बारे में बात कर रहे हैं, पुश नहीं। और मुझे पूरा यकीन है कि GitHub के पास अभी तक सर्वर पर Git 2.5 नहीं है।
VONC

2
अब और भी बेहतर, वहाँ uploadpack.allowAnySHA1InWantपुनरावर्तनीयता-संगणना दंड (और DoS वेक्टर) के बिना है।
आर .. गिटहब स्टॉप हेल्पिंग आईसीई

1
धन्यवाद! मुझे यह मज़ेदार लगता है कि वे इसे "उपयोग करने के लिए उपयोगकर्ता पर विश्वास" के बजाय "रेपो लेखकों पर भरोसा करने के लिए यादृच्छिक बकवास को धक्का नहीं देने का भरोसा करते हैं जो वे सार्वजनिक करने का इरादा नहीं रखते हैं"।
R .. GitHub STOP हेल्पिंग ICE

97

आप केवल एक बार क्लोन करते हैं, इसलिए यदि आपके पास पहले से ही रिमोट रिपॉजिटरी का क्लोन है, तो इससे खींचने से सब कुछ फिर से डाउनलोड नहीं होगा। बस इंगित करें कि आप किस शाखा को खींचना चाहते हैं, या परिवर्तनों को प्राप्त करना चाहते हैं और जो आप चाहते हैं उसे चेकआउट करें।

एक नए भंडार से प्राप्त करना बैंडविड्थ में बहुत सस्ता है, क्योंकि यह केवल उन परिवर्तनों को डाउनलोड करेगा जो आपके पास नहीं हैं। न्यूनतम भार के साथ, सही काम करने वाले गिट के संदर्भ में सोचें।

Git .gitफ़ोल्डर में सब कुछ संग्रहीत करता है । एक कमिट को अलग नहीं किया जा सकता है और उसे अलग-थलग किया जा सकता है। वे परस्पर जुड़े हुए हैं


हालांकि, डाउनलोड आकार को कम करने के लिए आप किसी विशिष्ट शाखा या कमिट से संबंधित वस्तुओं को लाने के लिए पूछ सकते हैं:

git fetch origin refs/heads/branch:refs/remotes/origin/branch

यह केवल दूरस्थ शाखा में निहित कमिट्स को डाउनलोड करेगा branch (और केवल वे जिन्हें आप याद करते हैं) , और इसे स्टोर करें origin/branch। फिर आप मर्ज या चेकआउट कर सकते हैं।

आप केवल एक SHA1 प्रतिबद्ध भी निर्दिष्ट कर सकते हैं:

git fetch origin 96de5297df870:refs/remotes/origin/foo-commit

यह केवल निर्दिष्ट SHA-1 96de5297df870 (और इसके पूर्वजों को जो आप याद करते हैं) की प्रतिबद्धता को डाउनलोड करेंगे, और इसे (गैर-मौजूदा) दूरस्थ शाखा के रूप में संग्रहीत करेंगे origin/foo-commit


3
ऐसा लगता है कि आप क्लोन बनाने का मतलब क्या है पर भ्रम बना रहे हैं। जब आप एक दूरस्थ रेपो से परिवर्तन लाते हैं, तो आप इसे क्लोन नहीं करते हैं, तो आपको अपने इतिहास में केवल कमिट्स मिलते हैं। फिर आप चुनते हैं कि आप कौन सा
कमिटमेंट

1
यह अभी भी बहुत सारे डेटा (430mb) को git fetch के साथ डाउनलोड करता है। आवश्यक कमिट कुछ ही kbs है। वास्तव में ऐसा करने के लिए कोई विशेष आदेश नहीं है? और क्या होगा यदि मैं 'git fetched' रेपो को हटाना चाहता हूँ? यह कहाँ संग्रहीत है?
वरुण चित्र

9
यह अब पुराना नहीं है। हमारे पास एक उथले क्लोन का प्रदर्शन करने की क्षमता है , साथ ही एक भी प्रतिबद्धता लाने के लिए । प्रोजेक्ट के पूरे इतिहास को जानने के बिना, उथले क्लोनों को अब सामान्य रूप से धकेलने और लाने की अनुमति दी जाती है, इसलिए यह कहना अब सही नहीं होगा कि एक प्रतिबद्ध अपने पूर्वजों के बिना अकेले मौजूद नहीं रह सकता है। प्रारंभिक क्लोन के बाद आपको भ्रूण के बारे में जो कहना है वह बहुत सही है, लेकिन हमारे पास सस्ता विकल्प भी है।
थियोडोर मर्डॉक

6
अंतिम कमांड (SHA1 कमिट का उपयोग करके) मेरे लिए काम नहीं करता है। आदेश चुपचाप थोड़ी देर के लिए "कुछ" करता है, और फिर कोई संदेश या स्पष्ट साइड-इफेक्ट के साथ बाहर निकलता है।
HRJ

1
@ एचआरजे हां, मुझे इसका सामना Ubuntu 16.04 पर गिट के साथ भी करना पड़ा 2.7.4-0ubuntu1.3। हालांकि, 2.16.2-0ppa1~ubuntu16.04.1गिट-कोर पीपीए से उपयोग करते समय , यह काम करना चाहिए। एक बग की तरह लगता है जो तय हो गया। त्वरित खोज के साथ इसका संदर्भ नहीं मिल सका। अगर कोई मुझे उस पर एक संकेतक प्राप्त कर सकता है, तो मुझे यह फिक्स बैकपोर्ट प्राप्त करना अच्छा लगेगा।
gertvdijk

62

मैंने अपने गिट रेपो पर एक पुल किया:

git pull --rebase <repo> <branch>

शाखा के लिए सभी कोड को खींचने की अनुमति देते हुए और फिर मैं उस कमिट पर एक रीसेट करने के लिए गया, जिसमें मेरी दिलचस्पी थी।

git reset --hard <commit-hash>

उम्मीद है की यह मदद करेगा।


1
जवाब में से किसी ने भी काम नहीं किया, हालांकि इसने मेरी जान बचाई! बहुत बहुत धन्यवाद!
michaeltintiuc

क्लोनिंग के बाद रीसेट -हार्ड ने मेरे लिए काम किया! धन्यवाद।
निक-एसीएनबी

3
-1: "विध्वंसक" जैसे आदेश git reset --hard, सामान्यीकृत समाधानों में साझा किए जाने पर, लोगों को जाल में ले जा सकते हैं, जहां वे डेटा खो देते हैं (या, इस मामले में: ऐसी स्थिति में जहां उनका डेटा वापस प्राप्त करना असम्भव है)।
यियूआई

54

आप बस के साथ एक दूरस्थ रेपो की एक भी प्रतिबद्धता ला सकते हैं

git fetch <repo> <commit>

कहाँ पे,

  • <repo>एक दूरस्थ रेपो नाम (जैसे origin) या यहां तक ​​कि एक दूरस्थ रेपो URL (जैसे https://git.foo.com/myrepo.git) हो सकता है
  • <commit> SHA1 प्रतिबद्ध हो सकता है

उदाहरण के लिए

git fetch https://git.foo.com/myrepo.git 0a071603d87e0b89738599c160583a19a6d95545

आपके द्वारा कमिटमेंट (और गुम हुए पूर्वजों) को प्राप्त करने के बाद आप इसे आसानी से देख सकते हैं

git checkout FETCH_HEAD

ध्यान दें कि यह आपको "अलग सिर" स्थिति में लाएगा।


10
जब मैं fetchएक विशिष्ट रेव की कोशिश करता हूं, जैसा आप वहां करते हैं, तो त्रुटि कोड 1 और कोई आउटपुट के साथ git विफल रहता है। क्या यह कुछ ऐसा था जो पिछले संस्करणों में काम करता था? (मैं v2.0.2 हूँ।)
जैक ओ'कॉनर

2
संपादित करें: यह काम करता है अगर मेरे पास पहले से ही स्थानीय रूप से प्रतिबद्ध है, जैसे कि अगर मैं पहले ही पूर्ण कर चुका हूं fetch, हालांकि उस मामले में मुझे यकीन नहीं है कि उपयोग क्या है।
जैक ओ'कॉनर

2
वास्तव में, यह मेरे लिए कोई काम नहीं लगता है git 2.0.2 के साथ या तो। :(
फ्लो

2
git checkout FETCH_HEADमदद करता है।
lzl124631x

1
यह विधि उथले लाने के साथ काम नहीं करेगी (जैसे --depth=1)!
किंगमेकरिंग

16

आप बस इसके साथ रिमोट रेपो ला सकते हैं:

git fetch <repo>

कहाँ पे,

  • <repo>एक दूरस्थ रेपो नाम (जैसे origin) या यहां तक ​​कि एक दूरस्थ रेपो URL (जैसे https://git.foo.com/myrepo.git) हो सकता है

उदाहरण के लिए:

git fetch https://git.foo.com/myrepo.git 

जब आप रिपॉजिट प्राप्त कर लेते हैं, तो आप अपने इच्छित मर्ज को मर्ज कर सकते हैं (चूंकि प्रश्न एक कमिट को पुनः प्राप्त करने के बारे में है, मर्ज करने के लिए आप चेरी-पिक का उपयोग केवल एक कमिट लेने के लिए कर सकते हैं):

git merge <commit>
  • <commit> SHA1 प्रतिबद्ध हो सकता है

उदाहरण के लिए:

git cherry-pick 0a071603d87e0b89738599c160583a19a6d95545

या

git merge 0a071603d87e0b89738599c160583a19a6d95545

यदि आप नवीनतम मर्ज करना चाहते हैं, तो आप FETCH_HEAD चर का उपयोग भी कर सकते हैं:

git cherry-pick (or merge) FETCH_HEAD

इसके लिए मशीन पर Git अकाउंट सेटअप की आवश्यकता होती है। यह एक परीक्षण खाते के तहत काम नहीं करता है। क्या आपके पास कुछ है जो एक परीक्षण खाते के तहत काम करता है?
jww

आपका मतलब क्या है ? आप नहीं ला सकते हैं?
सेर्गियो

उम्मम तो आज्ञा होगी git config set uploadpack.allowReachableSHA1InWant ?
अलेक्जेंडर मिल्स

2

यह सबसे अच्छा काम करता है:

git fetch origin specific_commit
git checkout -b temp FETCH_HEAD

नाम "अस्थायी" जो आप चाहते हैं ... यह शाखा यद्यपि अनाथ हो सकती है


स्पष्ट रूप से 1.8.x जैसे पुराने git संस्करणों के साथ नहीं
sorin

1

अंत में मुझे git चेरी-पिक का उपयोग करके विशिष्ट प्रतिबद्ध क्लोन करने का एक तरीका मिला । मान लें कि आपके पास स्थानीय में कोई रिपॉजिटरी नहीं है और आप रिमोट से विशिष्ट प्रतिबद्ध खींच रहे हैं,

1) स्थानीय और गिट इनिट में खाली भंडार बनाएँ

2) git रिमोट ऐड ओरिजिनल " url-of-repository "

3) git लाने का मूल [यह आपकी फ़ाइलों को आपके स्थानीय कार्यक्षेत्र में स्थानांतरित नहीं करेगा जब तक आप विलय नहीं करते]

4) git चेरी-पिक " एंटर-लॉन्ग-कमिट-हैश-दैट यू-यू-नीड "

किया। इस तरह, आप केवल अपने स्थानीय में उस विशिष्ट प्रतिबद्ध से फाइल होगा।

दर्ज-लंबी प्रतिबद्ध-हैश:

आप इसका उपयोग कर सकते हैं -> गिट लॉग - व्याख्या = ऑनलाइन



0

यदि अनुरोधित प्रतिबद्ध रिमोट रेपो के पुल अनुरोधों में है, तो आप इसकी आईडी द्वारा प्राप्त कर सकते हैं:

# Add the remote repo path, let's call it 'upstream':
git remote add upstream https://github.com/repo/project.git

# checkout the pull ID, for example ID '60':
git fetch upstream pull/60/head && git checkout FETCH_HEAD
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.