Git मर्ज --squash का उपयोग कैसे करें?


1208

मेरे पास एक दूरस्थ Git सर्वर है, यहां वह परिदृश्य है जो मैं प्रदर्शन करना चाहता हूं:

  • प्रत्येक बग / सुविधा के लिए मैं एक अलग Git शाखा बनाता हूं

  • मैं अपने कोड को उस Git शाखा में अन-ऑफिशियल Git संदेशों के साथ रखना चाहता हूं

  • शीर्ष भंडार में हमें आधिकारिक बग संदेश के साथ एक बग के लिए एक प्रतिबद्ध करना होगा

इसलिए मैं अपनी शाखा को सुदूर शाखा में कैसे मिला सकता हूं ताकि वे मेरे सभी चेक-इन के लिए सिर्फ एक कमिटमेंट प्राप्त कर सकें (मैं इसके लिए प्रतिबद्ध संदेश भी देना चाहता हूं)?


1
मुझे यकीन नहीं है कि अगर मैं आपको पूरी तरह से समझ गया हूं, लेकिन आप "ऑक्टोपस मर्ज" चाहते हैं।
मेट्रिक्सफ्रॉग

26
मैं आमतौर पर git rebase -i का उपयोग अपने सभी कमिट्स को एक कमिट में समाप्‍त करने और कमिट मैसेज को री-राइट करने के लिए करता हूं। फिर मैं इसे ऊपर की ओर भेजता हूं।
एडवर्ड फॉक

17
git merge --squashयह सब एक शॉट में कमांड लाइन पर होता है और आप बस उम्मीद करते हैं कि यह काम करे। git rebase -iएक संपादक को लाता है और आपको रिबास को ठीक करने देता है। यह धीमा है, लेकिन आप देख सकते हैं कि आप क्या कर रहे हैं। इसके अलावा, रिबेज और मर्ज में अंतर होता है जो एक टिप्पणी में संबोधित करने के लिए बहुत कम शामिल हैं।
एडवर्ड फॉक

4
इन सभी उत्तरों के साथ समस्या यह है कि आपको स्थानीय रूप से मास्टर ब्रांच में रहना होगा और मर्ज --squash कमांड को रन करना होगा ... मैं मर्ज को रन करना चाहता हूं - फीचर ब्रांच से मास्टर क्लास नहीं..इसलिए। जब मैं काम कर रहा होता हूं, तो मैं फीचर शाखा को रिमोट से पुश कर सकता हूं और पीआर सबमिट कर सकता हूं, क्या यह संभव है?
अलेक्जेंडर मिल्स

2
@AlexanderMills, मुझे लगता है कि आपको बस एक दूसरी सुविधा शाखा (मास्टर शाखा से क्लोन) की आवश्यकता है। क्या merge --squashनया करने के लिए पुराने से, और फिर गुरु के नई शाखा मर्ज करें। पुरानी शाखा पुरानी हो जाती है।
गायरोमाइट

जवाबों:


1998

कहते हैं कि आपका बग फिक्स ब्रांच कहलाता है bugfixऔर आप इसे मर्ज करना चाहते हैं master:

git checkout master
git merge --squash bugfix
git commit

यह bugfixशाखा से सभी कमिट्स ले जाएगा , उन्हें 1 कमिट में स्क्वैश करेगा, और इसे अपनी masterशाखा के साथ मर्ज करेगा ।


स्पष्टीकरण :

git checkout master

अपनी masterशाखा में बदल जाता है।

git merge --squash bugfix

bugfixशाखा से सभी कमिट्स लेता है और इसे आपकी वर्तमान शाखा के साथ विलय कर देता है।

git commit

मर्ज किए गए परिवर्तनों से एक ही प्रतिबद्ध बनाता है।

-mपैरामीटर को स्वीकार करने से आप अपनी प्रतिबद्धताओं को अंतिम रूप देने से पहले अपने स्क्वैश किए गए कमिट से हर संदेश वाले ड्राफ्ट कमिट मेसेज को संशोधित कर सकते हैं।


222
यदि आप पुराने प्रतिबद्ध संदेशों के संदर्भों को रखना चाहते हैं जो आप लिख सकते हैं git commit(बिना -mपरम)
एलेक्स

12
आप git commit --amend -m '...'बाद में ऐसा करके हासिल कर सकते हैं ।
Janusz Lenar

19
मामले में मर्ज संघर्ष होता है और आप इन संघर्षों को हल करते हैं, git commitअब आपके द्वारा स्क्वीड किए गए सभी प्रतिबद्ध संदेशों में उपयोगी प्रतिबद्ध संदेश नहीं दिखाई देगा। उस स्थिति में, प्रयास करें git commit --file .git/SQUASH_MSG( stackoverflow.com/a/11230783/923560 के माध्यम से )।
अब्दुल

23
ध्यान रखें कि स्क्वैश डिफ़ॉल्ट रूप से स्क्वैश करने वाले को कमिट करेगा । मूल लेखक को रखने के लिए, आपको स्पष्ट रूप से इसे इस तरह निर्दिष्ट करने की आवश्यकता है:git commit -a --author="Author" --message="Issue title #id"
विशाल

5
git merge --squashआपको वर्तमान शाखा के शीर्ष पर एक एकल प्रतिबद्ध बनाने की अनुमति देता है जिसका प्रभाव दूसरी शाखा को विलय करने के समान है। लेकिन यह मर्ज रिकॉर्ड का उत्पादन नहीं करेगा, जिसका अर्थ है कि परिणाम के रूप में आपके पुल-अनुरोध में कोई परिवर्तन नहीं होगा, फिर भी विलय के रूप में चिह्नित नहीं किया जाएगा! इसलिए, आपको बस उस शाखा को हटाने की आवश्यकता होगी।
am0wa

129

आखिरकार मेरे लिए यह साफ हो गया कि यह एक टिप्पणी थी जो दिखा रही थी:

git checkout main
git merge --squash feature

करने के बराबर है:

git checkout feature
git diff main > feature.patch
git checkout main
patch -p1 < feature.patch
git add .

जब मैं 105 (!!) के साथ एक फीचर शाखा को मर्ज करना चाहता हूं और उन सभी को एक में स्क्वैश कर दिया है, तो मैं नहीं करना चाहता git rebase -i origin/masterक्योंकि मुझे प्रत्येक मध्यवर्ती कमिट (या कम से कम वाले) के लिए अलग से मर्ज संघर्ष को हल करने की आवश्यकता है git खुद पता नहीं लगा सकता)। उपयोग करने git merge --squashसे मुझे वह परिणाम मिलता है, जो मैं चाहता हूं कि एक पूरी सुविधा शाखा के विलय के लिए एक ही प्रतिबद्ध हो। और, मुझे केवल एक ही मैनुअल संघर्ष समाधान पर करने की आवश्यकता है।


75
मैं पहले फ़ीचर ब्रांच में मर्ज करने का अत्यधिक सुझाव देता हूं git merge master, और उसके बाद ही git merge --squash featureमास्टर ब्रांच में।
50 पर डॉटैंकोहेन

8
@dotancohen एक पुरानी टिप्पणी को क्षमा करने के लिए क्षमा करें :) git merge --squash featureमास्टर शाखा से प्रदर्शन करने से पहले फीचर शाखा में विलय से क्या प्राप्त होता है ?
बिटसमैक

57
आप पहले फीचर शाखा में मास्टर को मर्ज करना चाहते हैं, और अपनी सुविधा शाखा में किसी भी मैनुअल सुधार के साथ सौदा करना चाहते हैं। इससे आप परीक्षण भी चला सकते हैं और सुनिश्चित कर सकते हैं कि आपकी सुविधा शाखा सही ढंग से काम करती है। फिर, आपको गारंटी दी जाती है कि आप अपनी सुविधा शाखा का एक स्वचालित मर्ज मास्टर में कर सकते हैं।
दान कोन

4
@dankohn मेरा सुझाव है कि आप अपने उपरोक्त टिप्पणी में स्पष्टीकरण को अपने उत्तर में जोड़ें।
guntbert

3
@bitmack: आप मास्टर को पहले फीचर में मर्ज करेंगे। यह आपको फीचर को मास्टर
माइक

97

आप स्क्वैश विकल्प के साथ विलय करना चाहते हैं। यदि आप इसे एक बार में एक शाखा करना चाहते हैं।

git merge --squash feature1

यदि आप एक ही समय में सभी शाखाओं को मर्ज करना चाहते हैं, तो पहले एकांत में रिबास करें और प्रत्येक सुविधा को स्क्वैश करें फिर ऑक्टोपस मर्ज करें:

git checkout feature1
git rebase -i master

एक प्रतिबद्ध में स्क्वैश करें फिर अन्य सुविधाओं के लिए दोहराएं।

git checkout master
git merge feature1 feature2 feature3 ...

यह अंतिम मर्ज एक "ऑक्टोपस मर्ज" है क्योंकि यह एक ही बार में बहुत सारी शाखाओं का विलय कर रहा है।

उम्मीद है की यह मदद करेगा


3
आप क्यों पलटवार कर रहे हैं?
उमैर ए।

12
@UmairAshraf यह एक इंटरैक्टिव रिबेस है जो आपको अपनी शाखा में स्क्वैश करने का विकल्प देता है।
-हो

1
रिबासिंग एक बुरा विचार है। पहले से प्रकाशित किए गए
पुनर्खरीद

1
@ Sebi2020 git मर्ज --squash आपके पहले से प्रकाशित किए गए कमिट्स को इस तरह से रीबैज करेगा जो एक इंटरेक्टिव रिबेस से भी बदतर है। एक इंटरैक्टिव रिबास (एक सुविधा शाखा पर) कोई प्रतिकूल प्रभाव के लिए कम ले।
xiix

1
@xiix यह केवल तभी सही है जब आप केवल सुविधा शाखा के साथ काम कर रहे हों। यह एक धारणा नहीं है जिसे आप बना सकते हैं। मैं गिट-एससीएम पर रीबासिंग से संबंधित पृष्ठों को पढ़ने की सलाह देता हूं । इसमें कहा गया है कि " अपने भंडार के बाहर मौजूद कमिट्स को रिबेट न करें और उन पर लोगों का काम आधारित हो सकता है। " git की प्रकृति) आप ऐसा नहीं करते।
सेबी 2020

23

यदि आपके पास पहले से ही git merge bugfixहै main, तो आप अपने मर्ज कमिटमेंट को एक में स्क्वैश कर सकते हैं:

git reset --soft HEAD^1
git commit

git reset --soft HEAD^1मर्ज से पहले की गई अंतिम प्रतिबद्ध को पूर्ववत करने के लिए लगता है , मर्ज के तेजी से आगे होने के मामले में कम से कम।
जेस्पर मैथेनीसेन

@JesperMatthiesen तेजी से आगे बढ़ने के मामले में आपको मर्ज कमिटमेंट नहीं मिलता है, तो आप ऐसा करेंगे git reset --soft HEAD^<number-of-commits-to-squash>
क्वर्टीजगुई

इसने मुझे डाउनस्ट्रीम मर्ज के बाद एक ही कमिट में सब कुछ स्क्वैश करने में मदद की।
किलोज

18

एक कस्टम कमिट के साथ newFeatureब्रांच को मर्ज masterकरें:

git merge --squash newFeature && git commit -m 'Your custom commit message';

यदि इसके बजाय, आप करते हैं

git merge --squash newFeature && git commit

आपको एक संदेश मिलेगा जिसमें सभी newFeatureशाखाएँ सम्मिलित होंगी , जिन्हें आप अनुकूलित कर सकते हैं।

मैं इसे यहाँ अच्छी तरह समझाता हूँ: https://youtu.be/FQNAIacelT4


10

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

गितुब के पास स्क्वैश मर्ज करने की क्षमता है, जो रिपॉजिटरी के लिए सक्षम मर्ज विकल्पों पर निर्भर करता है।

यदि स्क्वैश मर्ज सक्षम हैं, तो "स्क्वैश और मर्ज" विकल्प "मर्ज" बटन के तहत ड्रॉपडाउन में दिखाई देना चाहिए।

"स्क्वैश और मर्ज" जीथब फीचर का स्क्रीनशॉट


GitHub आपके खाते से जुड़े डिफ़ॉल्ट ईमेल का उपयोग करता है। यदि आपके पास कई ईमेल पते हैं, और आपको द्वितीयक उपयोग करने की आवश्यकता है, तो आप GH UI का उपयोग नहीं कर सकते।
लुका गाइडी

4

मान लीजिए कि आपने कई हिट के साथ फ़ीचर / टास्क 1 में काम किया है।

  1. अपनी परियोजना शाखा पर जाएं (परियोजना / my_project)

    git checkout project/my_project
    
  2. एक नई शाखा बनाएँ (सुविधा / task1_bugfix)

    git checkout -b feature/task1_bugfix
    
  3. --squashविकल्प के साथ मर्ज करें

    git merge --squash feature/task1
    
  4. सिंगल कमेट बनाएं

    git commit -am "add single comments"
    
  5. अपनी शाखा को धक्का दें

    git push --set-upstream origin feature/task1_bugfix
    

1

गिट के लिए

एक नई सुविधा बनाएँ

टर्मिनल / शेल के माध्यम से:

git checkout origin/feature/<featurename>
git merge --squash origin/feature/<featurename>

यह इसे कमिट नहीं करता है, आपको पहले इसकी समीक्षा करने की अनुमति देता है।

फिर इस नई शाखा से कमिटमेंट और फिनिश फीचर, और पुराने को डिलीट / इग्नोर करें (जिसे आपने डिसाइड किया था)।


@Melebius "SourceTree" का एकमात्र संदर्भ आपके वाक्य में है, अगर यह एक टैग या पिछला प्रश्न था: यह अब मौजूद नहीं है।
जॉर्डन स्टेफानेली

1
इस उत्तर के मूल संस्करण में @JordanStefanelli SourceTree का उपयोग किया गया था । यह तय करने के लिए धन्यवाद!
मेलेबियस

1

यदि आपको त्रुटि मिलती है: कमिटिंग संभव नहीं है क्योंकि आपके पास अनमैरिड फाइलें हैं।

git checkout master
git merge --squash bugfix
git add .
git commit -m "Message"

सभी संघर्ष फाइलों को तय किया

git add . 

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

git add [filename]

0

धक्का देने से पहले अपनी स्थानीय शाखा को स्क्वैश करने के लिए:

  1. यदि यह पहले से ही चेक आउट नहीं है, तो काम करने के लिए शाखा में चेकआउट करें।

  2. आप चाहते हैं कि रखने के लिए सबसे पुराना प्रतिबद्ध के आकार का पता लगाएं।

  3. उस कमेटी से एक नई शाखा (tmp1) बनाएं / चेक करें।

    git checkout -b tmp1 <sha1-of-commit>

  4. मूल शाखा को नए एक स्क्वैश में मिलाएं।

    git merge --squash <original branch>

  5. एक सारांश प्रतिबद्ध संदेश के साथ मर्ज के द्वारा जो परिवर्तन किए गए हैं, उन्हें प्रतिबद्ध करें।

    git commit -m <msg>

  6. उस मूल शाखा को चेकआउट करें जिसे आप स्क्वैश करना चाहते हैं।

    git checkout <branch>

  7. मूल प्रतिबद्ध शा पर रीसेट करें जिसे आप रखना चाहते हैं।

    git reset --soft <sha1>

  8. नई tmp1 शाखा के आधार पर इस शाखा को पुनः भेजें।

    git rebase tmp1

  9. यह है - अब अस्थायी tmp1 शाखा को हटा दें एक बार जब आप सुनिश्चित करें कि सब कुछ ठीक है।


0

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

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