आप केवल अपने कुछ स्थानीय कमिट को कैसे आगे बढ़ाते हैं?


160

मान लीजिए मेरे पास 5 स्थानीय कमिट हैं। मैं उनमें से केवल 2 को एक केंद्रीकृत रेपो (एसवीएन-शैली वर्कफ़्लो का उपयोग करके) पुश करना चाहता हूं। मैं यह कैसे करु?

यह काम नहीं किया:

git checkout HEAD~3  #set head to three commits ago
git push #attempt push from that head

यह सभी 5 स्थानीय कमिटों को आगे बढ़ाता है।

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

मेरी भावना यह है कि धक्का देने या रीसेट करने के लिए पारित कुछ ध्वज काम करेंगे।

अगर यह मदद करता है, तो यहाँ मेरा git config है

[ramanujan:~/myrepo/.git]$cat config 
[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
[remote "origin"]
        url = ssh://server/git/myrepo.git
        fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
        remote = origin
        merge = refs/heads/master

जवाबों:


192

यह मानते हुए कि आपके कमिट मास्टर शाखा पर हैं और आप उन्हें दूरस्थ मास्टर शाखा में धकेलना चाहते हैं:

$ git push origin master~3:master

यदि आप git-svn का उपयोग कर रहे थे:

$ git svn dcommit master~3

Git-svn के मामले में, आप HEAD ~ 3 का उपयोग भी कर सकते हैं, क्योंकि यह एक प्रतिबद्धता की उम्मीद कर रहा है। सीधे गिट के मामले में, आपको शाखा नाम का उपयोग करने की आवश्यकता है क्योंकि HEAD का मूल्यांकन रीस्पेक में ठीक से नहीं किया गया है।

आप इससे भी लंबा समय ले सकते हैं:

$ git checkout -b tocommit HEAD~3
$ git push origin tocommit:master

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

$ git checkout master
$ git merge working~3
$ git push origin master:master

ध्यान दें कि "मूल मास्टर: मास्टर" भाग संभवतः आपके सेटअप के लिए वैकल्पिक है।


14
नोट: आपको उपयोग करने की आवश्यकता नहीं है master~3। वांछित "अप" के लिए कोई भी संदर्भ समान रूप से मान्य है, जैसे HEAD~3या HEAD~~~, या विशिष्ट SHA, या एक टैग जो उस लेबल को लेबल करता है।
काज

2
अच्छी चीज़। हालांकि एक चेतावनी: ये उदाहरण मूल गुरु को धक्का देते हैं। यदि आप इस समाधान को कॉपी और पेस्ट कर रहे हैं, तो आप गलती से मास्टर शाखा को अपडेट कर सकते हैं। (बेशक, आप हमेशा सावधान रहना चाहिए और एक जारी करने से पहले अपने आदेश की अच्छी तरह जांच git push...)
nofinator

ऐसा प्रतीत होता है कि यह कमिट को आगे बढ़ाता है, लेकिन शाखा को दूरस्थ रूप से नहीं जोड़ता है।
नटोवामी

@ नाटेओमी के लिए आपको रेफस्पेक masterके दूरस्थ पक्ष के अलावा कुछ और निर्दिष्ट करने की आवश्यकता होगी , जैसेgit push origin tocommit:newbramch
रयान ग्राहम

समझा। शाखा का नाम पहले से ही स्थानीय रूप से मौजूद था; मुझे लगता है कि यह ऐसा नहीं था। रिमोट का शाखा नाम अभी तक नहीं था।
नटोमामी

16

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

मेरी मास्टर ब्रांच में अपस्ट्रीम से परिवर्तन खींचने के बाद, मैं git checkout workऔर git rebase master। यह इतिहास के अंत में होने वाले मेरे सभी स्थानीय परिवर्तनों को फिर से लिखता है।

मैं वास्तव git svnमें इस वर्कफ़्लो के साथ उपयोग कर रहा हूं , इसलिए मेरा "पुश" ऑपरेशन शामिल है git svn dcommit। मैं यह भी उपयोग tigकरता हूं जो मास्टर करने के लिए उपयुक्त कॉमे-चेरी को चुनने के लिए एक अच्छा टेक्स्ट मोड गिनी भंडार दर्शक है।


git svn dcommit के साथ, आप एक कमिट को dcommit तक निर्दिष्ट कर सकते हैं, इसलिए git-svn के साथ वांछित प्रभाव काफी तुच्छ है।
रयान ग्राहम

इस दृष्टिकोण के नुकसान हैं (संक्षेप में यहां stackoverflow.com/a/881014/1116674 )। एक अच्छा विकल्प आपके द्वारा काम करने वाली प्रत्येक सुविधा और एक workशाखा के लिए शाखाएं बनाना है । फिर, आप विशिष्ट शाखाओं को मर्ज करते हैं masterताकि आप उन पर इतिहास न खोएं। जब आप काम करते हैं work, तो आप अपनी सभी शाखाओं को इसमें मिला देते हैं। यह अधिक उपरि है, लेकिन कुछ मामलों में इसके लायक हो सकता है।
हडून

16

डिफ़ॉल्ट रूप से, गिट-पुश सभी शाखाओं को धक्का देता है। जब आप ऐसा करते हैं:

 git checkout HEAD~3  #set head to three commits ago
 git push #attempt push from that head

आप एक अलग हेड (आप किसी भी शाखा पर नहीं हैं) में चले जाते हैं और फिर आप स्थानीय मास्टर (जो अभी भी जहां था) सहित सभी शाखाओं को दूरस्थ मास्टर को धकेल देते हैं।

मैनुअल समाधान है:

 git push origin HEAD:master

यदि आप सभी शाखाओं को भ्रमित करने (और खतरनाक!) को धकेलने का डिफ़ॉल्ट व्यवहार पाते हैं, तो इसे अपने ~ / .gitconfig में जोड़ें।

 [remote.origin]
    push = HEAD

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

 error: unable to push to unqualified destination: HEAD

10

संक्षिप्त जवाब:

git push <latest commit SHA1 until you want commits to be pushed>

उदाहरण:

git push fc47b2

git push HEAD~2

लंबा जवाब:

माता-पिता / बाल तंत्र के साथ एक श्रृंखला के रूप में एक साथ जुड़े हुए हैं। इस प्रकार, वास्तव में एक प्रतिबद्ध धक्का भी सभी माता-पिता को इस प्रतिबद्ध के लिए धक्का देता है कि जहां रिमोट को नहीं जाना जाता है। जब आप git pushवर्तमान कमिट करते हैं , तो यह अनुमानित रूप से किया जाता है : सभी पिछले कमिट को भी धक्का दिया जाता है क्योंकि यह कमांड के बराबर है git push HEAD

तो यह प्रश्न फिर से लिखा जा सकता है कि किसी विशिष्ट कमिट को कैसे आगे बढ़ाया जाए और यह विशिष्ट कमेंट HEAD ~ 2 हो सकता है, उदाहरण के लिए।

यदि आप जो पुश करना चाहते हैं वह गैर-स्थिर हैं, तो बस उन्हें विशिष्ट पुशgit rebase -i से पहले एक बार फिर से ऑर्डर करें ।


5

1) यदि आप चाहते हैं, तो अपने कमानों को फिर से व्यवस्थित करने के लिए "गिट रिबेस" का उपयोग करें।

git rebase -i

यह कमांड आपके संपादक में कुछ इस तरह प्रदर्शित होगी (मैं विम का उपयोग कर रहा हूँ)

pick 4791291 commitA
pick a2bdfbd commitB
pick c3d4961 commitC
pick aa1cefc commitD
pick 9781434 commitE

# Rebase ..............
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out




^G Get Help         ^O WriteOut         ^R Read File        ^Y Prev Page                ^K Cut Text         ^C Cur Pos
^X Exit             ^J Justify          ^W Where Is         ^V Next Page            ^U UnCut Text       ^T To Spell

2) सरल कट पेस्ट द्वारा अपनी पसंद के अनुसार अपने कमिट्स को फिर से व्यवस्थित करें। मान लीजिए नया आदेश है

9781434 कमेटी चुनें

c3d4961 कमिट करें

4791291 कमेटी चुनें

aa1cefc कमिट चुनें

a2bdfbd कमिट चुनें

अपने संपादक में ये बदलाव करें और ctrl + O (writeOut) दबाएँ

या आप भी उपयोग कर सकते हैं

git rebase -i HEAD~<commitNumber>

आप के साथ नए अनुक्रम की जाँच कर सकते हैं

git log

3) अब उपयोग करें

git push <remoteName> <commit SHA>:<remoteBranchName>

यदि दूरस्थ (मूल) पर केवल एक शाखा और स्थानीय (मास्टर) में एक शाखा है, तो उपयोग करें

git push <commit SHA>
git push aa1cefc

यह प्रतिबद्ध और कमिट को आगे बढ़ाएगा।

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