मूल / HEAD कैसे सेट किया जाता है?


144

मेरे पास मूल में रेफरी को ट्रैक करने के लिए एक शाखा है। git checkout <branchname>उस शाखा पर स्विच करता है, और git statusमुझे दिखाएगा कि मेरी शाखा मूल से कितनी आगे या पीछे है, लेकिन मुझे आश्चर्य है कि origin/HEADअभी भी उस बिंदु पर है origin/masterऔर नहींorigin/<branchname>

तो मेरा सवाल यह है कि किन परिस्थितियों में मूल / HEAD स्थानांतरित होता है?

संपादित करें:

मैं मूल / HEAD को स्थानांतरित करने के तरीके के बारे में उत्तरों की सराहना करता हूं , लेकिन मुझे इसमें "संगठनात्मक" तरीके से दिलचस्पी है कि यह कैसे आगे बढ़ता है, मेरे बाहर स्पष्ट रूप से ऐसा करने के लिए कह रहा है।

उदाहरण के लिए, जब मैं शाखाओं को स्विच करता हूं, तो मैं जिस शाखा की जांच कर रहा हूं, उस बिंदु पर हेड बनाता है, इसलिए मुझे आश्चर्य होता है कि उत्पत्ति / हेड उसी तरीके से नहीं चलती है।


ध्यान दें कि यह प्रश्न रीमोट पर स्थानीय प्रतीकात्मक संदर्भों के बारे में है, जैसे refs/origin/HEAD। यह इस बारे में नहीं है कि एक रिपॉजिटरी का अपना प्रतीकात्मक संदर्भ कैसे HEADसेट हो जाता है।
क्लैके

जवाबों:


173

पहले ध्यान दें कि आपका प्रश्न गलतफहमी को दर्शाता है। मूल / HEAD रिमोट पर डिफ़ॉल्ट शाखा का प्रतिनिधित्व करता है , यानी HEAD उस दूरस्थ रिपॉजिटरी में जिसे आप मूल कह रहे हैं। जब आप अपने रेपो में शाखाएँ बदलते हैं, तो आप उस पर प्रभाव नहीं डाल रहे हैं। दूरस्थ शाखाओं के लिए भी यही सच है; आपके पास masterऔर origin/masterआपके रेपो में हो सकता है , जहां दूरस्थ रिपॉजिटरी में शाखा origin/masterकी एक स्थानीय प्रतिलिपि का प्रतिनिधित्व करता masterहै।

उत्पत्ति का HEAD केवल तभी बदलेगा जब आप या कोई और वास्तव में इसे दूरस्थ रिपॉजिटरी में बदलता है , जो मूल रूप से कभी नहीं होना चाहिए - आप चाहते हैं कि डिफ़ॉल्ट शाखा स्थिर रहने के लिए एक सार्वजनिक रिपो हो, स्थिर शाखा (शायद मास्टर) पर। मूल / HEAD दूरस्थ रिपॉजिटरी में HEAD की एक स्थानीय प्रति का प्रतिनिधित्व करने वाला एक स्थानीय रेफरी है। (इसका पूरा नाम refs / remotes / उत्पत्ति / HEAD है।)

मुझे लगता है कि उपरोक्त उत्तर जो आप वास्तव में जानना चाहते थे, लेकिन आगे बढ़ने और उस प्रश्न का उत्तर देने के लिए जिसे आपने स्पष्ट रूप से पूछा है ... मूल / HEAD स्वचालित रूप से सेट होता है जब आप एक रिपॉजिटरी क्लोन करते हैं, और इसके बारे में। विचित्र रूप से, कि यह आज्ञाओं द्वारा निर्धारित नहीं है , जैसे git remote update- मुझे विश्वास है कि यह एकमात्र तरीका है यदि आप इसे मैन्युअल रूप से बदलते हैं। (परिवर्तन से मेरा अभिप्राय एक अलग शाखा से है; स्पष्ट रूप से यह उस परिवर्तन की ओर इशारा करता है यदि वह शाखा बदल जाती है, जो लाने / खींचने / दूरस्थ अद्यतन पर हो सकती है।)


संपादित करें : नीचे चर्चा की गई समस्या Git 1.8.4.3 में ठीक की गई थी ; इस अद्यतन को देखें ।


हालांकि, एक छोटा कैवेट है। HEAD एक प्रतीकात्मक रेफ है, जो सीधे तौर पर कमिट करने के बजाय एक ब्रांच की ओर इशारा करता है, लेकिन git रिमोट ट्रांसफर प्रोटोकॉल केवल रिपोर्ट ही refs के लिए शुरू होता है। तो जीआईटी को एचएएडी और अन्य सभी रिफ द्वारा बताए गए कमेटी के एसएचए 1 का पता है; इसके बाद उसी शाखा को खोजने के लिए HEAD के मूल्य को कम करना पड़ता है जो एक ही प्रतिबद्ध की ओर इशारा करता है। इसका मतलब यह है कि अगर दो शाखाएँ वहाँ इंगित करती हैं, तो यह अस्पष्ट है। (मेरा मानना ​​है कि यदि यह संभव हो तो गुरु को चुनता है, फिर पहले वर्णानुक्रम में वापस आता है।) आप इसे आउटपुट में रिपोर्ट करेंगे git remote show origin:

$ git remote show origin
* remote origin
  Fetch URL: ...
  Push  URL: ...
  HEAD branch (remote HEAD is ambiguous, may be one of the following):
    foo
    master

अजीब तरह से, हालांकि इस तरह से मुद्रित हेड की धारणा बदल जाएगी यदि रिमोट पर चीजें बदल जाती हैं (जैसे कि अगर फू को हटा दिया जाता है), तो यह वास्तव में अपडेट नहीं करता है refs/remotes/origin/HEAD। यह वास्तव में विषम परिस्थितियों को जन्म दे सकता है। यह कहें कि उपरोक्त उदाहरण में उत्पत्ति / HEAD वास्तव में धूआं करने के लिए इंगित किया गया था, और मूल की फू शाखा को हटा दिया गया था। हम फिर ऐसा कर सकते हैं:

$ git remote show origin
...
HEAD branch: master
$ git symbolic-ref refs/remotes/origin/HEAD
refs/remotes/origin/foo
$ git remote update --prune origin
Fetching origin
 x [deleted]         (none)     -> origin/foo
   (refs/remotes/origin/HEAD has become dangling)

इसलिए भले ही रिमोट शो जानता है कि हेड मास्टर है, यह कुछ भी अपडेट नहीं करता है। बासी फू शाखा को सही ढंग से काट दिया जाता है, और HEAD झूलने लगता है (एक नॉनवेज शाखा की ओर इशारा करते हुए), और यह अभी भी इसे मास्टर को इंगित करने के लिए अपडेट नहीं करता है। यदि आप इसे ठीक करना चाहते हैं, तो उपयोग करें git remote set-head origin -a, जो स्वचालित रूप से ऊपर के रूप में उत्पत्ति के HEAD को निर्धारित करता है, और फिर वास्तव में उपयुक्त दूरस्थ शाखा को इंगित करने के लिए उत्पत्ति / HEAD सेट करता है।


@ जेफ्रोमी बहुत बढ़िया जवाब! बस एक टिप्पणी: आप लिखते हैं कि HEAD एक प्रतीकात्मक रेफरी है, जो सीधे एक प्रतिबद्ध [...] के बजाय एक शाखा की ओर इशारा करता है , लेकिन यह "पूर्ण राज्य के लिए अलग राज्य" का उल्लेख करने योग्य हो सकता है।
जुब।

2
@ जॉब्स थैंक्स! यदि मेरे जवाब को अपडेट करने की आवश्यकता है, तो कृपया इसे बस संपादित करने के लिए स्वतंत्र महसूस करें, हालांकि - यह निश्चित रूप से लोगों का समय बचाएगा कि दो साल पहले क्या सच था और अब क्या सच है के माध्यम से हल करने के बजाय चीजें वास्तव में कैसे काम करती हैं। ।
कास्केबेल

कम से कम 5 बार इसे पढ़ चुके हैं और अभी भी इसका कुछ समझ नहीं आया है
krb686

7
git remote set-head origin -aमेरे लिए काम किया
शुजितो

75

यह आपके स्थानीय रेपो के मालिक के रूप में आपकी सेटिंग है। इसे इस तरह बदलें:

git remote set-head origin some_branch

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

रिमोट सेट-हेड के लिए मैनुअल प्रविष्टि इस पर कुछ अच्छी जानकारी प्रदान करती है।

संपादित करें: जोर देने के लिए: आप इसे बताए बिना, यह "चाल" करने का एकमात्र तरीका मास्टर शाखा का नाम बदलने जैसा होगा , जो मुझे नहीं लगता कि "कार्बनिक" माना जाता है। इसलिए, मैं कहूंगा कि यह व्यवस्थित नहीं है।


1
संपादित जोर यहां पूरी तरह से सही नहीं है। यदि आप किसी स्थानीय प्रतिलिपि से मास्टर शाखा पर नहीं हैं तो यह भी बदल सकता है।
एमफैयर

मैं एक क्लोन "चलती" पर विचार नहीं करता, लेकिन मुझे लगता है कि हम उस पर असहमत हो सकते हैं :)
eis

24

क्या मूल / HEAD "व्यवस्थित" चलता है?

  • git clone इसे एक बार उस स्थान पर सेट करें जहां HEAD मूल पर है
    • यह क्लोनिंग के बाद चेकआउट करने के लिए डिफ़ॉल्ट शाखा के रूप में कार्य करता है git clone

उत्पत्ति पर HEAD क्या दर्शाता है?

  • नंगे रिपॉजिटरी पर (अक्सर रिपॉजिटरी "सर्वर पर") यह डिफ़ॉल्ट शाखा के लिए एक मार्कर के रूप में कार्य करता है, क्योंकि git cloneइस तरह से इसका उपयोग करता है
  • गैर-नंगे रिपॉजिटरी (स्थानीय या दूरस्थ) पर, यह रिपॉजिटरी के वर्तमान चेकआउट को दर्शाता है

क्या उत्पत्ति / HEAD सेट करता है?

  • git clone इसे लाते हैं और सेट करते हैं
  • यह समझ में आता है अगर git fetchयह किसी अन्य संदर्भ की तरह अद्यतन करता है, लेकिन यह नहीं है
  • git remote set-head origin -a इसे लाते हैं और सेट करते हैं
    • रिमोट क्या "डिफ़ॉल्ट शाखा" मानता है के स्थानीय ज्ञान को अद्यतन करने के लिए उपयोगी

सामान्य ज्ञान

  • origin/HEAD रिमोट से संपर्क किए बिना किसी अन्य मूल्य पर भी सेट किया जा सकता है: git remote set-head origin <branch>
    • मुझे परीक्षण के अलावा इसके लिए कोई उपयोग-मामला नहीं दिख रहा है
  • दुर्भाग्य से कुछ भी रिमोट पर HEAD सेट करने में सक्षम नहीं है
  • git के पुराने संस्करणों को पता नहीं था कि कौन सी शाखा HEAD रिमोट पर इंगित करती है, केवल जो आखिरकार हैश करता है: इसलिए उसने उम्मीद से उसी हैश की ओर इशारा करते हुए एक शाखा का नाम चुना

मैंने इसका संदर्भ खो दिया था origin/HEADऔर आपके समाधान में मदद मिली। धन्यवाद!
java_dude

मैं git fetchइसे अपडेट करने से असहमत हूं , क्योंकि यह एक (स्थानीय) शॉर्टकट को कॉन्फ़िगर करने की अनुमति देता है। डॉक्टर का हवाला देते हुए: "रिमोट के लिए एक डिफ़ॉल्ट शाखा होने की आवश्यकता नहीं है, लेकिन एक विशिष्ट शाखा के बदले रिमोट के नाम को निर्दिष्ट करने की अनुमति देता है"। यह अजीब होगा अगर एक दूरस्थ परिवर्तन स्थानीय रूप से कॉन्फ़िगर किए गए शॉर्टकट को अपडेट करेगा।
मीका विडेनमैन

@MichaWiedenmann स्थानीय रूप से कॉन्फ़िगर शॉर्टकट क्यों होगा? स्थानीय रूप से कॉन्फ़िगर किए गए शॉर्टकट के origin/HEADलिए एक बुरा नाम है। और जो git clone"स्थानीय रूप से कॉन्फ़िगर की गई शाखा" के लिए एक डिफ़ॉल्ट के रूप में एक दूरस्थ नाम का उपयोग करता है, वह भी विरोधाभासी है। गैर-नंगे रिपॉजिटरी पर यह रिमोट के करंट का उपयोग करने के लिए भी समझ में नहीं आता है HEAD
रॉबर्ट सिएमर

10

डिस्क्लेमर : यह जेफ्रोमी के जवाब का अपडेट है , जो मैं उत्सुक को बचाने के लिए लिख रहा हूं।

मैंने व्यर्थ में (गीट 2.0.1 में) remote HEAD is ambiguousसंदेश देने की कोशिश की कि जेफ्रोमी अपने जवाब में उल्लेख करता है; इसलिए मैंने थोड़ी खुदाई ( https://github.com/git/git पर क्लोन करके और लॉग को खोजकर) की। ऐसा हुआ करता था

Determining HEAD is ambiguous since it is done by comparing SHA1s.

In the case of multiple matches we return refs/heads/master if it
matches, else we return the first match we encounter. builtin-remote
needs all matches returned to it, so add a flag for it to request such.

(प्रतिबद्ध 4229f1fa325870d6b24fe2a4c7d2ed5f14c6f771, दिनांक 27 फरवरी, 2009, के साथ मिला git log --reverse --grep="HEAD is ambiguous")

हालाँकि, प्रश्न में अस्पष्टता को हटा दिया गया है :

One long-standing flaw in the pack transfer protocol used by "git
clone" was that there was no way to tell the other end which branch
"HEAD" points at, and the receiving end needed to guess.  A new
capability has been defined in the pack protocol to convey this
information so that cloning from a repository with more than one
branches pointing at the same commit where the HEAD is at now
reliably sets the initial branch in the resulting repository.

(प्रतिबद्ध 9196a2f8bd46d36a285bdfa03b4540ed3f01f671, दिनांक 8 नवंबर, 2013 के साथ मिला git log --grep="ambiguous" --grep="HEAD" --all-match)

संपादित करें (करने के लिए धन्यवाद torek ):

$ git name-rev --name-only 9196a2f8bd46d36a285bdfa03b4540ed3f01f671
tags/v1.8.4.3~3

इसका मतलब है कि, यदि आप Git v1.8.4.3 या बाद का उपयोग कर रहे हैं, तो आपको किसी भी अस्पष्ट- दूरस्थ- HEAD समस्या में नहीं चलना चाहिए।


1
गिट स्रोत में टैग के आधार पर, यह फिक्स संस्करण 1.8.4.3 और बाद के संस्करण पर लागू होता है।
torek

@RobertSiemer मुझे यकीन नहीं है, लेकिन मुझे ऐसा लगता है, हाँ।
जुबंस

8

याद रखें कि दो स्वतंत्र गिट प्रतिनिधि हैं जिनके बारे में हम बात कर रहे हैं। आपका स्थानीय रेपो आपके कोड के साथ और रिमोट कहीं और चल रहा है।

आपका सही है, जब आप एक शाखा बदलते हैं, तो HEAD आपकी वर्तमान शाखा को इंगित करता है। यह सब आपके स्थानीय गिट रेपो पर हो रहा है। रिमोट रेपो नहीं, जो किसी अन्य डेवलपर के स्वामित्व में हो सकता है, या आपके कार्यालय, या गिटहब, या फाइलसिस्टम, या आदि पर एक और निर्देशिका में एक गंभीर स्थिति में बैठ सकता है।

आपके कंप्यूटर (स्थानीय रेपो) में दूरस्थ गिट रेपो पर HEAD पॉइंटर को बदलने का कोई व्यवसाय नहीं है। यह उदाहरण के लिए एक अलग डेवलपर के स्वामित्व में हो सकता है।

एक और बात, जो आपके कंप्यूटर को ओरिजिनल / एक्सएक्सएक्स कहती है, वह है आपके कंप्यूटर की अंतिम अवस्था के समय रिमोट की स्थिति।

तो मूल "HEAD" को "व्यवस्थित रूप से" क्या अपडेट करेगा? यह रिमोट गिट रेपो पर गतिविधि होगी। अपने स्थानीय रेपो नहीं।

लोगों ने उल्लेख किया है

git प्रतीकात्मक-रेफ HEAD refs / head / my_other_branch

आम तौर पर, इसका उपयोग तब किया जाता है जब विकास टीम द्वारा उपयोग के लिए एक सर्वर पर एक साझा केंद्रीय गिट रेपो होता है। यह दूरस्थ कंप्यूटर पर निष्पादित एक कमांड होगी। आप इसे दूरस्थ गिट रेपो पर गतिविधि के रूप में देखेंगे।


1
क्षमा करें, यदि मैं थोड़ा दोहराव वाला हूं। मैं सिर्फ इस तथ्य को इंगित करना चाहता हूं कि गिट एक वितरित संस्करण नियंत्रण प्रणाली है, और जैसे कि दो रिपोज स्वतंत्र हैं।
पाब्लो मौरिन

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.