मुझे "पुश पुश -सेट-अपस्ट्रीम मूल <शाखा>" क्यों करना है?


146

मैंने सोलारिस और सन स्टूडियो के परीक्षण के लिए एक स्थानीय शाखा बनाई। मैंने फिर शाखा को ऊपर की ओर धकेला। एक परिवर्तन करने और परिवर्तनों को आगे बढ़ाने का प्रयास करने के बाद:

$ git commit blake2.cpp -m "Add workaround for missing _mm_set_epi64x"
[solaris 7ad22ff] Add workaround for missing _mm_set_epi64x
 1 file changed, 5 insertions(+)
$ git push
fatal: The current branch solaris has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin solaris

मुझे इसके लिए कुछ विशेष क्यों करना है?

क्या कोई उचित उपयोग का मामला है जहां कोई बनाएगा <branch>, <branch>दूरस्थ को धक्का देगा , और फिर दावा करेगा कि इसके लिए कोई प्रतिबद्धता <branch>नहीं है <branch>?


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


यहाँ एक अलग मशीन पर दृश्य है। शाखा स्पष्ट रूप से मौजूद है, इसलिए इसे बनाया गया था और धक्का दिया गया था:

$ git branch -a
  alignas
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/alignas
  remotes/origin/arm-neon
  remotes/origin/det-sig
  remotes/origin/master
  remotes/origin/solaris


2
धन्यवाद @ अलेक्सि। दुर्भाग्य से, उद्धृत डुप्लीकेट हास्यास्पद उपयोग के मामले की व्याख्या नहीं करता है जिसे डिफ़ॉल्ट रूप से दर्शाया जा रहा है। (वे अलंकारिक प्रश्न नहीं हैं। मैं वास्तव में यूएक्स डिजाइन के कारण में दिलचस्पी रखता हूं)।
jww

1
ध्यान दें कि यह विन्यास योग्य है। यदि आप करते हैं git config --add push.default current, तो यदि आवश्यक हो , तो git push अपने आप रिमोट रेपो में शाखा बना देगा।
गोगोविट्स्क

जवाबों:


271

टी एल; डॉ: git branch --set-upstream-to origin/solaris


आपके द्वारा पूछे गए प्रश्न का उत्तर - जिसे मैं थोड़ा सा दोहरा दूंगा जैसे "क्या मुझे एक अपस्ट्रीम सेट करना है" -इस: नहीं, आपको बिल्कुल अपस्ट्रीम सेट करने की आवश्यकता नहीं है

यदि आपके पास वर्तमान शाखा के लिए अपस्ट्रीम नहीं है, हालांकि, Git अपने व्यवहार को git pushऔर अन्य आदेशों पर भी बदलता है ।

यहां पूरी पुश स्टोरी लंबी और उबाऊ है और इतिहास में Git संस्करण 1.5 से पहले वापस चली जाती है। इसे पूरी तरह से छोटा करने के लिए, git pushइसे खराब तरीके से लागू किया गया था। 1 Git संस्करण 2.0 के अनुसार, Git में अब एक कॉन्फ़िगरेशन नॉब है, push.defaultजो अब डिफॉल्ट करता है simple। पहले और 2.0 के बाद Git के कई संस्करण के लिए, हर बार जब आप भाग गया git push, Git शोर सेट करने के लिए समझाने की कोशिश की बहुत सारी वमन हैं push.defaultसिर्फ पाने के लिए git pushचुप रहो करने के लिए।

आप यह उल्लेख नहीं करते हैं कि आप किस संस्करण को चला रहे हैं, न ही आपने कॉन्फ़िगर किया है या नहीं push.default, इसलिए हमें अनुमान लगाना चाहिए। मेरा अनुमान है कि आप Git संस्करण 2-बिंदु-कुछ का उपयोग कर रहे हैं, और जिसे आपने इसे बंद push.defaultकरने के simpleलिए प्राप्त करने के लिए सेट किया है। वास्तव में आपके पास Git का कौन सा संस्करण है, और यदि आपने जो कुछ भी push.defaultसेट किया है, वह लंबे और उबाऊ इतिहास के कारण मायने रखता है, लेकिन अंत में, यह तथ्य कि आपको Git से एक और शिकायत मिल रही है, यह इंगित करता है कि आपका Git है अतीत की गलतियों में से एक से बचने के लिए कॉन्फ़िगर किया गया है।

एक अपस्ट्रीम क्या है?

एक अपस्ट्रीम बस एक और शाखा का नाम है, आमतौर पर एक दूरस्थ-ट्रैकिंग शाखा, जो एक (नियमित, स्थानीय) शाखा से जुड़ी होती है।

हर शाखा में एक (1) अपस्ट्रीम सेट होने का विकल्प होता है। अर्थात्, प्रत्येक शाखा में या तो एक अपस्ट्रीम है, या एक अपस्ट्रीम नहीं है। किसी भी शाखा में एक से अधिक अपस्ट्रीम नहीं हो सकते।

अपस्ट्रीम होना चाहिए , लेकिन होना नहीं चाहिए, एक वैध शाखा (चाहे रिमोट-ट्रैकिंग जैसे या स्थानीय तरह )। यही है, अगर वर्तमान शाखा बी में ऊपर की ओर यू है , तो काम करना चाहिए । यदि यह काम नहीं करता है - यदि यह शिकायत करता है कि यू मौजूद नहीं है - तो अधिकांश गिट कार्य करता है, हालांकि अपस्ट्रीम बिल्कुल भी सेट नहीं है। कुछ कमांड, जैसे , अपस्ट्रीम सेटिंग दिखाएगा लेकिन इसे "चला गया" के रूप में चिह्नित करेगा।origin/Bmastergit rev-parse U git branch -vv

एक अपस्ट्रीम क्या अच्छा है?

यदि आपका या के push.defaultलिए सेट किया गया है , तो अपस्ट्रीम सेटिंग बिना किसी अतिरिक्त तर्क के उपयोग की जाएगी ।simpleupstreamgit push

यह बात है - यह सब इसके लिए करता है git push। लेकिन यह काफी महत्वपूर्ण है, क्योंकि git pushउन स्थानों में से एक है जहां एक सरल टाइपो प्रमुख सिरदर्द का कारण बनता है।

अपने तो push.defaultके लिए सेट है nothing, matchingया current, एक नदी के ऊपर स्थापित करने के लिए कुछ भी नहीं सभी के लिए कम से करता है git push

(यह सब आपके Git संस्करण को कम से कम 2.0 मान लेता है।)

अपस्ट्रीम प्रभावित करती है git fetch

यदि आप git fetchबिना किसी अतिरिक्त तर्क के साथ चलते हैं , तो वर्तमान शाखा के अपस्ट्रीम से परामर्श करके यह पता लगाने के लिए कि कौन से रिमोट को लाना है। यदि अपस्ट्रीम एक रिमोट-ट्रैकिंग शाखा है, तो Git उस रिमोट से प्राप्त होता है। (यदि अपस्ट्रीम सेट नहीं है या एक स्थानीय शाखा है, तो गिट लाने की कोशिश करता है origin।)

अपस्ट्रीम प्रभावित करता है git mergeऔर git rebaseभी

यदि आप चलाते हैं git mergeया git rebaseकोई अतिरिक्त तर्क नहीं देते हैं, तो Git वर्तमान शाखा के अपस्ट्रीम का उपयोग करता है। तो यह इन दो आदेशों के उपयोग को छोटा करता है।

अपस्ट्रीम प्रभावित करती है git pull

आपको कभी भी 2 का उपयोग नहीं करना चाहिए git pull, लेकिन यदि आप करते हैं, git pullतो अपस्ट्रीम सेटिंग का उपयोग यह पता लगाने के लिए कि किस रिमोट से लाना है, और फिर किस शाखा को मर्ज या रिबास करना है। यही है, git pullजैसा git fetchकि वास्तव में चलता है git fetch - और फिर वही काम करता है git mergeया git rebase, क्योंकि यह वास्तव में चलता है git merge या git rebase

(आपको आमतौर पर इन दो चरणों को मैन्युअल रूप से करना चाहिए, कम से कम जब तक आप अच्छी तरह से गिट को नहीं जानते हैं कि जब या तो चरण विफल हो जाता है, जो वे अंततः करेंगे, तो आप पहचानते हैं कि क्या गलत हुआ और इसके बारे में क्या करना है।

अपस्ट्रीम प्रभावित करती है git status

यह वास्तव में सबसे महत्वपूर्ण हो सकता है। एक बार आपके पास अपस्ट्रीम सेट होने के बाद, git statusआपकी वर्तमान शाखा और उसके अपस्ट्रीम के बीच के अंतर को कमिट के संदर्भ में रिपोर्ट कर सकता है।

अगर, जैसा कि सामान्य मामला है, आप Bइसके अपस्ट्रीम सेट के साथ शाखा पर हैं , और आप दौड़ते हैं , तो आप तुरंत देखेंगे कि क्या आपके पास है कि आप धक्का दे सकते हैं, और / या आप को मर्ज या रिबेस कर सकते हैं।origin/Bgit status

यह है क्योंकि git statusरन:

  • git rev-list --count @{u}..HEAD: आपके पास कितने कमिट हैं जो चालू Bनहीं हैं ?origin/B
  • git rev-list --count HEAD..@{u}: आपके पास कितने कमिट हैं जो चालू नहीं हैं ?origin/BB

अपस्ट्रीम सेट करने से आपको ये सभी चीजें मिल जाती हैं।

कैसे masterपहले से ही एक अपस्ट्रीम सेट है?

जब आप पहली बार कुछ रिमोट से क्लोनिंग करते हैं, तो:

$ git clone git://some.host/path/to/repo.git

या इसी तरह, अंतिम चरण Git करता है, अनिवार्य रूप से, है git checkout master। यह आपकी स्थानीय शाखा की जाँच करता है master— जब आपके पास स्थानीय शाखा नहीं हैmaster

दूसरी ओर, यदि आप करते हैं एक रिमोट ट्रैकिंग शाखा नामित किया है origin/master, क्योंकि आप बस इसे क्लोन।

Git अनुमान लगा लेता है कि आप का मतलब चाहिए है: "मुझे एक नया स्थानीय बनाना masterही के सूचक के रूप रिमोट ट्रैकिंग के लिए प्रतिबद्ध है कि origin/master, और, जब आप इसे पर हैं, के लिए नदी के ऊपर सेट masterकरने के लिए origin/master।"

यह हरgit checkout उस शाखा के लिए होता है जो आपके पास पहले से नहीं है। Git शाखा बनाता है और इसे "ट्रैक" (एक अपस्ट्रीम के रूप में) करता है जो संबंधित रिमोट-ट्रैकिंग शाखा है।

लेकिन यह नई शाखाओं के लिए काम नहीं करता है , यानी, अभी तक कोई रिमोट-ट्रैकिंग शाखा वाली शाखाएं नहीं

यदि आप एक नई शाखा बनाते हैं :

$ git checkout -b solaris

वहाँ है, जैसा कि अभी तक, नहीं origin/solaris। आपका स्थानीय रिमोट-ट्रैकिंग शाखा को ट्रैक solaris नहीं कर सकताorigin/solaris क्योंकि यह मौजूद नहीं है।

जब आप पहली बार नई शाखा को धक्का देते हैं:

$ git push origin solaris

जो बनाता solaris है origin, और इसलिए origin/solarisआपके स्वयं के Git भंडार में भी बनाता है। लेकिन यह बहुत देर हो चुकी है: आपके पास पहले से ही एक स्थानीय solarisहै जिसमें कोई अपस्ट्रीम नहीं है3

नहीं चाहिए बस सेट अप, अब, ऊपर नदी के रूप में स्वचालित रूप से?

शायद। देखें "खराब कार्यान्वित" और फुटनोट 1. यह बदलने के लिए मुश्किल है अब : वहाँ लाखों 4 लिपियों कि Git का उपयोग की और कुछ अच्छी तरह से अपनी वर्तमान व्यवहार पर निर्भर हो सकता। व्यवहार को बदलने के लिए आपको एक नया प्रमुख रिलीज, नाग-वेयर की आवश्यकता होती है जो आपको कुछ कॉन्फ़िगरेशन फ़ील्ड सेट करने के लिए मजबूर करता है, और इसी तरह। संक्षेप में, Git अपनी सफलता का शिकार है: इसमें जो भी गलतियाँ हैं, आज, केवल तभी तय की जा सकती है जब परिवर्तन या तो अदृश्य हो, स्पष्ट रूप से बहुत बेहतर हो, या समय के साथ धीरे-धीरे किया जाए।

तथ्य यह है, यह आज तक नहीं है, जब तक आप उपयोग नहीं करते हैं --set-upstreamया के -uदौरान करते हैं git push। यही संदेश आपको बता रहा हूं।

आपको ऐसा करने की जरूरत नहीं है। ठीक है, जैसा कि हमने ऊपर उल्लेख किया है, आपको यह बिल्कुल नहीं करना है, लेकिन मान लें कि आप एक अपस्ट्रीम चाहते हैं । आप पहले से ही शाखा बनाया है solarisपर originपहले के एक धक्का के माध्यम से, और अपने रूप में git branchउत्पादन से पता चलता है, तो आप पहले से ही है origin/solaris अपने स्थानीय भंडार में।

आपके पास इसके लिए अपस्ट्रीम के रूप में सेट नहीं है solaris

इसे अब सेट करने के लिए, पहले पुश के दौरान उपयोग करें git branch --set-upstream-to--set-upstream-toउप कमान जैसे, किसी भी मौजूदा शाखा का नाम लेता है origin/solaris, और कहा कि अन्य शाखा करने के लिए वर्तमान शाखा के नदी के ऊपर सेट।

यह है - कि यह सब करता है - लेकिन यह उन सभी निहितार्थ ऊपर उल्लेख किया है। इसका मतलब है कि आप बस चला सकते हैं git fetch, फिर चारों ओर देख सकते हैं, फिर दौड़ सकते हैं git mergeया git rebaseउपयुक्त हो सकते हैं, फिर git pushअतिरिक्त हंगामा-चारों ओर एक गुच्छा के बिना, नए कमिट और रन बना सकते हैं ।


1 निष्पक्ष होना, यह स्पष्ट नहीं था कि प्रारंभिक कार्यान्वयन त्रुटि-प्रवण था। यह तभी स्पष्ट हुआ जब हर नए उपयोगकर्ता ने हर बार वही गलतियाँ कीं। यह अब "कम खराब" है, जिसे "महान" कहना नहीं है।

2 "कभी नहीं" थोड़ा मजबूत है, लेकिन मुझे लगता है कि जब मैं कदमों को अलग करता हूं, तो गिट newbies चीजों को बहुत बेहतर तरीके से समझते हैं, खासकर जब मैं उन्हें दिखा सकता हूं कि git fetchवास्तव में क्या किया था, और वे तब देख सकते हैं कि आगे क्या करेंगे git mergeया क्या git rebaseकरेंगे।

3 आप अपनी चलाते हैं पहले git push के रूप में git push -u origin solarisयानी, आप जोड़ना अगर -uझंडा Git सेट हो जाएगा origin/solarisअगर (और केवल यदि) धक्का सफल होता है अपने वर्तमान शाखा के लिए नदी के ऊपर के रूप में। इसलिए आपको पहले पुश -uपर आपूर्ति करनी चाहिए । वास्तव में, आप इसे किसी भी बाद के धक्का पर आपूर्ति कर सकते हैं, और यह उस बिंदु पर अपस्ट्रीम को सेट या बदल देगा । लेकिन मुझे लगता है कि आसान है, अगर आप भूल गए।git branch --set-upstream-to

4 ऑस्टिन पॉवर्स / डॉ। ईविल की विधि द्वारा केवल "एक MILLLL-YUN" कहकर मापा जाता है, वैसे भी।


2
यदि सामान्य मामला {ब्रांच / पुश ब्रांच / यूज़ ब्रांच} बनाने का है, तो क्या नई लोकल ब्रांच को रिमोट गीट रिपॉजिटरी में पुश करने का नतीजा नहीं होना चाहिए और यह भी ट्रैक करना चाहिए कि क्या वास्तव में काम करता है? और अगर कोई चाहता है कि {ब्रांच / पुश ब्रांच बनाएं / ब्रांच का इस्तेमाल न करें}, तो क्या उन्हें कुछ खास नहीं करना चाहिए, जैसे --set-upstream /dev/null? आम मामले पर बोझ क्यों बढ़ाया जाता है? मैं वास्तव में इनमें से कुछ इंजीनियरिंग और प्रयोज्य निर्णयों को नहीं समझता।
jww

1
@VonC: सही है, यह बात है git push -u, लेकिन यह वास्तव में ऐसा लगता git push -uहै कि डिफ़ॉल्ट होना चाहिए, या कम से कम डिफ़ॉल्ट होना चाहिए यदि अभी तक कोई अपस्ट्रीम नहीं है , और ऐसा तब होना चाहिए git push --no-set-upstreamजब वर्तमान में कोई अपस्ट्रीम नहीं है और आप रखना चाहते हैं यह इस तरह से (जो भी समझ से बाहर के लिए :-))।
torek

2
"आप इस तरह से सवाल पूछते रहते हैं, क्योंकि मुझे लगता है, आपने" वास्तव में अप्रिय "के रूप में गिट लिखा है।" कृपया इस तरह की अटकलें अपने तक ही रखें। मुझे यह सवाल समझ में आया क्योंकि मैं भी खुद से इस तरह के सवाल करता रहता हूं। मैं दुनिया का सबसे अच्छा यूएक्स डिजाइनर नहीं हूं, लेकिन यहां तक ​​कि मैं मानता हूं कि इस विशेष परिदृश्य में डिफ़ॉल्ट व्यवहार बेहतर हो सकता है।
स्टीवन बक्स

4
@torek - धन्यवाद। आपका जवाब अन्यथा शानदार था; अच्छी तरह से सोचा, अच्छी तरह से संरचित, और अत्यंत जानकारीपूर्ण। :-)
स्टीवन बक्स

6
ध्यान दें कि यह विन्यास योग्य है। यदि आप करते हैं git config --add push.default current, तो यदि आवश्यक हो , तो git push अपने आप रिमोट रेपो में शाखा बना देगा।
गोगोविट्श

31

के बीच का अंतर
git push origin <branch>
और
git push --set-upstream origin <branch>
है कि वे दूरदराज के भंडार के लिए दोनों धक्का ठीक है, लेकिन यह जब तुम खींच है कि आप अंतर नोटिस है।

यदि आप करते हैं:
git push origin <branch>
खींचते समय, आपको करना होगा:
git pull origin <branch>

लेकिन अगर आप करते हैं:
git push --set-upstream origin <branch>
तब, जब खींचते हैं, तो आपको केवल यह करना होगा:
git pull

इसलिए --set-upstreamयह सुनिश्चित करने के लिए कि कौन सी शाखा को आप हर एक बार खींचना चाहते हैं, को जोड़ने की अनुमति देता है git pull


"गिट पुश" के दो संस्करणों के बीच का अंतर जो मुझे नहीं पता कि मैं उन्हें क्यों उपयोग करना चाहता / चाहूंगा। व्यर्थ!
फ्रैंक पक

17

एक मूल रूप से पूर्ण कमांड की तरह है git push <remote> <local_ref>:<remote_ref>। यदि आप बस चलाते हैं git push, तो गिट को नहीं पता कि क्या करना है जब तक कि आपने कुछ कॉन्फ़िगरेशन नहीं किया है जो निर्णय लेने में मदद करता है। Git repo में, हम कई रीमोट सेटअप कर सकते हैं। इसके अलावा, हम एक स्थानीय रेफरी को किसी भी दूरस्थ रेफरी में धकेल सकते हैं। पूर्ण कमांड एक धक्का बनाने का सबसे सीधा तरीका है। यदि आप कम शब्द टाइप करना चाहते हैं, तो आपको पहले कॉन्फ़िगर करना होगा, जैसे --सेट-अपस्ट्रीम।

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