मेरे पिछले एक्स स्क्वैश एक साथ Git का उपयोग करता है


3585

मैं अपने अंतिम X को एक साथ Git का उपयोग करते हुए कैसे कर सकता हूं?


12
इसी तरह के सवाल: stackoverflow.com/questions/7275508/…
koppor


2
@matt TortoiseGit आपका टूल है। यह एक एकल फ़ंक्शन "कमिट टू वन कमिट" प्रदान करता है जो पृष्ठभूमि में सभी चरणों को स्वचालित रूप से कॉल करेगा। दुर्भाग्य से केवल विंडोज के लिए उपलब्ध है। नीचे मेरा जवाब देखें।
मथायस एम

1
पहली प्रतिबद्ध तक
स्क्वाश

1
पोस्ट स्क्वैश एक करने के लिए बल धक्का stackoverflow.com/questions/10298291/…
vikramvi

जवाबों:


2091

मैनुअलgit rebase -i <after-this-commit> में वर्णित "स्क्वैश" या "फिक्सअप" के साथ दूसरे और बाद में "पिक" का उपयोग करें और बदलें ।

इस उदाहरण में, <after-this-commit>या तो SHA1 हैश है या वर्तमान शाखा के HEAD से संबंधित स्थान है जहां से रीमेस कमांड के लिए कमिट का विश्लेषण किया जाता है। उदाहरण के लिए, यदि उपयोगकर्ता पिछले कमांड में वर्तमान कमांड से 5 कमिट्स देखना चाहता है git rebase -i HEAD~5


260
यह, मुझे लगता है, इस सवाल का जवाब थोड़ा बेहतर stackoverflow.com/a/5201642/295797
रॉय Truelove

92
क्या मतलब है <after-this-commit>?
2540625

43
<after-this-commit>प्रतिबद्ध है X + 1 यानी सबसे पुराने माता-पिता के लिए आप स्क्वैश करना चाहते हैं।
12

339
मुझे यह उत्तर बहुत स्पष्ट समझ में नहीं आया। एक उदाहरण से मदद मिली होगी।
इयान ओल्मन

53
इस rebase -iदृष्टिकोण और के बीच का अंतर reset --soft, rebase -iमुझे प्रतिबद्ध लेखक को बनाए रखने की reset --softअनुमति देता है , जबकि मुझे फिर से जोड़ने की अनुमति देता है। कभी-कभी मुझे लेखक की जानकारी को बनाए रखने के लिए अभी तक पुल अनुरोधों को स्वीकार करना पड़ता है। कभी-कभी मुझे अपने स्वयं के कमिट पर नरम रीसेट करने की आवश्यकता होती है। वैसे भी दोनों महान जवाब के लिए Upvotes।
जियोनीक्स

3825

आप इसे आसानी से git rebaseया बिना आसानी से कर सकते हैं git merge --squash। इस उदाहरण में, हम पिछले 3 कमिट्स को स्क्वैश करेंगे।

यदि आप स्क्रैच से नया कमिट संदेश लिखना चाहते हैं, तो यह पर्याप्त है:

git reset --soft HEAD~3 &&
git commit

यदि आप नई प्रतिबद्ध संदेश को मौजूदा प्रतिबद्ध संदेशों (जैसे कि पिक / स्क्वैश / स्क्वैश /… / स्क्वैश git rebase -iइंस्ट्रक्शन लिस्ट आप के साथ शुरू करेंगे) के संयोजन के साथ शुरू करना चाहते हैं, तो आपको उन संदेशों को निकालने और पास करने की आवश्यकता है उन्हें git commit:

git reset --soft HEAD~3 && 
git commit --edit -m"$(git log --format=%B --reverse HEAD..HEAD@{1})"

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


163
हा! मुझे यह तरीका पसंद है। यह समस्या की भावना को बंद करता है। यह अफ़सोस की बात है कि इसके लिए बहुत अधिक वूडू की आवश्यकता है। बुनियादी कमांड में से कुछ को इस तरह जोड़ा जाना चाहिए। संभवतः git rebase --squash-recent, या यहां तक ​​कि git commit --amend-many
एड्रियन रत्नापाल

13
@ABB: यदि आपकी शाखा में "अपस्ट्रीम" सेट है, तो आप उपयोग कर सकते हैं branch@{upstream}(या सिर्फ @{upstream}वर्तमान शाखा के लिए; दोनों ही मामलों में, अंतिम भाग संक्षिप्त रूप में देखा जा सकता है @{u}; gitrevisions देखें )। यह आपके "अंतिम पुश किए गए कमिट" से अलग हो सकता है (जैसे कि अगर किसी और ने कुछ ऐसा धक्का दिया, जो आपके सबसे हाल के पुश को बनाए और फिर आपने उसे प्राप्त किया), लेकिन ऐसा लगता है कि आप जो चाहते हैं उसके करीब हो सकता है।
क्रिस जॉन्सन

104
इस थोड़े-छांटे की मुझे आवश्यकता थी push -fलेकिन अन्यथा यह प्यारा था, धन्यवाद।
2rs2ts

39
@ 2rs2ts git पुश -f ध्वनि खतरनाक। केवल स्थानीय स्क्वैश का ध्यान रखें। कभी नहीं धक्का दिया कमिट्स!
मथायस एम

20
मुझे git push --forceबाद में भी उपयोग करने की आवश्यकता है ताकि यह प्रतिबद्ध हो जाए
Zach Saucier

738

आप इसके लिए उपयोग कर सकते हैं git merge --squash, जो की तुलना में थोड़ा अधिक सुरुचिपूर्ण है git rebase -i। मान लीजिए कि आप मास्टर हैं और आप अंतिम 12 को एक में बदलना चाहते हैं।

चेतावनी: पहले सुनिश्चित करें कि आप अपना काम कर रहे हैं - git statusसाफ है कि जाँच करें (क्योंकि git reset --hardमंचन और अस्थिर परिवर्तन फेंक देंगे)

फिर:

# Reset the current branch to the commit just before the last 12:
git reset --hard HEAD~12

# HEAD@{1} is where the branch was just before the previous command.
# This command sets the state of the index to be as it would just
# after a merge from that commit:
git merge --squash HEAD@{1}

# Commit those squashed changes.  The commit message will be helpfully
# prepopulated with the commit messages of all the squashed commits:
git commit

के लिए प्रलेखनgit merge--squash अधिक विस्तार से विकल्प का वर्णन करता है।


अद्यतन: अपने जवाबgit reset --soft HEAD~12 && git commit में क्रिस जॉन्सन द्वारा सुझाए गए सरल से अधिक इस पद्धति का एकमात्र वास्तविक लाभ यह है कि आपको हर प्रतिबद्ध संदेश के साथ पूर्वनिर्मित संदेश मिल जाता है जिसे आप स्क्वैश कर रहे हैं।


16
आप कहते हैं कि यह 'से अधिक सुरुचिपूर्ण' है git rebase -i, लेकिन आप एक कारण नहीं देते। Tentatively -1 यह क्योंकि यह मुझे लगता है कि वास्तव में विपरीत सच है और यह एक हैक है; क्या आप विशेष रूप से के लिए डिज़ाइन किए git mergeगए चीजों में से एक को करने के लिए मजबूर करने के लिए आवश्यक से अधिक कमांड का प्रदर्शन नहीं कर रहे हैं git rebase?
मार्क एमी जूल

76
@ मर्क अमेरी: विभिन्न कारणों से मैंने कहा कि यह अधिक सुरुचिपूर्ण है। उदाहरण के लिए, यह अनावश्यक रूप से एक संपादक को पैदा नहीं करता है और फिर "टू-डू" फ़ाइल में स्ट्रिंग के लिए खोज और प्रतिस्थापित करता है। का उपयोग करते हुए git merge --squashभी एक स्क्रिप्ट में उपयोग करने के लिए आसान है। मूलतः, तर्क यह था कि आपको इसके लिए "अन्तरक्रियाशीलता" की आवश्यकता नहीं है git rebase -i
मार्क लोंगेयर

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

2
जब मैं हार्ड रीसेट की बात करता हूं तो मैं बहुत अनिच्छुक होता हूं - मैं HEAD@{1}केवल सुरक्षित पक्ष पर होने के बजाय एक अस्थायी टैग का उपयोग करता हूं जैसे कि जब आपके वर्कफ़्लो को एक पावर आउटेज आदि द्वारा एक घंटे के लिए बाधित किया जाता है
टोबीस किंजलर

8
@BT: अपनी प्रतिबद्धता को नष्ट कर दिया? :( मुझे यकीन नहीं है कि आपका क्या मतलब है। आपके द्वारा किए गए कुछ भी आप आसानी से गिट के रिफ्लॉग से वापस पाने में सक्षम होंगे। यदि आपके पास काम नहीं था, लेकिन फ़ाइलों का मंचन किया गया था, तो आपको अभी भी प्राप्त करने में सक्षम होना चाहिए। उनकी सामग्री वापस, हालांकि यह अधिक काम होगा । यदि आपका काम भी नहीं किया गया था, हालांकि, मुझे डर है कि थोड़ा कम किया जा सकता है; इसीलिए जवाब ऊपर-सामने कहता है: "पहले जाँच लें कि गिट की स्थिति साफ है (चूँकि गिट रीसेट
मार्क लोंगेयर

218

मैं git resetजब संभव हो तब परहेज करने की सलाह देता हूं - विशेष रूप से गिट-नौसिखियों के लिए। जब तक आपको वास्तव में कमिट की संख्या के आधार पर एक प्रक्रिया को स्वचालित करने की आवश्यकता नहीं है, तब तक कम विदेशी तरीका है ...

  1. एक काम कर रहे शाखा पर (अगर वे पहले से ही नहीं हैं) पर टू-स्क्वॉड कमिट्स डालें - इसके लिए गिटक का उपयोग करें
  2. लक्ष्य शाखा देखें (उदाहरण के लिए 'मास्टर')
  3. git merge --squash (working branch name)
  4. git commit

स्क्वैश के आधार पर प्रतिबद्ध संदेश को पूर्व निर्धारित किया जाएगा।


4
यह सबसे सुरक्षित तरीका है: कोई रीसेट सॉफ्ट / हार्ड (!!), या इस्तेमाल किया हुआ रिफ्लोग!
14

14
यदि आप (1) पर विस्तार करते हैं तो यह बहुत अच्छा होगा।
एडम

2
@ अदम: मूल रूप से, इसका मतलब है gitkकि आप जिस स्क्वैशिंग को कोड कर रहे हैं उसे लेबल करने के लिए GUI इंटरफ़ेस का उपयोग करें और जिस आधार पर स्क्वैश करना है उस पर भी लेबल लगाएँ। सामान्य स्थिति में, ये दोनों लेबल पहले से मौजूद होंगे, इसलिए चरण (1) को छोड़ दिया जा सकता है।
नोबार

3
ध्यान दें कि यह विधि पूरी तरह से विलय होने के रूप में कार्य शाखा को चिह्नित नहीं करती है, इसलिए इसे हटाने के लिए जबरन हटाने की आवश्यकता होती है। :(
किर्स्टेलाइन

2
(1) के लिए, मुझे git branch your-feature && git reset --hard HEAD~Nसबसे सुविधाजनक तरीका मिल गया है। हालाँकि, इसमें फिर से git रीसेट शामिल है, जिसे इस उत्तर ने टालने की कोशिश की।
eis

132

क्रिस जॉन्सन के जवाब के आधार पर ,

बैश से एक वैश्विक "स्क्वैश" उपनाम जोड़ें: (या विंडोज पर गेट बैश)

git config --global alias.squash '!f(){ git reset --soft HEAD~${1} && git commit --edit -m"$(git log --format=%B --reverse HEAD..HEAD@{1})"; };f'

... या विंडोज कमांड कमांड प्रॉम्प्ट का उपयोग कर:

git config --global alias.squash "!f(){ git reset --soft HEAD~${1} && git commit --edit -m\"$(git log --format=%B --reverse HEAD..HEAD@{1})\"; };f"


~/.gitconfigअब आपके पास यह उपनाम होना चाहिए:

[alias]
    squash = "!f(){ git reset --soft HEAD~${1} && git commit --edit -m\"$(git log --format=%B --reverse HEAD..HEAD@{1})\"; };f"


उपयोग:

git squash N

... जो स्वचालित रूप से पिछले Nकमिट्स को सम्मिलित करता है, समावेशी है।

नोट: परिणामी प्रतिबद्ध संदेश क्रम में सभी स्क्वैस्ड कमिट्स का संयोजन है। यदि आप इससे नाखुश हैं, तो आप git commit --amendइसे मैन्युअल रूप से संशोधित कर सकते हैं । (या, अपने स्वाद से मेल खाने के लिए उपनाम संपादित करें।)


6
दिलचस्प है, लेकिन मैं बहुत अधिक प्रतिबद्ध संदेश टाइप करूंगा, क्योंकि यह मेरे लिए कई बार ऑटो-एंटर किया गया था। इसलिए मैं नहीं बल्कि निर्दिष्ट git squash -m "New summary."और Nस्वचालित रूप से निर्धारित किया है के रूप में अप्रकाशित की संख्या।
एक्यूमेनस

1
@ABB, यह एक अलग प्रश्न की तरह लगता है। (मुझे नहीं लगता कि यह बिल्कुल वही है जो ओपी पूछ रहा था; मैंने अपने गिट स्क्वैश वर्कफ़्लो में कभी इसकी आवश्यकता महसूस नहीं की है।)
एथनबी

3
यह बहुत मीठा है। व्यक्तिगत रूप से मैं एक ऐसा संस्करण चाहूंगा जो पहले स्क्वैश-एक से प्रतिबद्ध संदेश का उपयोग करता है। व्हाट्सएप ट्विक्स जैसी चीजों के लिए अच्छा रहेगा।
बजे

@ फर्राटेदार सहमत। बस आखिरी कमेंट मेस को ड्रॉप करना मेरे लिए एक सुपर कॉमन जरूरत है। हमें उसको समर्पित करने में सक्षम होना चाहिए ...
स्टीव क्ले

2
@ABB आप git commit --amendसंदेश को और बदलने के लिए उपयोग कर सकते हैं , लेकिन यह उपनाम आपको प्रतिबद्ध संदेश में क्या होना चाहिए, इसकी एक अच्छी शुरुआत है।
15 अप्रैल को रात

131

इस आसान ब्लॉग पोस्ट की बदौलत मैंने पाया कि आप इस कमांड का उपयोग अंतिम 3 कमिट्स को स्क्वैश करने के लिए कर सकते हैं:

git rebase -i HEAD~3

यह आसान है क्योंकि यह तब भी काम करता है जब आप किसी ट्रैकिंग जानकारी / रिमोट रेपो के साथ स्थानीय शाखा में हों।

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


इंटरएक्टिव रिबेस संपादक का उपयोग करना:

इंटरएक्टिव रिबेस संपादक आखिरी तीन कमिट दिखाता है। यह बाधा HEAD~3कमान चलाते समय निर्धारित की गई थी git rebase -i HEAD~3

सबसे हालिया प्रतिबद्ध, HEADपहली पंक्ति 1 पर प्रदर्शित होता है। यह लाइनें एक #टिप्पणी / प्रलेखन के साथ शुरू होती हैं।

प्रदर्शित प्रलेखन बहुत स्पष्ट है। किसी भी लाइन पर आप pickकमांड को अपनी पसंद के कमांड से बदल सकते हैं ।

मैं कमांड का उपयोग करना पसंद करता हूं fixup इस "स्क्वाश" के रूप ऊपर की लाइन पर कमिट में बदलाव करता है और कमिट का मैसेज छोड़ देता है।

जैसा कि लाइन 1 पर प्रतिबद्ध है HEAD, ज्यादातर मामलों में आप इसे छोड़ देंगेpick । आप का उपयोग नहीं कर सकते हैं squashया के fixupरूप में प्रतिबद्ध स्क्वैश करने के लिए कोई अन्य प्रतिबद्ध नहीं है।

आप आवागमन के क्रम को भी बदल सकते हैं। यह आपको स्क्वैश या फ़िक्सअप करने की अनुमति देता है जो आसन्न कालानुक्रमिक नहीं हैं।

इंटरैक्टिव विद्रोही संपादक


एक व्यावहारिक हर रोज का उदाहरण

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

पहली चीज जो मैं करता हूं वह गलती को ठीक करना है और टिप्पणी के साथ एक नई प्रतिबद्धता बनाना है squash this into my new feature!

मैं तब (या इस मामले में ) नई सुविधा का प्रतिबद्ध SHA चलाता हूं git logया gitkप्राप्त करता हूं 1ff9460

अगला, मैं इंटरएक्टिव रिबेस संपादक को साथ लाता हूं git rebase -i 1ff9460~~प्रतिबद्ध के बाद SHA संपादक बताता है शामिल करने के लिए है कि संपादक में करते हैं।

इसके बाद, मैं fe7f1e0फीचर कमिट के नीचे फिक्स ( ) युक्त कमेट को स्थानांतरित करता हूं , और इसमें बदलाव pickकरता हूं fixup

संपादक को बंद करते समय, फिक्स्ड फीचर कमिट में स्क्वैश हो जाएगा और मेरी कमिट हिस्ट्री अच्छी और साफ दिखेगी!

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

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


5
क्या आपको शीर्ष एक चुनना है और बाकी को स्क्वैश करना है? आपको अपने उत्तर को यह बताने के लिए संपादित करना चाहिए कि इंटरएक्टिव रिबेस संपादक का अधिक विस्तार से उपयोग कैसे करें
कोलोब कैनियन

2
हां, pickलाइन 1 में छोड़ दें । यदि आप लाइन 1 पर कमिट करते हैं squashया चुनते हैं fixup, तो git एक मैसेज दिखाएगा, जिसमें कहा जा सकता है कि "त्रुटि: पिछले कमिट के बिना 'फिक्स' नहीं कर सकता है"। फिर यह आपको इसे ठीक करने का विकल्प देगा: "आप इसे 'git rebase --edit-todo' से ठीक कर सकते हैं और फिर 'git rebase --continue' चला सकते हैं।" या आप सिर्फ गर्भपात कर सकते हैं और शुरू कर सकते हैं: "या आप रिबेट को 'गिट रिबेस - वेबोर्ट' के साथ गर्भपात करा सकते हैं।"
br3nt

56

यदि आप TortoiseGit का उपयोग करते हैं, तो आप कार्य कर सकते हैं Combine to one commit:

  1. TortoiseGit संदर्भ मेनू खोलें
  2. चुनते हैं Show Log
  3. लॉग दृश्य में प्रासंगिक कमिट्स को चिह्नित करें
  4. Combine to one commitसंदर्भ मेनू से चयन करें

मिलाते हैं

यह फ़ंक्शन स्वचालित रूप से सभी आवश्यक एकल गिट चरणों को निष्पादित करता है। Unfortunatly केवल Windows के लिए उपलब्ध है।


जहां तक ​​मुझे जानकारी है, यह मर्ज कमिट के लिए काम नहीं करेगा।
थोरिल होल्म-जैकबसेन

1
हालाँकि यह किसी अन्य द्वारा टिप्पणी नहीं की गई है, लेकिन यह उन कामों के लिए भी काम करता है जो HEAD में नहीं हैं। उदाहरण के लिए, मेरी जरूरत कुछ WIP स्क्वैश करने की थी, जिसे मैंने आगे बढ़ाने से पहले एक अधिक समझदार वर्णन के साथ किया। खूबसूरती से काम किया। बेशक, मुझे अभी भी उम्मीद है कि मैं यह सीख सकता हूं कि यह कैसे करना है।
चार्ल्स रॉबर्टो कैनाटो

55

ऐसा करने के लिए आप निम्नलिखित git कमांड का उपयोग कर सकते हैं।

 git rebase -i HEAD~n

n (= 4 यहाँ) अंतिम प्रतिबद्ध की संख्या है। फिर आपको निम्नलिखित विकल्प मिले,

pick 01d1124 Message....
pick 6340aaa Message....
pick ebfd367 Message....
pick 30e0ccb Message....

सबसे नीचे हाल में pickएक कमिट और squashअन्य की तरह अपडेट करें ,

p 01d1124 Message....
s 6340aaa Message....
s ebfd367 Message....
s 30e0ccb Message....

विवरण के लिए लिंक पर क्लिक करें


48

इस लेख के आधार पर मैंने इस विधि को अपने usecase के लिए आसान पाया।

मेरी My देव ’शाखा 96 कमिट द्वारा / उत्पत्ति / देव’ से आगे थी (इसलिए इन कमिटों को अभी तक रिमोट से नहीं धकेला गया था)।

मैं बदलाव को आगे बढ़ाने से पहले इन कमिट्स को एक साथ जोड़ना चाहता था। मैं 'मूल / देव' की स्थिति के लिए शाखा को रीसेट करने का पूर्वाभास करता हूं (यह 96 हिट से सभी परिवर्तन छोड़ देगा) और फिर एक ही बार में परिवर्तन करने के लिए प्रतिबद्ध हैं:

git reset origin/dev
git add --all
git commit -m 'my commit message'

1
मुझे जिस चीज की जरूरत थी। स्क्वैश नीचे मेरी सुविधा शाखा से शुरू होता है, और फिर मैं चेरी उठाता हूं जो मेरे स्वामी में प्रतिबद्ध है।
डेविड विक्टर

1
यह स्क्वैश पिछले नहीं करता है!
इगोरगानापोलस्की

क्या आप थोड़ा और आगे बता सकते हैं कि
ट्रूडोल्फ

3
@ ट्रुडोल्फ यह वास्तव में स्क्वैश नहीं है (व्यक्तिगत स्क्वैश को उठाते हुए)। यह एक बार में आपके सभी परिवर्तनों को करने के लिए अधिक है।
इगोरगानपोलस्की

15
हाँ, इसलिए यह आपके सभी आवागमन को एक में बदल देता है। बधाई हो!
ट्रूडोल्फ

45

जिस शाखा में आप कमिट्स को जोड़ना चाहते हैं, उसे चलाएं:

git rebase -i HEAD~(n number of commits back to review)

उदाहरण:

git rebase -i HEAD~1

यह टेक्स्ट एडिटर को खोलेगा और आपको प्रत्येक स्क्वैश के साथ 'पिक' को 'स्क्वैश' के साथ स्विच करना होगा अगर आप चाहेंगे कि ये कमिट्स एक साथ मर्ज हो जाएं। प्रलेखन से:

पी, उठाओ = उपयोग कमिट

s, स्क्वैश = कमिट का उपयोग करें, लेकिन पिछले प्रतिबद्ध में पिघला

उदाहरण के लिए, यदि आप सभी कमिट्स को एक में मिलाना चाहते हैं, तो 'पिक' आपके द्वारा की गई पहली प्रतिबद्धता है और भविष्य के सभी (पहले से नीचे रखे गए) को 'स्क्वैश' में सेट किया जाना चाहिए। यदि विम का उपयोग कर रहे हैं, तो उपयोग करें : x तो संपादक को बचाने और बाहर निकलने के लिए इन्सर्ट मोड में ।

फिर रिबास जारी रखने के लिए:

git rebase --continue

इस पर और अपने प्रतिबद्ध इतिहास को फिर से लिखने के अन्य तरीकों के लिए इस उपयोगी पोस्ट को देखें


2
कृपया यह भी बताएं कि --continueविम और विम :xक्या करता है।
दोपहर 2 बजे

रिबास ब्लॉकों में होगा क्योंकि यह आपकी शाखा पर कमिट्स के माध्यम से जाता है, git addआपके द्वारा अपनी फ़ाइलों में सही कॉन्फ़िगरेशन के बाद आप git rebase --continueअगले कमिट पर जाने और मर्ज करने के लिए उपयोग करते हैं। :xएक आदेश उस फ़ाइल के परिवर्तन जब vim को देखने का उपयोग कर की बचत होगी है इस
aabiro

32

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

चरण ०: लॉग लॉग

देखें कि आप कहां हैं git log। सबसे महत्वपूर्ण है, पहली स् वश की हैश को खोजें जिसे आप स्क्वैश नहीं करना चाहते हैं। तो केवल:

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

चरण 1: गिट रीबेस

git rebase -i [your hash]मेरे मामले में निष्पादित करें :

$ git rebase -i 2d23ea524936e612fae1ac63c95b705db44d937d

चरण 2: आप क्या चाहते हैं / उठाएं

मेरे मामले में, मैं उस समय जो कुछ पहली बार हुआ था, उस पर सब कुछ छीनना चाहता हूं। आदेश पहली से आखिरी तक है, ठीक उसी तरह जैसे दूसरे तरीके से git log। मेरे मामले में, मुझे चाहिए:

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

चरण 3: संदेश समायोजित करें

यदि आपने केवल एक कमिट किया है और बाकी को स्क्वैश किया है, तो आप एक कमिट मैसेज एडजस्ट कर सकते हैं:

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

बस। एक बार जब आप इसे बचा :wqलेते हैं ( ), तो आप कर रहे हैं। इसके साथ एक नज़र रखना git log


2
अंतिम परिणाम देखकर अच्छा लगेगा, जैसे,git log
टिमोथी एलजे स्टीवर्ट

2
जी नहीं, धन्यवाद। यह ठीक इसी तरह है जब मैं अपना काम करता हूं।
एक्सालिक्स

@Axalix क्या आपने अपनी सभी लाइनों को हटा दिया? इस तरह आप अपने कमिट खो देते हैं।
a3y3

31

प्रक्रिया १

1) कम शॉर्ट हैश की पहचान करें

# git log --pretty=oneline --abbrev-commit
abcd1234 Update to Fix for issue B
cdababcd Fix issue B
deab3412 Fix issue A
....

यहां तक ​​कि git log --oneline शॉर्ट हैश पाने के लिए भी इस्तेमाल किया जा सकता है।

2) यदि आप अंतिम दो प्रतिबद्ध करना चाहते हैं (मर्ज)

# git rebase -i deab3412 

3) यह nanoविलय के लिए एक संपादक को खोलता है । और यह नीचे की तरह दिखता है

....
pick cdababcd Fix issue B
pick abcd1234 Update to Fix for issue B
....

4) उस शब्द pickका नाम बदलें squashजो पहले मौजूद है abcd1234। नाम बदलने के बाद यह नीचे की तरह होना चाहिए।

....
pick cdababcd Fix issue B
squash abcd1234 Update to Fix for issue B
....

5) अब nanoएडिटर को सेव और बंद करें । बचाने के लिए दबाएं ctrl + oऔर दबाएं Enter। और फिर दबाएँctrl + x संपादक से बाहर निकलने के लिए ।

6) तब nano संपादक अपडेट के लिए फिर से खुलता है, यदि आवश्यक हो तो इसे अपडेट करें।

7) अब इसका स्क्वैश सफलतापूर्वक हो गया है, आप लॉग की जाँच करके इसे सत्यापित कर सकते हैं।

# git log --pretty=oneline --abbrev-commit
1122abcd Fix issue B
deab3412 Fix issue A
....

8) अब रेपो पर पुश करें। +शाखा के नाम से पहले हस्ताक्षर जोड़ने के लिए ध्यान दें । इसका मतलब है जबरदस्ती धक्का देना।

# git push origin +master

नोट: यह ubuntuशेल पर गिट का उपयोग करने पर आधारित है । यदि आप अलग-अलग ओएस ( Windowsया Mac) का उपयोग कर रहे हैं तो ऊपर के कमांड संपादक के अलावा समान हैं। आपको अलग-अलग संपादक मिल सकते हैं।

प्रक्रिया २

  1. पहले प्रतिबद्ध के लिए आवश्यक फाइलें जोड़ें
git add <files>
  1. फिर --fixupविकल्प का उपयोग करने के लिए प्रतिबद्ध OLDCOMMITहोना चाहिए और उस पर होना चाहिए जिस पर हमें इस कमिट को मर्ज (स्क्वैश) करना है।
git commit --fixup=OLDCOMMIT

अब यह HEAD के शीर्ष पर एक नई प्रतिबद्धता बनाता है fixup1 <OLDCOMMIT_MSG>

  1. उसके बाद नए कमिट टू मर्ज (स्क्वैश) को निष्पादित करें OLDCOMMIT
git rebase --interactive --autosquash OLDCOMMIT^

यहाँ ^पिछले करने का मतलब है OLDCOMMIT। यह rebaseकमांड एक संपादक (विम या नैनो) पर इंटरैक्टिव विंडो खोलता है, जिस पर हमें कुछ भी करने की आवश्यकता नहीं है बस बचाने और बाहर निकलने के लिए पर्याप्त है। क्योंकि इसमें दिया गया विकल्प स्वचालित रूप से नवीनतम प्रतिबद्ध को पुरानी प्रतिबद्ध के बगल में ले जाएगा और ऑपरेशन fixupको स्क्वैश के बराबर में बदल देगा । फिर रिबास जारी है और खत्म।

प्रक्रिया ३

  1. यदि अंतिम प्रतिबद्ध साधनों के --amendसाथ नए बदलाव जोड़ने की आवश्यकता है, तो इसका उपयोग किया जा सकता है git-commit
    # git log --pretty=oneline --abbrev-commit
    cdababcd Fix issue B
    deab3412 Fix issue A
    ....
    # git add <files> # New changes
    # git commit --amend
    # git log --pretty=oneline --abbrev-commit
    1d4ab2e1 Fix issue B
    deab3412 Fix issue A
    ....  

यहां --amendअंतिम बदलावों के लिए नए बदलावों का विलय किया गया है cdababcdऔर नई प्रतिबद्ध आईडी बनाई गई है1d4ab2e1

निष्कर्ष

  • 1 प्रक्रिया का लाभ कई कमिट्स को स्क्वैश करना और रीऑर्डर करना है। लेकिन यह प्रक्रिया कठिन होगी अगर हमें बहुत पुरानी प्रतिबद्धताओं के लिए एक विलय करने की आवश्यकता है।
  • तो दूसरी प्रक्रिया बहुत पुरानी प्रतिबद्धताओं को आसानी से मर्ज करने में मदद करती है।
  • और तीसरी प्रक्रिया एक मामले में उपयोगी है जो अंतिम प्रतिबद्ध के लिए एक नए बदलाव को स्क्वैश करने के लिए उपयोगी है।

यह केवल अंतिम दो अपडेट को अद्यतन करता है, यहां तक ​​कि मैं एक कमिट आईडी से 6 वीं अंतिम प्रतिबद्ध पर रीसेट करता हूं, पता नहीं क्यों
कार्लोस लियू

यहां तक ​​कि आप प्रतिबद्ध आदेश को पुनर्व्यवस्थित कर सकते हैं। यह बढ़िया काम करता है।
राशोक

29

अंतिम 10 स्क्वैश को 1 सिंगल कमिट में करना है:

git reset --soft HEAD~10 && git commit -m "squashed commit"

यदि आप भी स्क्वैश कमिट के साथ रिमोट ब्रांच को अपडेट करना चाहते हैं:

git push -f

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

27

यदि आप एक सुदूर शाखा (जिसे feature-branchगोल्डन रिपॉजिटरी) कहा जाता है ) से क्लोन किया गया है golden_repo_name, तो यहाँ आपके द्वारा एक में स्क्वैश करने की तकनीक है:

  1. गोल्डन रेपो की जाँच करें

    git checkout golden_repo_name
    
  2. निम्नानुसार से एक नई शाखा (गोल्डन रेपो) बनाएँ

    git checkout -b dev-branch
    
  3. स्क्वैश आपके स्थानीय शाखा के साथ विलय कर देता है जो आपके पास पहले से है

    git merge --squash feature-branch
    
  4. अपने परिवर्तन करें (यह एकमात्र ऐसी प्रतिबद्धता होगी जो देव-शाखा में जाती है)

    git commit -m "My feature complete"
    
  5. अपने स्थानीय भंडार में शाखा को पुश करें

    git push origin dev-branch
    

चूंकि मैं सिर्फ स्क्वैशिंग कर रहा था ~ 100 कमिट्स (git-svn के माध्यम से svn शाखाओं को सिंक करने के लिए), यह अंतःक्रियात्मक रीबेसिंग की तुलना में बहुत तेज़ है!
ऋषि

1
नीचे पढ़ते हुए, मैं @ क्रिस की टिप्पणी देखता हूं, जो कि मैं करता था (रिबास - सोफ्ट ...) - बहुत बुरा है कि स्टैकओवरफ़्लो अब उत्तर को सैकड़ों अपवोट के साथ शीर्ष पर नहीं डाल रहा है ...
ऋषि

1
आपसे सहमत हैं @sage, आशा करते हैं कि वे भविष्य में कभी-कभी ऐसा कर सकते हैं
संध्या कुमार

यह सही तरीका है। रिबेस का दृष्टिकोण अच्छा है, लेकिन इसे केवल अंतिम उपाय के रूप में स्क्वैश के लिए इस्तेमाल किया जाना चाहिए।
एक्सालिक्स

20

क्या वास्तव में सुविधाजनक हो सकता है:
आप के शीर्ष पर स्क्वैश करना चाहते हैं, कहते हैं खोजें d43e15

अब उपयोग करें

git reset d43e15
git commit -am 'new commit name'

2
इस। अधिक लोग इसका उपयोग क्यों नहीं करते हैं? यह अलग-अलग तरीके से रिबासिंग और स्क्वैश करने से अलग है।
a3y3

17

यह सुपर-डुपर कुल्डी है, लेकिन एक तरह से शांत तरीके से, इसलिए मैं इसे रिंग में टॉस करूंगा:

GIT_EDITOR='f() { if [ "$(basename $1)" = "git-rebase-todo" ]; then sed -i "2,\$s/pick/squash/" $1; else vim $1; fi }; f' git rebase -i foo~5 foo

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

मैं शायद वही करूँगा जो मार्क लोंगेयर ने सुझाया था , हालाँकि।


7
+1: यह मजेदार और शिक्षाप्रद है, इसमें मेरे लिए यह बिल्कुल भी स्पष्ट नहीं है कि आप GIT_EDITOR पर्यावरण चर में एक कार्यक्रम के नाम से अधिक जटिल कुछ भी डाल सकते हैं।
मार्क लॉन्गेयर

16

यदि आप हर कमिट को एक ही कमिट में स्क्वीज़ करना चाहते हैं (जैसे पहली बार सार्वजनिक रूप से किसी प्रोजेक्ट को जारी करते समय), तो कोशिश करें:

git checkout --orphan <new-branch>
git commit

14

मुझे लगता है कि ऐसा करने का सबसे आसान तरीका यह है कि नई शाखा को मास्टर से दूर कर दिया जाए और सुविधा शाखा का मर्ज - स्क्वैश किया जाए।

git checkout master
git checkout -b feature_branch_squashed
git merge --squash feature_branch

फिर आपके पास सभी बदलाव करने के लिए तैयार हैं।


14

2020 रिबास के बिना सरल समाधान:

git reset --soft HEAD~2

git commit -m "new commit message"

git push --force

2 का मतलब है कि पिछले दो कमिट्स को स्क्वैश किया जाएगा। आप इसे किसी भी नंबर से बदल सकते हैं


12

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

git reset --soft $(git merge-base HEAD master) && git commit --reuse-message=HEAD@{1}

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

12

यदि उदाहरण के लिए आप अंतिम 3 को एक शाखा में एक कमिट के लिए भेजना चाहते हैं (दूरस्थ रिपॉजिटरी) उदाहरण के लिए: https://bitbucket.org

मैंने जो किया है

  1. git reset --soft हेड ~ 3 &&
  2. कमिट
  3. git पुश ओरिजिन (शाखा_नाम) --फोर्स

3
बस सावधान रहें, क्योंकि यदि आप बल का उपयोग करते हैं तो आपके द्वारा हटाए जाने के बाद से पिछले कमिट्स को पुनः प्राप्त करने का कोई तरीका नहीं है
अल्बर्ट रूएलन

12

⚠️ चेतावनी: "मेरा आखिरी एक्स कमिट" अस्पष्ट हो सकता है।

  (MASTER)  
Fleetwood Mac            Fritz
      ║                    ║
  Add Danny  Lindsey     Stevie       
    Kirwan  Buckingham    Nicks                                              
      ║         ╚═══╦══════╝     
Add Christine       ║          
   Perfect      Buckingham
      ║           Nicks            
    LA1974══════════╝                                    
      ║                  
      ║                  
    Bill <══════ YOU ARE EDITING HERE
  Clinton        (CHECKED OUT, CURRENT WORKING DIRECTORY)              

Https://github.com/fleetwood-mac/band-history रिपॉजिटरी के इस बहुत संक्षिप्त इतिहास में आपने बिल क्लिंटन को मूल ( MASTER) फ्लीटवुड मैक कमिट में विलय करने के लिए एक पुल अनुरोध खोला है ।

आपने पुल अनुरोध खोला और GitHub पर आप इसे देखते हैं:

चार काम:

  • डैनी किरण को जोड़ें
  • क्रिस्टीन परफेक्ट जोड़ें
  • LA1974
  • बील क्लिंटन

यह सोचकर कि कोई भी कभी भी पूर्ण भंडार इतिहास पढ़ने की परवाह नहीं करेगा। (वास्तव में एक भंडार है, ऊपर दिए गए लिंक पर क्लिक करें!) आप इन कमानों को स्क्वैश करने का निर्णय लेते हैं। इसलिए तुम जाओ और दौड़ो git reset --soft HEAD~4 && git commit। तो फिर आप git push --forceअपने पीआर को साफ करने के लिए GitHub पर जाएं।

और क्या होता है? आपने अभी-अभी सिंगल कमिट किया है जो फ्रिट्ज से बिल क्लिंटन तक मिलता है। क्योंकि आप भूल गए थे कि कल आप इस परियोजना के बकिंघम निक संस्करण पर काम कर रहे थे। और git logजो आप GitHub पर देखते हैं उससे मेल नहीं खाता।

कहानी का OF मॉरल

  1. आप प्राप्त करना चाहते हैं सटीक फ़ाइलें खोजें करने के लिए , और git checkoutउन्हें
  2. सटीक पूर्व-निर्धारित करें कि आप इतिहास में क्या रखना चाहते हैं, और git reset --softवह
  3. एक बनाने git commitसे सीधे कि warps से करने के लिए

1
यह 100% ऐसा करने का सबसे आसान तरीका है। यदि आपका वर्तमान HEAD वह सही स्थिति है जिसे आप चाहते हैं, तो आप # 1 को छोड़ सकते हैं।
स्टेन

यह एकमात्र तरीका है जो मुझे पता है कि पहले प्रतिबद्ध इतिहास को फिर से लिखने की अनुमति देता है।
वडकोरक्वेस्ट

9

यदि आप इन-कमिट्स के बीच के प्रतिबद्ध संदेशों की परवाह नहीं करते हैं, तो आप उपयोग कर सकते हैं

git reset --mixed <commit-hash-into-which-you-want-to-squash>
git commit -a --amend

7

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

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


6
git rebase -i HEAD^^

जहाँ ^ की संख्या X है

(इस मामले में, दो अंतिम कमिट्स स्क्वैश)


6

अन्य उत्कृष्ट उत्तरों के अलावा, मैं यह जोड़ना चाहूंगा कि कैसे git rebase -iहमेशा मुझे प्रतिबद्ध आदेश के साथ भ्रमित करता है - नए से पुराना या इसके विपरीत? तो यह मेरा वर्कफ़्लो है:

  1. git rebase -i HEAD~[N], जहां एन सबसे हाल ही में एक से शुरू होने वाले कमिट की संख्या है, जिसमें मैं शामिल होना चाहता हूं । तो git rebase -i HEAD~5इसका मतलब होगा "अंतिम 5 स्क्वैश एक नए में शुरू होता है";
  2. संपादक पॉप अप करता है, मैं मर्ज करना चाहते हैं की सूची दिखाते हुए। अब उन्हें रिवर्स ऑर्डर में प्रदर्शित किया जाता है : पुरानी प्रतिबद्धता शीर्ष पर है। "स्क्वैश" या "एस" के रूप में चिह्नित करें , पहले / पुराने एक को छोड़कर वहां सभी कमिट करता है : इसे शुरुआती बिंदु के रूप में उपयोग किया जाएगा। संपादक को सहेजें और बंद करें;
  3. संपादक नई प्रतिबद्ध के लिए एक डिफ़ॉल्ट संदेश के साथ फिर से पॉप अप करता है: इसे अपनी आवश्यकताओं में बदलें, सहेजें और बंद करें। स्क्वैश पूरा!

स्रोत और अतिरिक्त रीड: # 1 , # 2


6

इस तरह एक वर्कफ़्लो से संबंधित प्रश्न के उत्तर के बारे में क्या?

  1. कई स्थानीय कमिट, मास्टर से कई मर्ज के साथ मिश्रित , ,
  2. अंत में रिमोट के लिए एक धक्का,
  3. पीआर और समीक्षक द्वारा मास्टर में विलय । (हां, merge --squashपीआर के बाद डेवलपर के लिए यह आसान होगा , लेकिन टीम ने सोचा कि इससे प्रक्रिया धीमी हो जाएगी।)

मैंने इस पृष्ठ पर उस तरह का वर्कफ़्लो नहीं देखा है। (यह मेरी आंखें हो सकती हैं।) अगर मैं rebaseसही ढंग से समझूं, तो कई मर्जों के लिए कई संघर्ष संकल्पों की आवश्यकता होगी । मैं उस बारे में सोचना भी नहीं चाहता!

तो, यह हमारे लिए काम करने लगता है।

  1. git pull master
  2. git checkout -b new-branch
  3. git checkout -b new-branch-temp
  4. संपादित करें और स्थानीय रूप से बहुत कुछ करें, नियमित रूप से मास्टर मर्ज करें
  5. git checkout new-branch
  6. git merge --squash new-branch-temp // सभी परिवर्तनों को चरण में रखता है
  7. git commit 'one message to rule them all'
  8. git push
  9. समीक्षक पीआर करता है और मास्टर में विलय करता है।

कई राय से मैं आपके दृष्टिकोण को पसंद करता हूं। यह बहुत सुविधाजनक और तेज़ है
आर्टेम सोलोवव

5

मुझे लगता है कि 'एन' कमिट को निर्दिष्ट करने के लिए एक अधिक सामान्य समाधान नहीं है, बल्कि उस शाखा / कमिट-आईडी के बारे में जिसे आप शीर्ष पर रखना चाहते हैं। यह एक विशिष्ट कमिट तक कमियों को गिनने की तुलना में कम त्रुटि वाला है - सीधे टैग को निर्दिष्ट करें, या यदि आप वास्तव में गिनना चाहते हैं तो आप HEAD ~ N निर्दिष्ट कर सकते हैं।

मेरे वर्कफ़्लो में, मैं एक शाखा शुरू करता हूं, और उस शाखा पर मेरी पहली प्रतिबद्धता लक्ष्य को सारांशित करती है (यानी यह आमतौर पर है कि मैं सार्वजनिक रिपॉजिटरी को सुविधा के लिए 'अंतिम' संदेश के रूप में धक्का दूंगा।) तो जब मैं पूरा हो जाता हूं। मैं करना चाहता हूं git squash master पहले संदेश पर वापस जाना चाहता हूं और फिर धक्का देने के लिए तैयार हूं।

मैं उपनाम का उपयोग करता हूं:

squash = !EDITOR="\"_() { sed -n 's/^pick //p' \"\\$1\"; sed -i .tmp '2,\\$s/^pick/f/' \"\\$1\"; }; _\"" git rebase -i

ऐसा करने से पहले इतिहास को दरकिनार कर दिया जाएगा - इससे आपको एक पुरानी प्रतिबद्ध आईडी को कंसोल से हथियाने का मौका मिलता है, अगर आप वापस करना चाहते हैं। (सोलारिस उपयोगकर्ता ध्यान दें कि यह GNU sed -iविकल्प का उपयोग करता है , मैक और लिनक्स उपयोगकर्ता इसके साथ ठीक होना चाहिए।)


मैंने उपनाम की कोशिश की, लेकिन मुझे यकीन नहीं है कि अगर सीड्स की जगह पर कोई असर पड़ रहा है। उन्हें क्या करना चाहिए?
Raine

पहला सेड सिर्फ इतिहास को सांत्वना देता है। दूसरी सीड सभी 'पिक' को 'एफ' (फिक्सअप) से बदल देती है और एडिटर फाइल को इन-प्लेस (इन-ऑप्शन) को फिर से लिखती है। तो दूसरा सब काम करता है।
एथन

आप सही हैं, विशिष्ट संख्‍याओं की एन-संख्‍या गिनना बहुत त्रुटि प्रवण है। इसने मुझे कई बार डांटा है और घंटों तक बर्बाद करके रिबास को पूर्ववत करने की कोशिश की है।
इगोरगानपोलस्की

हाय एथन, मैं जानना चाहूंगा कि क्या यह वर्कफ़्लो मर्ज पर संभावित टकराव को छिपाएगा। तो कृपया विचार करें कि क्या आपके पास दो शाखाएं हैं, स्वामी और दास। यदि दास का स्वामी के साथ टकराव होता है और git squash masterजब हम गुलाम की जाँच करते हैं तो हम उसका उपयोग करते हैं। क्या होगा? क्या हम संघर्ष को छिपाएंगे?
सर्जियो बिलेलो

@Sergio यह इतिहास के पुनर्लेखन का एक मामला है, इसलिए आपको संभवतः संघर्ष होगा यदि आप स्क्वैश करते हैं जो पहले से ही धकेल दिया गया है, और फिर स्क्वैश संस्करण को वापस मर्ज करने / फिर से जोड़ने का प्रयास करें। (कुछ तुच्छ मामले इसके साथ दूर हो सकते हैं।)
एथन

5

प्रश्न में यह अस्पष्ट हो सकता है कि "अंतिम" से क्या अभिप्राय है।

उदाहरण के git log --graphलिए निम्नलिखित (सरलीकृत) आउटपुट:

* commit H0
|
* merge
|\
| * commit B0
| |
| * commit B1
| | 
* | commit H1
| |
* | commit H2
|/
|

फिर समय से अंतिम हिट H0, मर्ज, B0 हैं। उन्हें स्क्वैश करने के लिए आपको प्रतिबद्ध एच 1 पर अपनी मर्ज की गई शाखा को रिबेट करना होगा।

समस्या यह है कि H0 में H1 और H2 शामिल हैं (और आम तौर पर मर्ज करने से पहले और बाद में ब्रांच करने के बाद) अधिक होता है जबकि B0 नहीं। इसलिए आपको कम से कम H0, मर्ज, H1, H2, B0 से बदलाव का प्रबंधन करना होगा।

पुन: उपयोग करना संभव है, लेकिन अलग-अलग तरीकों से फिर दूसरों के उत्तर में उल्लेख किया गया है:

rebase -i HEAD~2

यह आपको विकल्प विकल्प दिखाएगा (जैसा कि अन्य उत्तरों में बताया गया है):

pick B1
pick B0
pick H0

H0 लेने के बजाय स्क्वैश लगाएं:

pick B1
pick B0
s H0

सहेजें और बाहर निकलने के बाद रिबास एच 1 के बाद बदले में कमिट लागू करेगा। इसका मतलब है कि यह आपको फिर से संघर्षों को हल करने के लिए कहेगा (जहां HEAD पहली बार H1 होगा और फिर लागू होते ही जमा हो जाएगा)।

रिबेस करने के बाद आप स्क्वैस्ड H0 और B0 के लिए संदेश चुन सकते हैं:

* commit squashed H0 and B0
|
* commit B1
| 
* commit H1
|
* commit H2
|

PS यदि आप केवल BO के लिए कुछ रीसेट करते हैं: (उदाहरण के लिए, इसका उपयोग करके reset --mixedयहां और अधिक विस्तार से बताया गया है https://stackoverflow.com/a/18690845/2405850 ):

git reset --mixed hash_of_commit_B0
git add .
git commit -m 'some commit message'

तब आप H0, H1, H2 के B0 परिवर्तनों में स्क्वैश करते हैं (ब्रांचिंग के बाद और विलय से पहले परिवर्तनों के लिए पूरी तरह से कम हो जाते हैं।


4

1) git रीसेट --soft HEAD ~ n

n - कमिट की संख्या, स्क्वैश की जरूरत

2) git कमिट -m "नया कमिट मैसेज"

3) git पुश ओरिजिन ब्रांच_नाम --फोर्स

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