क्या रिमोट रिपॉजिटरी में गिट स्टैश को धक्का देना संभव है?


205

Git में, क्या यह संभव है कि एक स्‍लैश बनाया जाए, स्‍टेश को रिमोट रिपॉजिटरी में धकेल दिया जाए, दूसरे कंप्‍यूटर पर स्‍कैश को पुनः प्राप्त करें और स्‍टेश को लागू करें?

या मेरे विकल्प हैं:

  • एक पैच बनाएँ और दूसरे कंप्यूटर पर पैच कॉपी करें, या
  • एक छोटी शाखा बनाएँ और उस शाखा के लिए अधूरा काम करें?

जवाबों:


68

यह लाने के लिए संभव नहीं है के माध्यम से लाने के लिए या तो, दर्पण refspec है fetch = +refs/*:refs/*, और भले ही छिपाने की जगह refs/stashयह भेजा नहीं है। एक स्पष्ट refs/stash:refs/stashप्रभाव भी नहीं है!

यह केवल वैसे भी भ्रामक होगा क्योंकि यह सभी चोरी नहीं करेगा, केवल नवीनतम होगा; stashes की सूची है reflog रेफरी की refs/stashes


4
आप नवीनतम रिमोट को एक जीआईटी रिमोट से प्राप्त कर सकते हैं, लेकिन अपने स्‍टेश में, केवल दूसरे रेफरी में नहीं। की तरह कुछ । लेकिन आप पुराने स्टैग नहीं प्राप्त कर सकते हैं क्योंकि वे रिफ्लोग में संग्रहीत हैं जो कि उपलब्ध नहीं है। देखें stackoverflow.com/questions/2248680/…git fetch some-remote +refs/stash:refs/remotes/some-remote/stashgit stash apply some-remote/stash
sj26 3

75

नोट: मैंने अपने बेल्ट के नीचे 24 घंटे अधिक गिट-फू के साथ इस उत्तर को फिर से लिखा है :) मेरे शेल इतिहास में, पूरे शेबंग अब तीन एक-लाइनर हैं। हालाँकि, मैंने उन्हें आपकी सुविधा के लिए बिना शर्त हटा दिया है।

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


यहाँ कदम से कदम है।

मान लिया गया है कि ~ ~ OLDREPO में स्टैड्स हैं। टेस्ट क्लोन बनाएँ जिसमें कोई स्टैम्स न हो:

cd ~/OLDREPO
git clone . /tmp/TEST

सभी बाधाओं को अस्थायी शाखाओं के रूप में धकेलें:

git send-pack /tmp/TEST $(for sha in $(git rev-list -g stash); \
    do echo $sha:refs/heads/stash_$sha; done)

वापस प्राप्त करने के लिए स्टैप में तब्दील होने के लिए लूप:

cd /tmp/TEST/
for a in $(git rev-list --no-walk --glob='refs/heads/stash_*'); 
do 
    git checkout $a && 
    git reset HEAD^ && 
    git stash save "$(git log --format='%s' -1 HEAD@{1})"
done

अपनी अस्थायी शाखाओं को साफ करें यदि आप करेंगे

git branch -D $(git branch|cut -c3-|grep ^stash_)

Git stash लिस्ट करें और आप कुछ इस तरह से होंगे:

stash@{0}: On (no branch): On testing: openmp import
stash@{1}: On (no branch): On testing: zfsrc
stash@{2}: On (no branch): WIP on sehe: 7006283 fixed wrong path to binary in debianized init script (reported as part of issue
stash@{3}: On (no branch): WIP on debian-collab: c5c8037 zfs_pool_alert should be installed by default
stash@{4}: On (no branch): WIP on xattrs: 3972694 removed braindead leftover -O0 flag
stash@{5}: On (no branch): WIP on testing: 3972694 removed braindead leftover -O0 flag
stash@{6}: On (no branch): WIP on testing: db9f77e fuse_unmount_all could be starved for the mtx lock
stash@{7}: On (no branch): WIP on xattrs: db9f77e fuse_unmount_all could be starved for the mtx lock
stash@{8}: On (no branch): WIP on testing: 28716d4 fixed implicit declaration of stat64
stash@{9}: On (no branch): WIP on emmanuel: bee6660 avoid unrelated changes

मूल भंडार पर, वही दिखता था

stash@{0}: WIP on emmanuel: bee6660 avoid unrelated changes
stash@{1}: WIP on testing: 28716d4 fixed implicit declaration of stat64
stash@{2}: WIP on xattrs: db9f77e fuse_unmount_all could be starved for the mtx lock
stash@{3}: WIP on testing: db9f77e fuse_unmount_all could be starved for the mtx lock
stash@{4}: WIP on testing: 3972694 removed braindead leftover -O0 flag
stash@{5}: WIP on xattrs: 3972694 removed braindead leftover -O0 flag
stash@{6}: WIP on debian-collab: c5c8037 zfs_pool_alert should be installed by default
stash@{7}: WIP on sehe: 7006283 fixed wrong path to binary in debianized init script (reported as part of issue #57)
stash@{8}: On testing: zfsrc
stash@{9}: On testing: openmp import

1
मैं कम समय में बहुत कुछ सीख रहा हूं, और मुझे लगता है कि मुझे अपने पहले के दृष्टिकोण में संभवतः कई कमांड usages चाहिए, जिन्हें मैं बाद में करने की कोशिश करूंगा।
11:00

9
यह मेरे लिए अच्छी तरह से काम करता है सिवाय इसके कि मुझे कदम से git add .पहले एक नई फाइल की आवश्यकता git stash save ...से git stashइंकार कर दिया है जब तक कि उनका मंचन नहीं किया गया है। इसके अलावा, परिणाम के git rev-list ...माध्यम से पाइपिंग, tacस्टैड्स के क्रम को उलट देती है, इसलिए वे उसी क्रम में बाहर आते हैं।
एलन क्रुएगर

1
@ सई उत्कृष्ट स्क्रिप्ट !! दो सुझाव: 1) - अंतिम रेफरी-सूची को आगे बढ़ाएं ताकि लक्ष्य के रूप में मूल रूप में स्टैम्स उसी क्रम में हों। 2) अंतिम अंतिम forलूप के साथ git branch -D stash_$a(क्लीन अप के रूप में स्टैड्स बनाए जाते हैं) ताकि अगर कुछ गलत हो जाए और हम फिर से प्रयास करें, तो हम पहले से ही सफलतापूर्वक रद्द किए गए कामों को दोहराते नहीं हैं।
कीथ रॉबर्टसन

1
"सिर्फ समाधान पोस्ट करने" के बजाय आपने क्या किया, यह समझाने के लिए समय निकालने के लिए बहुत-बहुत धन्यवाद।
मार्जन वेनेमा

1
समाधान को और बेहतर बनाया जा सकता है: यदि आप अपने git stash save "$(git log --format='%s' -1 HEAD@{1})"साथ git update-ref --create-reflog -m "$(git show -s --format=%B $rev)" refs/stash $revमूल संदेश प्राप्त करते हैं ( update-refजो git stash saveकि पर्दे के पीछे है)।
सेबेस्टियन श्रैडर

31

मैं पार्टी में थोड़ी देर का हूं, लेकिन मेरा मानना ​​है कि मुझे कुछ ऐसा मिला है जो इस बारे में मेरे लिए काम करता है और यह आपके लिए भी हो सकता है यदि आपकी परिस्थितियां समान या समान हैं।

मैं अपनी शाखा में एक सुविधा पर काम कर रहा हूं। शाखा को मास्टर में विलय नहीं किया गया है और इसके समाप्त होने तक धकेल दिया गया है या मैंने कमिट किया है कि मैं जनता को दिखाने में सहज महसूस करता हूं। जब मैं दूसरे कंप्यूटर में गैर-मंचित परिवर्तन करना चाहता हूं तो मैं क्या करूं:

  • एक प्रतिबद्ध संदेश, जैसे " [non-commit] FOR TRANSFER ONLY" के साथ, जिस सामग्री को आप स्थानांतरित करना चाहते हैं, उसे बनाएं ।
  • दूसरे कंप्यूटर पर लॉगइन करें।
  • फिर करो:

    git pull ssh+git://<username>@<domain>/path/to/project/ rb:lb

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

  • git reset HEAD^(तात्पर्य --mixed)

    यह "[गैर-प्रतिबद्ध]" प्रतिबद्ध से पहले राज्य को इंगित करने के लिए HEAD को रीसेट करता है।

Git-reset (1) से: " --mixed: इंडेक्स को रीसेट करता है, लेकिन वर्किंग ट्री को नहीं (यानी, बदली हुई फाइलें संरक्षित हैं लेकिन कमिट के लिए चिह्नित नहीं हैं] [...]"

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

हालांकि इसके लिए आपको git reset --hard HEAD^उस रिपॉजिटरी की आवश्यकता होगी जिसमें आपने "[नॉन-कमिट]" बनाया है, क्योंकि यह कमिट कचरा है।


यह एक बहुत ही गन्दा है तो बस एक नई सुविधा शाखा का निर्माण करना और फिर बाद में इसे हटाना ....
तायगास्त

@ टैगास्ट आपके पर्यावरण पर निर्भर करता है जिसका मैं अनुमान लगाता हूं। हो सकता है कि कुछ CI / CD सामान सिर्फ शाखाएं ऊपर की ओर धकेलने से रोकें। लेकिन हां, आप जो पसंद करते हैं उसके आधार पर, आप एक ही चीज़ को पूरा करने के लिए एक शाखा बनाना चाहते हैं।
विक्टर ज़मानियन

22

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

मेरे लिए जो काम करता है वह है मेरा इन-प्रोग्रेस कोड (एक ऐसी शाखा में जो मैं अकेले काम कर रहा हूं)। जब मैं अपने दूसरे कंप्यूटर पर जाता हूं, तो एक पुल करता हूं, फिर उसके साथ कमिट करें:

git reset --soft HEAD^

जब आप वहां थे, तब तक काम करना जारी रखें, जब तक कि आपकी सारी प्रगति नहीं हो जाती, तब तक आप अनचाहे और अस्थिर रहे।

आशा करता हूँ की ये काम करेगा।


जब मैं ऐसा करने की कोशिश करता हूं, तो ओरिजिन अभी भी कमिट को बनाए रखता है, जो कि अनकम्युटेड था। बंद करो लेकिन मेरे लिए कोई सिगार नहीं।
rezwits

@rezwits हाँ, रिमोट रखता है, लेकिन यह केवल मूल से अस्थायी शाखा को हटाने के लिए पर्याप्त आसान है।
सर रॉबर्ट

इस तथ्य के रूप में कि मैं क्या कर रहा हूँ!
rezwits

19

इसे हल करने के लिए बहुत साफ-सुथरी चाल लगती है। आप git diff > file.diffफ़ाइल का उपयोग कर सकते हैं (और कर सकते हैं ), फिर उपयोग करके परिवर्तनों को पुनर्स्थापित करेंgit apply file.diff उसी परिणाम को प्राप्त करने के लिए (कहीं से भी) ।

यह यहाँ भी समझाया गया था ।


5
अगर आपके पास अनटैक की गई फाइलें हैं: 1. गिट ऐड। 2. git diff HEAD> file.diff
trickpatty

अपने आप में अंतर को संदेश देना रेपो पर किसी भी तरह के कमिट / फुटप्रिंट की अनुमति नहीं देता है! (उदाहरण: सिग्नल डेस्कटॉप ऐप के माध्यम से नोट-टू-सेल्फ), या ईमेल।
जॉन मी

9

मैं दूसरे दृष्टिकोण के साथ जाना चाहता हूँ, हालांकि कोई विचार नहीं है कि आप इसे मास्टर / फ़ीचर की गई शाखा में क्यों नहीं भेज सकते। चेरी-पिकिंग करना भी संभव है।


27
मास्टर / फ़ीचर के लिए प्रतिबद्ध नहीं होने का कोई तकनीकी कारण नहीं है, बस मैं यह कहना चाहता हूं कि "यह एक वास्तविक प्रतिबद्धता नहीं है, यह सिर्फ मेरे काम को बचा रहा है ताकि मैं इसे किसी अन्य मशीन पर प्राप्त कर सकूं"।
एंड्रयू ग्रिम

4

AFAIK के पूरे विचार को छिपाने के लिए स्थानीय कालीन के तहत कुछ महत्वपूर्ण नहीं छिपाना है । किसी को भी अपने पसंदीदा बकवास के बारे में नहीं जानना चाहिए ;-) केवल "लेकिन" है: लेकिन अगर मैं कुछ वर्कस्टेशनों पर विकसित होता हूं? फिर scpरास्ता बेहतर है।


9
कुछ इस मजाकिया टिप्पणी होना चाहिए। ;-)
एंड्रयू ग्रिम

2
कुल git-ssh-newbie यहाँ लेकिन क्या आप github के साथ scp का उपयोग कर सकते हैं?
कोएन

नहीं, github के git-ssh फ्रंटेंड को क्रमादेशित किया गया है ताकि आपके पास कभी भी ssh शेल / कंसोल न हो। यह केवल सर्वर-साइड गिट प्रक्रिया चला सकता है।
argent_smith

1
अगर वास्तव में आपकी मास्टर ब्रांच जीथब पर है तो इस परिदृश्य के लिए एससीपी एक विकल्प नहीं है? उस मामले में एक तबादला करने के लिए कोई अन्य सुझाव?
कोएन

1
मैंने इस बात पर जोर देने की कोशिश की है कि एएएसएआईके में स्टैश ट्रांसफर संभव नहीं है।
argent_smith

2

वर्तमान में स्वीकार जवाब तकनीकी रूप से सही है, तो आप सीधे एक दूरदराज के लिए अपने सभी stashes पुश करने के लिए Git नहीं बता सकता, और उसके बाद किसी अन्य कंप्यूटर पर अपने स्थानीय stashes में सब कुछ खींच।

और जबकि वर्तमान में टॉप-अपवॉट किए गए उत्तर को काम करना चाहिए, मुझे यह पसंद नहीं आया कि यह अस्थायी शाखाओं का एक गुच्छा बनाता है, और इसके लिए इसे मैन्युअल रूप से स्टैस कमिट की जाँच करनी चाहिए और इसे स्टैश के रूप में सहेजना चाहिए, जिससे इस टिप्पणी जैसे मुद्दे पैदा हो सकते हैं। उल्लेख किया और एक डुप्लिकेट की ओर जाता है On (no branch): On testing:। निश्चित रूप से एक बेहतर तरीका होना चाहिए!

जब आप सीधे स्ट्रैस को धक्का नहीं दे सकते हैं, तो एक स्टैश सिर्फ एक कमिट (वास्तव में दो कमिट्स) है, और उस git pushमैन पेज के अनुसार आप पुश कर सकते हैं:

<src>अक्सर शाखा आप पुश करने के लिए चाहते हो जाएगा का नाम है, लेकिन यह किसी भी मनमाने ढंग से "SHA-1 अभिव्यक्ति" हो सकता है ...

मैंने स्टैचेज़ को आगे बढ़ाने के लिए चुना refs/stashes/*ताकि मैं अतिरिक्त शाखाओं के साथ अपने रिमोट को अव्यवस्थित न कर सकूं। इसलिए मैं ऐसा कर सकता हूं:

git push origin stash@{0}:refs/stashes/$(git rev-parse --short stash@{0})

( rev-parse कमांड को स्टैश का शॉर्ट हैश मिलता है, जो रेपो के लिए अद्वितीय होगा।)

अगला, मुझे दूसरे कंप्यूटर से स्टैश लाने की जरूरत है। Git केवल डिफ़ॉल्ट रूप से शाखाएँ लाती है, इसलिए मुझे विशेष रूप से स्टैच लाने की आवश्यकता है:

git fetch origin refs/stashes/*:refs/stashes/*

अब स्‍टैश कमिट को वास्तविक स्‍टेश में बदलने के लिए। जैसा कि उल्लेख किया गया है, जबकि मैं बस स्टैस कमिट, रीसेट, और हमेशा की तरह जांच कर सकता था, मुझे यह पसंद नहीं है कि इसके लिए अतिरिक्त चरणों की आवश्यकता हो, या यह हो सकता है कि यह स्टैश के लिए सूचकांक स्थिति को बनाए न रखे। मैं स्वचालित रूप से ऐसा करने के लिए ऑनलाइन देख रहा था, लेकिन मेरे खोज-फू ने मुझे विफल कर दिया। अंत में मैंने मैन पेज के लिए देखाgit stash , जहाँ मुझे यह मिला:

सृजन करना
a stash (जो एक रेग्युलर कमिट ऑब्जेक्ट है) बनाएँ और रेफ नेमस्पेस में कहीं भी स्टोर किए बिना, उसका ऑब्जेक्ट नाम वापस करें। यह स्क्रिप्ट के लिए उपयोगी माना जाता है। यह संभवतः वह कमांड नहीं है जिसका आप उपयोग करना चाहते हैं; ऊपर "सहेजें" देखें।

दुकान
स्टोर किए गए रीट को अपडेट करते हुए, git stash create (जो कि एक झूलता हुआ मर्ज कमिट है) के माध्यम से दिया गया स्टोर करें। यह स्क्रिप्ट के लिए उपयोगी माना जाता है। यह संभवतः वह कमांड नहीं है जिसका आप उपयोग करना चाहते हैं; ऊपर "सहेजें" देखें।

चूंकि मेरे पास पहले से ही कमिटमेंट है, इसलिए storeलगता है कि मुझे क्या चाहिए। तो मैं कर सकता हूँ:

git stash store --message "$(git show --no-patch --format=format:%s <SHA>)" <SHA>

की जगह <SHA> साथ जो अभी-अभी आया था।

( git show कमांड को स्‍टैश कमेट से मैसेज मिलता है, स्‍टैश लॉग के संदेश के रूप में उपयोग करने के लिए।)

मेरे स्थानीय रेपो में अब यह स्थिति सामान्य दिखती है:

$ git stash list
stash@{0}: On master: temp
...

रिमोट को साफ करने के लिए, स्टैम्स को रिमोट से हटाया जा सकता है जैसे:

git push origin :refs/stashes/<SHA>

इस पद्धति का भी लाभकारी होने का लाभ है: यदि आप pushफिर से कमांड चलाते हैं , तो यह रिपोर्ट करेगा Everything up-to-datefetchआदेश भी सुरक्षित रूप से बार-बार चलाया जा सकता है। हालांकि stash storeयदि यह हाल ही के सबसे अधिक स्लैश के समान है, तो स्टैश को स्टोर करना छोड़ देगा, यह पुराने स्टैच के डुप्लिकेट को नहीं रोकता है। यह चारों ओर काम किया जा सकता है, जैसा कि मैं अपनी git-rstashस्क्रिप्ट में करता हूं , नीचे देखें।


पूरा करने के लिए, आप आसानी से सभी स्टैड्स को धक्का दे सकते हैं (साथ में) ):

for i in $(seq 0 $(expr $(git rev-list --walk-reflogs --count stash) - 1))
do
  git push origin stash@{$i}:refs/stashes/$(git rev-parse --short stash@{$i})
done

या सभी लाए गए आयातों को आयात करें:

for stash in $(ls .git/refs/stashes)
do
  git stash store --message "$(git show --no-patch --format=format:%s $stash)" $stash
done

मैंने एक बनाया है स्क्रिप्ट जिसे एक सबकमांड (उदा git rstash push 0) के रूप में कहा जा सकता है, इसलिए मुझे यह सब याद रखने की ज़रूरत नहीं है। git-rstashयहाँ पाया जा सकता है।


1

निम्नलिखित स्टैश के साथ काम नहीं करता है, लेकिन काम करने वाले डायर में अनपेक्षित परिवर्तनों के साथ। यह एक शाखा बनाता है, सभी वर्तमान परिवर्तनों को स्वचालित करता है, और रिमोट को धक्का देता है:

commit_and_push_ ( ) {
    # This will:
    #  1. checkout a new branch stash-XXX
    #  2. commit the current changes in that branch
    #  3. push the branch to the remote
    local locbr=${1:-autostash-XXX}
    git checkout -b $locbr
    git add .
    git commit -a -m "Automatically created commit"
    git push origin $locbr
    echo "Autocommitted changes in branch $locbr ..."
}

उपयोग की तरह:

commit_and_push_ my-temp-branch
commit_and_push_

0

जब भी उस शाखा की आवश्यकता नहीं होगी, मैं बस एक नया स्टैश शाखा और निष्कासन बनाऊंगा।

git add . // Add work-in-progress job
git checkout -b stash-branch // Create and checkout to stash-branch
git commit -m 'WIP: job description' // Commit message
git push origin stash-branch // Push to remote
git pull origin stash-branch // Pull the stash-branch
git checkout master // Checkout to working branch
git rebase stash-branch // Rebase the stash-branch
git reset --soft // Equivalent to stash!!
git branch -d stash-branch // Delete when not needed from local
git push -d origin stash-branch // Delete when not needed from remote

-9

बस ड्रॉपबॉक्स का उपयोग करें जैसे इस आदमी ने किया। इस तरह से आपको अपने सभी कोड का बैकअप लेने के बाद से स्टैग को धकेलने की चिंता नहीं करनी चाहिए।

http://blog.sapegin.me/all/github-vs-dropbox


2
इससे पहले कि किसी को भी घुटने में झटका लगने की प्रतिक्रिया हो, मैं गिथब के बजाय ड्रॉपबॉक्स का उपयोग करने के लिए नहीं कह रहा हूं, लेकिन कोड को स्टोर करने के लिए जो ड्रॉपबॉक्स में एक कमिट के लिए तैयार नहीं है जो अभी भी स्थानीय रूप से संस्करण नियंत्रण में होगा।
NYC टेक इंजीनियर

4
सभी प्रोजेक्ट को दूरस्थ क्लाउड पर कॉपी करने में बहुत अधिक समय लगेगा।
स्टैव अल्फी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.