फाइल चेकआउट के बिना Git शाखा स्विच करें


100

क्या सभी फाइलों की जांच के बिना Git को किसी अन्य शाखा में स्विच करना संभव है?

ब्रांच को स्विच करने के बाद मुझे सभी फ़ाइलों को हटाने, उन्हें फिर से बनाने, कमिट करने और वापस स्विच करने की आवश्यकता है। इसलिए फाइलों की जांच करना समय की बर्बादी है (और लगभग 14,000 फाइलें हैं - यह एक लंबा ऑपरेशन है)।

सब कुछ स्पष्ट करने के लिए:

मुझे GitHub पर प्रलेखन अपलोड करने के लिए यह सब चाहिए ।

मेरे पास gh-pages शाखा के साथ एक भंडार है । जब मैं स्थानीय रूप से प्रलेखन का पुनर्निर्माण करता हूं, तो मैं इसे रिपॉजिटरी डायरेक्टरी में कॉपी करता हूं, कमिट करता हूं और GitHub को धक्का देता हूं। लेकिन मैं खुश नहीं था, क्योंकि मेरे पास स्थानीय रूप से प्रलेखन की दो प्रतियां थीं। और मैंने एक खाली शाखा बनाने का फैसला किया और कमिट करने के बाद, रिक्त स्थान पर जाएँ और फ़ाइलों को हटा दें। लेकिन वापस स्विच करना एक लंबा ऑपरेशन है - इसलिए मैंने यह सवाल पूछा।

मुझे पता है कि मैं सिर्फ gh-pages ब्रांच पर जाकर फाइलें डिलीट कर सकता हूं, लेकिन मुझे गंदे वर्किंग ट्री पसंद नहीं हैं।


आपके लिए "लंबी" कितनी लंबी है? आप किस प्लेटफार्म पर काम कर रहे हैं? क्या आप किसी नेटवर्क पर काम कर रहे हैं जैसे NFS या अन्य फ़ाइल साझाकरण के साथ?
ग्रेग हेविगिल

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

शायद यह आपके काम की नकल का एक अस्थायी (या स्थायी?) क्लोन बनाने के लिए सस्ता है। मेरा संबंधित उत्तर और एक राइटअप दिखाता है कि यह मुख्य रिपॉजिटरी के उपनिर्देशिका के रूप में भी कैसे काम करता है।
krlmlr

जवाबों:


106

हां, आप यह कर सकते हैं।

git symbolic-ref HEAD refs/heads/otherbranch

यदि आपको इस शाखा पर प्रतिबद्ध होने की आवश्यकता है, तो आप सूचकांक को भी रीसेट करना चाहते हैं अन्यथा आप अंतिम रूप से जाँच की गई शाखा के आधार पर कुछ करना चाहेंगे।

git reset

1
उपयोग echo "ebff34ffb665de0694872dceabe0edeaf50ec5a9" > .git/HEADके बाद git resetएक शाखा के बजाय एक रेफरी को बात करने के लिए।
कैडर्न

1
सीधे HEAD फ़ाइल में लिखना कम भरोसेमंद है। यदि आप किसी उपनिवेश में हैं तो क्या होगा? अलग किए गए सिर (सीधे SHA1 की ओर इशारा करते हुए सिर) के लिए, यह कोशिश करें: git update-ref HEAD refs/heads/otherbranch
अलेक्जेंडर बर्ड

2
यदि आप वर्तमान शाखा से एक नई शाखा की जांच करना चाहते हैं, तो ऐसा करने का दूसरा तरीका 1. git stash2. git checkout -b otherBranch3. है।git stash pop
विनी जूल

@AlexanderBird: git update-refउपयोगी है, लेकिन यह वर्तमान शाखा के सिरे को भी हिलाता है।
टोमेक्वी

47

केवल मूल गिट कमांड का उपयोग करना:

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

अपना वर्तमान स्थान चिह्नित करें (यदि आवश्यक हो तो पहले प्रतिबद्ध हों):

git checkout -b temp

कार्यशील डीआईआर को बदले बिना दूसरी शाखा के मार्कर को रीसेट करें (चलता है):

git reset <branch where you want to go>

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

git checkout <branch where you want to go>

चूँकि आपका HEAD पहले से ही एक ही कमिट की ओर इशारा कर रहा है, काम करने वाले डायर को छुआ नहीं गया है

git branch -d temp

ध्यान दें कि ये कमांड किसी भी ग्राफिकल क्लाइंट से आसानी से उपलब्ध हैं।


7
मैं git reset --soft <branch where you want to go>सूचकांक को अपडेट करने से बचना पसंद करूंगा
जोएलफैन

7
मैं गिट प्लमिंग कमांड से बचने और चीनी मिट्टी के बरतन के पक्ष में आपकी रणनीति से सहमत हूं।
user64141

26

V2.24 git switchमें एक तिजोरी की तरह कुछ है git checkout
इसलिए मैंने "वर्कआउट को बदले बिना शाखा पर हॉप" के git hopलिए नीचे दिए गए उपनाम का नाम बदल दिया।

पाठक के लाभ के लिए:

जबकि मुझे लगता है कि चार्ल्स बेली का समाधान एक सही है, इस समाधान को किसी चीज़ पर स्विच करते समय एक मोड़ की आवश्यकता होती है, जो एक स्थानीय शाखा नहीं है। इसके अलावा कुछ तरीके भी होने चाहिए कि इसे रेगुलर कमांड के साथ कैसे किया जाए जिसे समझना आसान है। यहां वह है जो मैंने जुटाया:

git checkout --detach
git reset --soft commitish
git checkout commitish

व्याख्या की:

  • git checkout --detachवही है git checkout HEAD^{}जो वर्तमान शाखा को पीछे छोड़ता है और "अलग राज्य" में चला जाता है। तो HEADबिना किसी शाखा के अगले संशोधन किसी भी शाखा को प्रभावित नहीं करता है। Detaching HEADworktree है और न ही सूचकांक को प्रभावित नहीं करता।
  • git reset --soft commitishफिर HEADदिए गए SHA पर जाता है commitish। यदि आप इंडेक्स अपडेट करना चाहते हैं, तो भी छोड़ दें --soft, लेकिन मैं ऐसा करने की सलाह नहीं देता। यह, फिर से, वर्कट्री को नहीं छूता है, और ( --soft) इंडेक्स को नहीं।
  • git checkout commitishफिर HEADदिए गए commitish(शाखा) से फिर से जुड़ जाता है । (अगर commitishSHA होता है तो कुछ भी नहीं होता है।) यह भी, न तो सूचकांक को प्रभावित करता है और न ही वर्कट्री को।

यह समाधान सब कुछ स्वीकार करता है जो एक कमिट को संदर्भित करता है, इसलिए यह कुछ gitउपनामों के लिए आदर्श है । rev-parseनीचे ऐसी है कि लिखने की त्रुटियों गलती से अलग सिर राज्य में स्विच नहीं है (त्रुटि वसूली रास्ता और अधिक जटिल हो जाएगा) सुनिश्चित करने के लिए सिर्फ एक परीक्षण, श्रृंखला में कुछ भी नहीं टूटता है, है।

यह निम्नलिखित git hop treeishउपनाम की ओर जाता है :

git config --global alias.hop '!f() { git rev-parse --verify "$*" && git checkout "HEAD^{}" && git reset --soft "$*" && git checkout "$*"; }; f'

FYI करें, आप इसे मेरी gitउपनामों की सूची में पा सकते हैं ।


क्या आप $@इसके बजाय उपयोग नहीं करना चाहते हैं $*? अंतर यह है कि $ @ उद्धृत तर्कों का विस्तार नहीं है, जिनके अंदर रिक्त स्थान हैं।
कीब

1
@kyb फ़ंक्शन ट्रिक किसी अन्य SO उत्तर से चोरी हो जाती है । और $@निश्चित रूप से यहाँ मतलब नहीं है। $*के बजाय प्रयोग किया जाता है $1, जैसे कि git switch -f bवही हो जाता है git switch '-f b'जो एक त्रुटि होनी चाहिए। इस तरह मैं कुछ त्रुटि से निपटने के लिए दूर छोड़ने से उपनाम को छोटा कर सकता हूं जैसे!f() { [ 1 = $# ] || { echo 'WTF!'; return 1; }; ..
टिनो

बहुत अच्छा उपाय है। विशेष रूप से, कि इसका उपयोग दूरस्थ शाखाओं के लिए किया जा सकता है!
नेल्स-ओ-मैट

14

एक रिपॉजिटरी या दो रिपॉजिटरी के साथ दो वर्किंग डायरेक्टरी (दो वर्किंग एरिया) के लिए बेहतर समाधान नहीं होगा?

इसमें आपकी सहायता करने के लिए अनुभाग में git-new-workdir टूल है contrib/


क्या git-new-workdir, git के स्वयं के वर्कट्री कमांड के समान है? मैं वर्कट्री का उपयोग तब करता हूं जब मैं एक शाखा को एक अलग फ़ोल्डर में चेकआउट करना चाहता हूं (पूरे रेपो को क्लोन किए बिना)।
रियू

git-new-worktreeस्क्रिप्ट पहले का है git worktreesubcommand; उत्तर लिखे जाने पर यह आदेश उपलब्ध नहीं था। उदाहरण के लिए स्क्रिप्ट को सिमलिंक समर्थन की आवश्यकता होती है; IMHO देशी समर्थन का उपयोग करना बेहतर है।
जैकब नार

8

मुझे लगता है कि आप प्लंबिंग कमांड की तलाश कर रहे हैं git read-tree । यह इंडेक्स को अपडेट करेगा लेकिन आपके वर्किंग डायरेक्टरी में किसी भी फाइल को अपडेट नहीं करेगा। उदाहरण के लिए, यह मानना branchकि शाखा का नाम है:

git वाच-ट्री शाखा

यदि आप उस शाखा के लिए प्रतिबद्ध करना चाहते हैं जिसे आपने अभी पढ़ा है, तो आपको निम्नलिखित की आवश्यकता होगी:

git प्रतीकात्मक रेफरी HEAD refs / सिर / शाखा

नहीं, मुझे केवल शाखा बदलने की आवश्यकता है, कोई अन्य परिवर्तन नहीं है - इसलिए प्रतीकात्मक-रेफ काफी अच्छा है
tig

read-treeत्रुटि उत्पन्न करता है: fatal: Not a valid object name branchअगर कोई git switch branchअभी तक नहीं था
एंड्री

7

आप अपनी HEAD फाइल को एक अलग शाखा के नाम से अधिलेखित कर सकते हैं:

इको "रेफ: रेफ्स / हेड्स / मायऑथरब्रंच"> .गित / हेड


13
संभवतः आपके लिए ऐसा करने के लिए प्रतीकात्मक-रेफ कमांड का उपयोग करना बेहतर है: git symbolic-ref HEAD refs/heads/MyOtherBranch kernel.org/pub/software/scm/git/docs/git-symbolic-ref.html
ग्रेग हेगिल

@GregHewgill, यह एकमात्र तरीका है जिससे मैं HEAD को कमिटेड हैश में ले जा सकता हूं। क्या आप ऐसा कर सकते हैं git symbolic-ref?
टोमेक्वी

0

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


आप git-new-worktreeइसके बजाय (में contrib/)
जकुब नारबस्की

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

0

यदि आप बस एक दूरस्थ शाखा बिंदुओं को बदलने की कोशिश कर रहे हैं, तो आप इसे अपनी स्थानीय कॉपी को छूने के बिना "गिट पुश" के साथ कर सकते हैं।

http://kernel.org/pub/software/scm/git/docs/git-push.html

<Refspec> पैरामीटर का प्रारूप एक वैकल्पिक प्लस + ​​है, इसके बाद स्रोत रेफ <src>, इसके बाद एक कोलोन:, गंतव्य रेफरी <dst> द्वारा पीछा किया जाता है। इसका उपयोग यह निर्दिष्ट करने के लिए किया जाता है कि दूरस्थ रिपॉजिटरी में <src> ऑब्जेक्ट <dst> Ref को अद्यतन किया जाना है।

उदाहरण के लिए, c5f7eba करने के लिए फू को अपडेट करने के लिए निम्न कार्य करें:

git push origin c5f7eba:foo

यकीन नहीं है कि क्या आप के बाद थे या नहीं।


इस सवाल का पहले ही जवाब मिल गया: stackoverflow.com/questions/1282639/…
tig

0

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

      1. git checkout -f <new-branch>
      2. git cherry-pick -x <previous-branch-commit-id>

पिछला-शाखा-कमिट-आईडी वह प्रतिबद्ध है जहां से आप पुराने डेटा की प्रतिलिपि बनाना चाहते हैं।


0

या सिर्फ अपने मालिक को अपने मालिक से पैच करने के लिए एक पैच फ़ाइल का उपयोग करें

git diff otherbranch master > ~/tmp/otherbranch.diff
git checkout master
git apply ~/tmp/otherbranch.diff

-1

आप शाखा ए में रहना चाहते हैं, लेकिन शाखा बी की फाइलों के साथ

git लॉग के साथ शाखा A की वर्तमान प्रतिबद्ध प्रतिशोध को ढूंढें, जैसे "99ce9a2",

git checkout A
git reset --hard B
git reset 99ce9a2

अब आपको B के अनुरूप एक फ़ोल्डर संरचना के साथ शाखा A पर होना चाहिए, जो कि बिना किसी परिवर्तन के दिखाई देता है (A इतिहास नहीं बदला गया है)।

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