मर्ज (स्क्वैश के साथ) एक ही प्रतिबद्ध के रूप में एक और शाखा से सभी परिवर्तन


479

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

मैं अक्सर एक अलग शाखा में एक नई सुविधा पर काम करता हूं और नियमित रूप से / पुश करूंगा - मुख्य रूप से बैकअप के लिए या किसी अन्य मशीन पर जो मैं काम कर रहा हूं उसे स्थानांतरित करने के लिए। ज्यादातर वे कहते हैं "फ़ीचर xxx WIP" या कुछ बेमानी है।

एक बार जब वह काम खत्म हो जाता है और मैं डब्ल्यूआईपी शाखा को वापस मास्टर में विलय करना चाहता हूं, तो मैं उन सभी मध्यवर्ती कमिट्स को त्यागना चाहता हूं, और बस एक ही क्लीन कमिट है।

क्या इसे करने का कोई आसान तरीका है?

वैकल्पिक रूप से, कैसे एक कमांड के बारे में जो स्क्वाश करता है सब उस बिंदु पर होता है, जहां वह शाखा में था?

जवाबों:


601

एक अन्य विकल्प git merge --squash <feature branch>तो अंत में एक है git commit

से Git मर्ज

--squash

--no-squash

कार्यशील ट्री और इंडेक्स स्थिति का उत्पादन करें जैसे कि एक वास्तविक मर्ज हुआ (मर्ज की जानकारी को छोड़कर), लेकिन वास्तव में एक कमिट या स्थानांतरित करने के लिए HEADन तो रिकॉर्ड $GIT_DIR/MERGE_HEADकरें और न ही अगले git commitकमांड को मर्ज कमिट बनाने के लिए रिकॉर्ड करें । यह आपको वर्तमान शाखा के शीर्ष पर एक एकल प्रतिबद्ध बनाने की अनुमति देता है जिसका प्रभाव किसी अन्य शाखा (या एक ऑक्टोपस के मामले में अधिक) के विलय के समान है।


1
शांत सुविधा! मुझे गिट से प्यार है। हालांकि मैं निश्चित रूप से भविष्य में इसका उपयोग कर रहा हूं, फिर भी मैं आपको रिबेस-आई के आसपास अपना रास्ता जानने की सलाह दूंगा। यह एक अच्छा कौशल है, बस के मामले में आप वास्तव में उन्हें सिर्फ एक प्रतिबद्ध से अधिक बनाना चाहते थे।
विल बक

4
सावधानी का एक शब्द: यह काम करता है, लेकिन डिफ़ॉल्ट प्रतिबद्ध संदेश में शामिल होने वाली शाखा से लॉग शामिल है। समस्या यह है कि यह उस प्रारूप के समान है जिसे आप सामान्य रूप से देखते हैं जहां दिखाया गया संपूर्ण पाठ वास्तव में प्रतिबद्ध संदेश का हिस्सा नहीं बनता है, लेकिन इस मामले में वह ऐसा नहीं करता है। इसलिए यदि आप वह सब नहीं चाहते हैं, तो आपको मैन्युअल रूप से अपने कमिट मैसेज से यह सब हटाने की जरूरत है। मुझे इसका उपयोग करने से पहले इसका परीक्षण करना चाहिए था ...
still_dreaming_1

23
कि, और, चेतावनी दी जाए कि शाखा को विलय के रूप में नहीं देखा जाएगा। stackoverflow.com/questions/19308790/…
रायन

3
IMHO इसे बुलाया जाना चाहिए थाrebase --squash
एंडी

इसलिए (क्योंकि यह वास्तव में फीचर शाखा को मर्ज नहीं करता है) यह उचित होगा यदि आप कमिटमेंट के बाद फीचर शाखा को हटाने जा रहे हैं। क्या वो सही है? (मैं एक विशेषज्ञ विशेषज्ञ नहीं हूँ)
एंड्रयू स्पेंसर

214

मिल गया! मर्ज कमांड के पास एक --squashविकल्प है

git checkout master
git merge --squash WIP

इस बिंदु पर सब कुछ विलय कर दिया गया है, संभवतः विवादित है, लेकिन प्रतिबद्ध नहीं है। तो मैं अब कर सकता हूँ:

git add .
git commit -m "Merged WIP"

2
क्या करता git add .है?
माइकल पॉटर

1
@MichaelPotter यह सभी फ़ाइलों और परिवर्तनों को जोड़ता है
दक्ष शाह

2
git add .वर्तमान निर्देशिका में सभी गैर-अनदेखा फ़ाइलें जोड़ता है, मैं इस तरह से अनपेक्षित फ़ाइलों को लेने से सावधान रहूंगा।
जेक कोब

7
एक विकल्प के रूप में git add .आप git add -uकेवल उन फ़ाइलों को जोड़ने के लिए उपयोग कर सकते हैं जो पहले से ही पेड़ में जोड़े गए हैं।
ब्रैंडन ओगल

19
यह सुझाव देते हुए कि "git add।" किया जाना भी भ्रामक है। जब मैं "git मर्ज --squash WIP" करता हूं, तो इसमें पहले से ही इंडेक्स में स्क्वैश बदलाव होते हैं। जरूरत है तो बस उन्हें प्रतिबद्ध करने की। एक "git ऐड करना।" उन परिवर्तनों को जोड़ देगा जो कार्यशील निर्देशिका में होते हैं, लेकिन जो सुविधा शाखा का हिस्सा नहीं थे। सवाल यह था कि फीचर ब्रांच में बदलाव को किस तरह कमिट किया जाए।
जॉन पेंकोविज़

30

git rebase -i masterअपनी सुविधा शाखा पर प्रयास करें । फिर आप सभी लेकिन एक 'पिक' को 'स्क्वैश' में बदल सकते हैं ताकि कमिट्स को मिलाया जा सके। रिबास के साथ स्क्वाशिंग कमिट देखें

अंत में, आप तब मास्टर शाखा से मर्ज कर सकते हैं।


8
हां जो काम करता है, लेकिन मैं इंटरएक्टिव रिबेस की परेशानी नहीं चाहता हूं। मैं सिर्फ सब कुछ चाहता हूं क्योंकि शाखा चपटी है।
ब्रैड रॉबिंसन

2
+1 यह एक स्वच्छ इतिहास के लिए बनाता है। यह व्यक्तिगत पैच, कार्ड, कहानियों, आदि के रूप में कमिट को पहचानने और प्रबंधित करने के लिए बहुत आसान है
रयान

2

स्वीकृत उत्तर केgit merge --squash <feature branch> रूप में उपयोग करने से पता चलता है कि यह चाल है लेकिन यह विलय की गई शाखा को नहीं दिखाएगा जैसा कि वास्तव में विलय किया गया है।

इसलिए एक और भी बेहतर समाधान है:

  • नवीनतम मास्टर से एक नई शाखा बनाएँ
  • <feature branch>ऊपर का उपयोग कर मर्ज करेंgit merge --squash
  • नए बनाए गए शाखा को मास्टर में मर्ज करें

यह विकी प्रक्रिया के बारे में विस्तार से बताता है।


0

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

अपने .itconfig में निम्न उपनाम रखकर इसे स्थापित करें:

[alias]
  freebase = "!f() { \
    TOPIC="$(git branch | grep '\\*' | cut -d ' ' -f2)"; \
    NEWBASE="${1:-master}"; \
    PREVSHA1="$(git rev-parse HEAD)"; \
    echo "Freebaseing $TOPIC onto $NEWBASE, previous sha1 was $PREVSHA1"; \
    echo "---"; \
    git reset --hard "$NEWBASE"; \
    git merge --squash "$PREVSHA1"; \
    git commit; \
  }; f"

इसे अपनी सुविधा शाखा से चलाकर उपयोग करें: git freebase <new-base>

मैंने केवल कुछ ही बार इसका परीक्षण किया है, इसलिए इसे पहले पढ़ें और सुनिश्चित करें कि आप इसे चलाना चाहते हैं। एक छोटे से सुरक्षा उपाय के रूप में, यह शुरू करने वाले sha1 को प्रिंट करता है इसलिए आपको अपनी पुरानी शाखा को पुनर्स्थापित करने में सक्षम होना चाहिए अगर कुछ भी गलत हो जाता है।

मैं इसे गितुब पर अपने डॉटफाइल्स रेपो में बनाए रखूंगा: https://github.com/stevecrozz/dotfiles/blob/master/.gitconfig


आनंद की तरह काम किया! तुम भी पर एक नज़र ले सकता है evernote.com/shard/s52/sh/7f8f4ff1-9a68-413f-9225-c49e3ee2fafd/...
इल्या Sheershoff

-1

git merge --squash <feature branch> एक अच्छा विकल्प है। "गिट कमिट" आपको यह बताने के लिए आपकी पसंद के साथ सभी सुविधा शाखा प्रतिबद्ध संदेश बताता है।

कम प्रतिबद्ध मर्ज के लिए।

git मर्ज करते हैं x बार --गित रीसेट HEAD ^ --soft फिर git कमिट।

जोखिम - हटाई गई फाइलें वापस आ सकती हैं।


-5

आप इसे "रिबेस" कमांड के साथ कर सकते हैं। चलो शाखाओं को "मुख्य" और "सुविधा" कहते हैं:

git checkout feature
git rebase main

रिबास कमांड "फ़ीचर" के सभी कमेंट्स को फिर से करेगा, जैसा कि एक "मुख्य" के बराबर माता-पिता के साथ होता है।

यदि "फीचर" बनाया गया था (या सबसे हाल के मर्ज के बाद) "मुख्य" बदल गया है, तो आप git merge mainपहले चलाना चाह सकते हैं git rebase main। इस तरह, आपके पास अभी भी अपना पूरा इतिहास है यदि आपके पास मर्ज संघर्ष था।

रिबास के बाद, आप अपनी शाखा को मुख्य में विलय कर सकते हैं, जिसके परिणामस्वरूप तेजी से आगे विलय हो सकता है:

git checkout main
git merge feature

एक अच्छे सिंहावलोकन के लिए अवधारणात्मक रूप से समझ पाने का पुन: पृष्ठ देखें


यह मेरे लिए काम नहीं किया। मैंने सिर्फ एक सरल परीक्षण रेपो बनाया, जिसमें एक WIP शाखा थी और ऊपर की कोशिश की और मर्ज संघर्ष (भले ही मैंने मास्टर पर कोई बदलाव नहीं किया था) हो गया।
ब्रैड रॉबिन्सन

यदि सुविधा मुख्य (git चेकआउट -b फीचर मुख्य) से बनाई गई थी और आपके पास मुख्य से हाल ही में मर्ज था, तो आपको
रिबास

ठीक है, फिर से कोशिश की। इस बार संघर्ष नहीं हुआ, लेकिन इतिहास को तोड़-मरोड़ कर पेश नहीं किया गया।
ब्रैड रॉबिन्सन

गिट-मर्ज प्रलेखन पर एक और नज़र डालते हुए, आप सही हैं, कुछ कमिट्स रहेंगे। यदि आपने "मुख्य" से "फीचर" में पिछले मर्ज किए हैं, तो रिबास उनमें से कुछ को हटा देगा, लेकिन सभी नहीं।
नामशूब्रिटर

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