Git में, मर्ज - स्क्वैश और रिबेस के बीच अंतर क्या है?


363

मैं नया हूँ और मैं एक स्क्वैश और एक रिबेस के बीच के अंतर को समझने की कोशिश कर रहा हूँ। जैसा कि मैंने समझा कि आप एक रिबास करते समय स्क्वैश करते हैं।

जवाबों:


360

दोनों git merge --squashऔर git rebase --interactive"कुचल" एक प्रतिबद्ध उत्पादन कर सकते हैं।
लेकिन वे विभिन्न उद्देश्यों की पूर्ति करते हैं।

किसी भी मर्ज संबंध को चिह्नित किए बिना, गंतव्य शाखा पर एक स्क्वैश प्रतिबद्ध का उत्पादन करेगा।
(नोट: यह तुरंत एक प्रतिबद्ध उत्पादन नहीं करता है: आपको एक अतिरिक्त की आवश्यकता है git commit -m "squash branch")
यह उपयोगी है यदि आप स्रोत शाखा को पूरी तरह से फेंकना चाहते हैं, तो जा रहे हैं (एसओए प्रश्न से लिया गया स्कीमा ):

 git checkout stable

      X                   stable
     /                   
a---b---c---d---e---f---g tmp

सेवा:

git merge --squash tmp
git commit -m "squash tmp"

      X-------------------G stable
     /                   
a---b---c---d---e---f---g tmp

और फिर tmpशाखा को हटाना ।


नोट: git mergeएक --commitविकल्प है , लेकिन इसका उपयोग नहीं किया जा सकता है --squash। इसका उपयोग और एक साथ करना कभी संभव नहीं था । Git 2.22.1 (Q3 2019) के बाद से, यह असंगति स्पष्ट कर दी गई है:--commit--squash

विशाल वर्मा ( ) द्वारा देखें 1d14d0c (24 मई 2019 )(द्वारा विलय Junio सी Hamano - - में प्रतिबद्ध 33f2790 , 25 जुला 2019)reloadbrain
gitster

merge: के --commitसाथ मना कर दिया--squash

पहले, जब --squashआपूर्ति की गई थी, ' option_commit' चुपचाप गिरा दिया गया था। यह --commitस्पष्ट रूप से उपयोग करके स्क्वैश के नो-कम व्यवहार को ओवरराइड करने की कोशिश करने वाले उपयोगकर्ता के लिए आश्चर्यजनक हो सकता है ।

git/git builtin/merge.c#cmd_merge() अब शामिल हैं:

if (option_commit > 0)
    die(_("You cannot combine --squash with --commit."));

एक नए आधार पर आपके कुछ या सभी हिट्स को रिप्लाई करता है, जिससे आप सीधे स्क्वैश कर सकते हैं (या हाल ही में "ठीक करें", इस SO प्रश्न को देखें ), सीधे जा रहे हैं:

git checkout tmp
git rebase -i stable

      stable
      X-------------------G tmp
     /                     
a---b

यदि आप सभी प्रकार के स्क्वैश का चयन करते हैं tmp(लेकिन, इसके विपरीत merge --squash, आप कुछ को फिर से खेलना और दूसरों को स्क्वैश करना चुन सकते हैं)।

तो मतभेद हैं:

  • squashअपनी स्रोत शाखा ( tmpयहां) को नहीं छूता है और जहां आप चाहते हैं, वहां एक एकल प्रतिबद्ध बनाता है।
  • rebaseआपको उसी स्रोत शाखा (अभी भी tmp) पर जाने की अनुमति देता है :
    • एक नया आधार
    • एक क्लीनर इतिहास

11
Gएक c--d--e--f--gसाथ स्क्वैश है?
वेन कॉनराड

8
@Wayne: हाँ, जी उन उदाहरणों में tmpएक साथ स्केम किए गए कमिट्स का प्रतिनिधित्व करते हैं।
वॉनक

3
@ Th4wn: चूंकि किसी प्रोजेक्ट के स्नैपशॉट के साथ Git कारण , द्वारा प्रस्तुत किए गए परिवर्तनों की वजह Gसे समान सामग्री का प्रतिनिधित्व नहीं करेगा । gX
वॉनसी

1
@VonC: उस अंतिम टिप्पणी के बारे में निश्चित नहीं है। यदि आपके पास git merge --no-ff tempइसके बजाय है git merge --squash temp, तो आपको एक गड़बड़ इतिहास मिलता है, लेकिन आप यह भी कर सकते हैं जैसे कि git revert e, बहुत आसानी से। यह एक गड़बड़, लेकिन ईमानदार और व्यावहारिक इतिहास है, और मुख्य शाखा अभी भी काफी साफ बनी हुई है।
n

2
@ n-0101 मैं सहमत हूं। जैसा कि stackoverflow.com/a/7425751/6309 में बताया गया है , यह भी नहीं तोड़ने git bisectया git blameजब बहुत बार उपयोग किया जाता है (जैसा कि git pull --no-ff: stackoverflow.com/questions/12798767/… )। वैसे भी एक दृष्टिकोण नहीं है, यही वजह है कि इस लेख में तीन का वर्णन किया गया है ( stackoverflow.com/questions/9107861/… )
VonC

183

मर्ज करता है: अपनी शाखा के सभी कमेंट्स को बरकरार रखता है और बेस ब्रांच पर कमिट्स के साथ उन्हें इंटरलेक्ट करता हैयहां छवि विवरण दर्ज करें

मर्ज स्क्वैश: परिवर्तनों को बरकरार रखता है लेकिन इतिहास से अलग व्यक्ति को छोड़ देता है यहां छवि विवरण दर्ज करें

Rebase: यह मास्टर शाखा की नोक पर शुरू करने के लिए पूरी सुविधा शाखा को स्थानांतरित करता है, प्रभावी रूप से मास्टर में सभी नए कमेंट्स को शामिल करता है

यहां छवि विवरण दर्ज करें

यहाँ पर और अधिक


81

मर्ज स्क्वाश एक पेड़ (कमिट्स का एक क्रम) को एक ही प्रतिबद्ध में मिला देता है। यही है, यह n में किए गए सभी परिवर्तनों को एक ही कमिट में स्क्वैश करता है।

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

इंटरेक्टिव रिबेस करने के दौरान, आपको स्क्वैश चुनने, संपादित करने या छोड़ने के विकल्प दिए जाते हैं।

उम्मीद है कि स्पष्ट था!


7
मुझे कब रिबेस करना चाहिए और कब स्क्वैश करना चाहिए?
मार्टिन थोमा

31

निम्नलिखित उदाहरण से शुरू करते हैं:

यहां छवि विवरण दर्ज करें

अब हमारे पास सुविधा शाखा के परिवर्तन को मास्टर शाखा में विलय करने के लिए 3 विकल्प हैं :

  1. मर्ज करता है
    सभी सुविधा शाखा के इतिहास को जारी रखेंगे और उन्हें मास्टर शाखा में स्थानांतरित
    करेंगे। अतिरिक्त डमी प्रतिबद्ध करेंगे।

  2. रिबास और मर्ज
    करेंगे सभी मास्टर शाखा के सामने सुविधा शाखा के इतिहास को जोड़ेंगे अतिरिक्त डमी प्रतिबद्ध नहीं जोड़ेंगे।

  3. स्क्वैश और मर्ज
    विल समूह के सभी सुविधा शाखा में प्रतिबद्ध एक प्रतिबद्ध तो संलग्न इसे के सामने मास्टर शाखा
    जोड़ने होगा अतिरिक्त डमी प्रतिबद्ध।

आप नीचे पा सकते हैं कि मास्टर शाखा उनमें से प्रत्येक के बाद कैसे दिखेगी

यहां छवि विवरण दर्ज करें

सभी मामलों में:
हम सुविधा शाखा को सुरक्षित रूप से हटा सकते हैं ।


1
क्या आप बता सकते हैं कि डमी दूसरी तस्वीर में क्या है? मैं एक शुरुआत करने वाला हूं।
यूसुफ

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