Git: शाखा में सभी स्क्वैश कैसे करें


315

मैं इसके साथ नई शाखा बनाता हूं master:

git checkout -b testbranch

मैं इसमें 20 कमिट करता हूं।

अब मैं उन 20 कमिट्स को स्क्वैश करना चाहता हूं। मैं इसके साथ करता हूं:

git rebase -i HEAD~20

अगर मैं नहीं जानता कि कितने के बारे में क्या है? क्या कुछ करने का कोई तरीका है:

git rebase -i all on this branch

6
आप कर सकते हैं git rebase -i 58333012713fc168bd70ad00d191b3bdc601fa2dजो एक इंटरेक्टिव रिबेस करेगा जहां कमिटमेंट आखिरी प्रतिबद्ध है जो अपरिवर्तित
denns

पिछले के साथ इस पद्धति का उपयोग करना @denns शाखा आप रिबेसिंग कर रहे हैं में प्रतिबद्ध से शानदार काम किया। बहुत बहुत धन्यवाद!
जोशुआ पिंटर

जवाबों:


392

अपने सभी कमिट्स को स्क्वाश करने का एक और तरीका है, इंडेक्स को मास्टर में रीसेट करना:

 git checkout yourBranch
 git reset $(git merge-base master yourBranch)
 git add -A
 git commit -m "one commit on yourBranch"

यह सही नहीं है क्योंकि इसका तात्पर्य है कि आपको पता है कि "yourBranch" किस शाखा से आ रही है।
नोट: मूल शाखा Git के साथ आसान / संभव नहीं है ( दृश्य तरीका अक्सर सबसे आसान है , जैसा कि यहां देखा गया है )।


EDIT: आपको उपयोग करने की आवश्यकता होगी git push --force


Karlotcha Hoa टिप्पणियों में जोड़ता है :

रीसेट के लिए, आप कर सकते हैं

git reset $(git merge-base master $(git rev-parse --abbrev-ref HEAD)) 

[वह] स्वचालित रूप से उस शाखा का उपयोग करता है जो आप वर्तमान में हैं।
और यदि आप इसका उपयोग करते हैं, तो आप उपनाम का उपयोग भी कर सकते हैं, क्योंकि कमांड शाखा के नाम पर निर्भर नहीं है


2
YourBranchवर्तमान में जहां है, वहां जांच करने के लिए बेहतर है। YourBranchजब आप ऐसा करेंगे तो यह बरकरार रहेगाreset
यूजेन कोनकोव

1
@ अब्दुर्रहीम या एक गिट बैश खोलें, और यो अपने आदेशों को कॉपी-पेस्ट कर सकते हैं!
वॉन

3
रीसेट के लिए, आप git reset $(git merge-base master $(git rev-parse --abbrev-ref HEAD))उस शाखा का उपयोग स्वतः करने के लिए कर सकते हैं जिस पर आप वर्तमान में हैं। और यदि आप इसका उपयोग करते हैं, तो आप उपनाम का उपयोग भी कर सकते हैं, क्योंकि कमांड शाखा के नाम पर निर्भर नहीं है।
कार्लोटचा होआ

1
@ द्रासका उपमा शाखाओं के मामलों के लिए, नहीं, यह ठीक काम करना चाहिए।
वॉन सीपीसी

1
@ शम्मी हाँ, बशर्ते आप रीसेट के बाद धक्का दे git push --forceदें : (और अपने सहकर्मियों को चेतावनी दें कि यदि आप उस शाखा में काम करने वाले कई लोग हैं)
VONC

112

उस शाखा को चेकआउट करें जिसके लिए आप सभी कमिट्स को एक कमिट में स्क्वैश करना चाहेंगे। चलो कहते हैं इसकी feature_branch,।

git checkout feature_branch

चरण 1:

origin/feature_branchअपनी स्थानीय masterशाखा के साथ अपना एक नरम रीसेट करें (अपनी आवश्यकताओं के आधार पर, आप मूल / मास्टर के साथ भी रीसेट कर सकते हैं)। यह आपके सभी अतिरिक्त कमेंट्स को रीसेट कर देगा feature_branch, लेकिन आपकी किसी भी फ़ाइल को स्थानीय रूप से बदले बिना।

git reset --soft master

चरण 2:

अपनी git रेपो डायरेक्टरी में सभी बदलावों को जोड़ें, जो नई कमेटी बनाने जा रही है। और एक संदेश के साथ एक ही प्रतिबद्ध है।

git add -A && git commit -m "commit message goes here"


6
यह मेरे लिए सबसे विश्वसनीय समाधान था - किसी भी रिबेस की त्रुटियों का कारण नहीं और न ही संघर्ष का विलय।
ANTARA

1
चेतावनी: git ऐड-ए जोड़ें जो आपके पास स्थानीय फ़ोल्डर में है - शाखा में।
डेविड एच

इस समाधान को प्यार करो! जैसा मुझे चाहिए था यह बिल्कुल वैसा ही है!
१०:४० पर जैकोब्लेंनवुड

1
एक noob के लिए सबसे अच्छा समाधान - गैर विनाशकारी और केवल उफ़ पल बहुत अधिक हो सकता है जैसे कि ऐप रहस्य आदि, जो कि आपके पास उचित gitignore फ़ाइल होने पर कोई फर्क नहीं पड़ता
kkarakk

@NSduToit संक्षिप्त उत्तर: नहीं, आपके पास नहीं है। मेरे उत्तर में उपर्युक्त चरणों को करने के बाद, आप कुछ कोड परिवर्तनों के साथ एक प्रतिबद्ध के साथ समाप्त हो जाएंगे। आप इसे कुछ कोड परिवर्तनों के साथ किसी अन्य प्रतिबद्ध की तरह ही सोच सकते हैं। आप -fध्वज के बिना अपनी दूरस्थ शाखा को धक्का दे सकते हैं ।
झाँकी

110

आप जो कर रहे हैं वह बहुत त्रुटीपूर्ण है। बस करो:

git rebase -i master

जो वर्तमान नवीनतम मास्टर पर केवल आपकी शाखा के कमिट्स को स्वचालित रूप से वापस कर देगा।


5
धन्यवाद, मुझे वह मिल गया, लेकिन मेरे सिस्टम में त्रुटि क्यों है
user3803850

10
शायद इसलिए क्योंकि नंबर गलत होना आसान है?
डैनियल स्कॉट

13
इससे सहमत ही आपका सबसे अच्छा समाधान है। लेकिन इस लिंक का अनुसरण करें क्योंकि यह बेहतर बताता है कि आपको क्या करने की आवश्यकता है।
क्रिस्टो

3
स्क्वैश करने के बजाय, आप ब्रांच को मर्ज करने के लिए मर्ज कर सकते हैं और सभी कमिट्स को अनस्टैज करने के लिए उत्पत्ति / मास्टर को रीसेट रीसेट कर सकते हैं। इससे आपको अपना मौजूदा अस्थिर कोडcommit -am "the whole thing!"
nurettin

2
@nurettin मुझे लगता है कि reset origin/masterविधि वास्तव में बहुत खराब है क्योंकि यह सीधे मास्टर पर कमिट करने के समान है - इसमें 'मर्ज ब्रांच' इतिहास नहीं है, कोई पुल अनुरोध विकल्प नहीं है। @WaZaA द्वारा इसका उत्तर सामान्य git वर्कफ़्लो को ध्यान में रखते हुए बहुत अधिक है
Drenai

79

ऐसा करने का एक और सरल तरीका है: मूल शाखा पर जाएं और ए करें merge --squash। यह कमांड "स्क्वैश" कमिट नहीं करता है। जब आप इसे करते हैं, तो आपके ब्रांच के सभी प्रतिबद्ध संदेश एकत्र हो जाएंगे।

$ git checkout master
$ git merge --squash yourBranch
$ git commit # all commit messages of yourBranch in one, really useful
 > [status 5007e77] Squashed commit of the following: ...

1
सच। मैंने मर्ज में अंतर - स्क्वैश और रिबास-आई के बीच अंतर का उल्लेख किया stackoverflow.com/a/2427520/6309
VonC

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

चियर्स दोस्त, महान टिप!
नेस्टर मिलियाव

अच्छा! मैं एक "अस्थायी" शाखा "मास्टर" बनाने के लिए पहले स्क्वैश "yourBranch" में, फिर "टेम्प" को "मास्टर" में मर्ज करें।
लेज़ीबर्ड

34

यह मानते हुए कि आप गुरु से शाखित हैं, आपको yourBranchहर समय रीसेट चरण में प्रवेश करने की आवश्यकता नहीं है :

git checkout yourBranch
git reset --soft HEAD~$(git rev-list --count HEAD ^master)
git add -A
git commit -m "one commit on yourBranch"

स्पष्टीकरण :

  • git rev-list --count HEAD ^masterचूंकि आपने अपनी सुविधा शाखा को मास्टर, f.ex. 20।
  • git reset --soft HEAD~20पिछले 20 कमिट्स का सॉफ्ट रिसेट करेगा। यह फ़ाइलों में आपके परिवर्तन को छोड़ देता है, लेकिन कमिट को हटा देता है।

उपयोग :

मेरे .bash_profile में मैंने gisquashएक कमांड के साथ ऐसा करने के लिए एक उपनाम जोड़ा है :

# squash all commits into one
alias gisquash='git reset --soft HEAD~$(git rev-list --count HEAD ^master)'

रीसेट करने और कमिट करने के बाद आपको ए git push --force

संकेत :

यदि आप Gitlab> = 11.0 का उपयोग कर रहे हैं, तो आपको ऐसा करने की आवश्यकता नहीं है क्योंकि शाखाओं को मर्ज करते समय इसमें स्क्वैशिंग विकल्प होता है। Gitlab स्क्वाशिंग विकल्प


15

स्क्वॉवरफ़्लोइंग के कई सवालों और जवाबों को स्क्वैश पर पढ़ने के आधार पर, मुझे लगता है कि यह एक अच्छा लाइनर है जो सभी ब्रांच पर स्क्वैश करता है:

git reset --soft $(git merge-base master YOUR_BRANCH) && git commit -am "YOUR COMMIT MESSAGE" && git rebase -i master

यह माना जाता है कि मास्टर आधार शाखा है।


1
बहुत बहुत धन्यवाद, कंपनी के पास बहुत सारे प्रतिबंध हैं और एक संपादक के साथ सामान्य तरीके से फिर से नहीं कर सकते क्योंकि बचाने के लिए जोर से नहीं था। इसके अलावा स्क्वैश का उपयोग नहीं कर सकते हैं और इस सुविधा को मर्ज करने की सुविधा नहीं है क्योंकि यह शाखा विलय के लिए लीड देव के पास जाती है और उन्हें यह पसंद नहीं है। इस 1 लाइनर ने काम किया और सिरदर्द से बचाया। शानदार कार्य।
L1ghtk3ira

10

उन लोगों के लिए समाधान जो क्लिक करना पसंद करते हैं:

  1. Sourcetree स्थापित करें (यह मुफ़्त है)

  2. जांचें कि आपके कमिट कैसे दिखते हैं। सबसे अधिक संभावना है कि आपके पास इसके समान कुछ है यहां छवि विवरण दर्ज करें

  3. पैरेंट कमेंट पर राइट क्लिक करें । हमारे मामले में यह मास्टर ब्रांच है।

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

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

  2. परिणाम बहुत बढ़िया हैं और हम धक्का देने के लिए तैयार हैं! यहां छवि विवरण दर्ज करें

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


इसके लिए धन्यवाद!
क्रिस्टल

0

एक अन्य समाधान सभी प्रतिबद्ध लॉग को एक फ़ाइल में सहेजना होगा

git लॉग> शाखा.लॉग

अब Branch.log में शुरू से ही सभी प्रतिबद्ध आईडी होंगे। नीचे स्क्रॉल करें और पहली प्रतिबद्ध का उपयोग करके पहला कमिट लें (यह टर्मिनल में मुश्किल होगा)

git रीसेट --soft

सभी कमियों को तोड़ दिया जाएगा


0

Git रीसेट, जैसा कि पहले कई उत्तरों में बताया गया है, जो आप चाहते हैं उसे प्राप्त करने का सबसे अच्छा और सरल तरीका है। मैं निम्नलिखित वर्कफ़्लो में इसका उपयोग करता हूं:

(विकास शाखा पर)

git fetch
git merge origin/master  #so development branch has all current changes from master
git reset origin/master  #will show all changes from development branch to master as unstaged
git gui # do a final review, stage all changes you really want
git commit # all changes in a single commit
git branch -f master #update local master branch
git push origin master #push it

0

यह सब git रीसेट, हार्ड, सॉफ्ट, और यहां बताई गई हर चीज शायद काम कर रही है (यह मेरे लिए नहीं है) यदि आप सही तरीके से कदम उठाते हैं और किसी प्रकार का जिन्न करते हैं।
यदि आप औसत जो smo हैं, तो यह प्रयास करें:
git मर्ज --squash का उपयोग कैसे करें?


मेरे जीवन को बचाया, और मेरे स्क्वैश में जाएंगे, इस बारे में 4 बार उपयोग कर रहे हैं क्योंकि मुझे इसके बारे में पता चला है। सरल, स्वच्छ और मूल रूप से 1 कॉमनंड। संक्षेप में:


यदि आप शाखा पर हैं, तो इसे "my_new_feature" कहकर विकसित करें और आपके पुल अनुरोध में 35 कमिट (या फिर बहुत से) हैं और आप चाहते हैं कि यह 1. हो

। सुनिश्चित करें कि आपकी शाखा अद्यतित है, पर जाएं। विकास, नवीनतम और विलय करें और "my_new_feature" के साथ किसी भी संघर्ष को हल
करें (यह कदम वास्तव में आपको जितनी जल्दी हो सके सभी समय पर लेना चाहिए)

B. एक शाखा में विकसित और शाखा से नवीनतम प्राप्त करें इसे "my_new_feature_squashed" कहें

सी। मैजिक यहां है।
आप अपने काम को "my_new_feature" से "my_new_feature_squashed" तक ले जाना चाहते हैं,
तो बस करें (जबकि आपकी नई शाखा हमने विकसित की है):
git merge --squash mynew_feature

आपके सभी परिवर्तन अब आपकी नई शाखा पर होंगे, इसका परीक्षण करने के लिए स्वतंत्र महसूस करें, फिर बस अपनी 1 एकल प्रतिबद्ध, धक्का, उस शाखा के नए पीआर - और अगले दिन दोहराने के लिए प्रतीक्षा करें।
क्या आपको कोडिंग पसंद नहीं है? :)


0

आप इस कार्य के लिए विशेष रूप से बनाए गए टूल का उपयोग कर सकते हैं:

https://github.com/sheerun/git-squash

मूल रूप से आपको कॉल करने की आवश्यकता है git squash master और आप कर रहे हैं

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