git - गिट कमेट्स/स्क्वैशिंग गिट हिस्ट्री ट्रिमिंग




branch (3)

मैं अपने कोड को हर कुछ मिनटों में गिट शाखा में चेक करता हूं, और टिप्पणियां "सबकुछ फिर से टूटा हुआ" और अन्य बेतुकापन जैसी चीजें होती हैं।

फिर हर कुछ मिनट / घंटे / दिन मैं एक असली टिप्पणी के साथ एक गंभीर प्रतिबद्धता करता हूं, जैसे "फिक्स्ड बग # 22.55, तीसरी बार।" मैं इन दो अवधारणाओं को कैसे अलग कर सकता हूं? मैं अपने सभी लगातार काम करने में सक्षम होना चाहता हूं और केवल गंभीर लोगों को छोड़ दूंगा।


अपने साथियों को एक साथ लेने और स्क्वैश करने के लिए गिट रीबेस-i का उपयोग करें।


इसके बजाय स्क्वैश का उपयोग करना

हाल ही में, मैं एक और शाखा में काम कर रहा हूं और squash का उपयोग कर रहा हूं। दूसरी शाखा को अस्थायी कहा जाता है, और फिर मैं git merge temp --squash का उपयोग वास्तविक शाखा में लाने के लिए करता git merge temp --squash जो सर्वर पर धक्का देता है।

वर्कफ़्लो ऐसा कुछ है, मानते हुए कि मैं Ticket65252 में काम कर रहा हूं:

git branch -d temp #remove old temp bbranch
git checkout -b temp
# work work work, committing all the way
git checkout Ticket65252
git merge temp --squash
git commit -m "Some message here"

rebase का उपयोग करने पर लाभ ? रास्ता कम जटिल है।

reset --soft का उपयोग reset --hard पर लाभ और फिर reset --soft ? कम भ्रमित और थोड़ा कम त्रुटि प्रवण।


अब के साथ संपादित उत्तर (इस प्रविष्टि के दूसरे भाग में) नया गिट 1.7 फिक्सअप! त्वरित प्रतिबद्धता और संदेश संपादन के लिए कार्रवाई और --autosquash विकल्प।

सबसे पहले, क्लासिक स्क्वैशिंग प्रक्रिया, जैसा कि गिट 1.7 से पहले किया गया था।
(गिट 1.7 में एक ही प्रक्रिया है, मैन्युअल रीडरिंग के विपरीत स्वचालित क्लीनर रीडरिंग की संभावना से और केवल क्लीनर स्क्वैशिंग संदेशों द्वारा)

मैं अपने सभी लगातार चेक-इन को हटाने में सक्षम होना चाहता हूं और केवल गंभीर लोगों को छोड़ना चाहता हूं।

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

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

alt text http://www.gitready.com/images/squash1.png

अगर वे एक साथ लपेट गए तो आखिरी 4 काम बहुत खुश होंगे

$ git rebase -i HEAD~4

pick 01d1124 Adding license
pick 6340aaa Moving license into its own file
pick ebfd367 Jekyll has become self-aware.
pick 30e0ccb Changed the tagline in the binary, too.

# Rebase 60709da..30e0ccb onto 60709da
#
# Commands:
#  p, pick = use commit
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#

पिछले चार कामों का उपयोग करके पुन: उपयोग करें जहां से HEAD HEAD~4
हम सब कुछ एक प्रतिबद्धता में स्क्वैश करने जा रहे हैं।
तो, फ़ाइल की पहली चार पंक्तियों को बदलने से यह चाल चल जाएगी:

pick 01d1124 Adding license
squash 6340aaa Moving license into its own file
squash ebfd367 Jekyll has become self-aware.
squash 30e0ccb Changed the tagline in the binary, too.

असल में यह गिट को सूची में पहली प्रतिबद्धता में सभी चार प्रतिबद्धताओं को गठबंधन करने के लिए कहता है। एक बार यह किया और सहेजा गया, एक और संपादक निम्नलिखित के साथ पॉप अप:

# This is a combination of 4 commits.
# The first commit's message is:
Adding license

# This is the 2nd commit message:

Moving license into its own file

# This is the 3rd commit message:

Jekyll has become self-aware.

# This is the 4th commit message:

Changed the tagline in the binary, too.

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# Explicit paths specified without -i nor -o; assuming --only paths...
# Not currently on any branch.
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   new file:   LICENSE
#   modified:   README.textile
#   modified:   Rakefile
#   modified:   bin/jekyll
#

चूंकि हम इतने सारे कामकाज का संयोजन कर रहे हैं, गिट आपको प्रक्रिया में शामिल शेष कार्यों के आधार पर नए प्रतिबद्धता संदेश को संशोधित करने की अनुमति देता है। जैसा कि आप फिट देखते हैं, संदेश को संपादित करें, फिर सहेजें और छोड़ दें।
एक बार ऐसा करने के बाद, आपके काम सफलतापूर्वक squashed किया गया है!

Created commit 0fc4eea: Creating license file, and making jekyll self-aware.
 4 files changed, 27 insertions(+), 30 deletions(-)
  create mode 100644 LICENSE
    Successfully rebased and updated refs/heads/master.

और अगर हम फिर से इतिहास को देखते हैं ...

alt text http://www.gitready.com/images/squash2.png

नोट: "प्रतिबद्ध Git1.7 " उद्देश्यों के लिए, Git1.7 (फरवरी 2010) ने 2 नए तत्व प्रस्तुत किए हैं (जैसा टिप्पणी में Dustin द्वारा उल्लिखित है):

  • " git rebase -i " ने नई कार्रवाई " fixup " सीखा जो परिवर्तन को स्क्वैश करता है लेकिन मौजूदा लॉग संदेश को प्रभावित नहीं करता है।
  • " git rebase -i --autosquash " ने भी --autosquash विकल्प सीखा जो कि " --autosquash " एक्शन के साथ उपयोगी है।

दोनों ( --autosquash एक्शन और --autosquash विकल्प) इस Thechnosorcery नेटवर्क ब्लॉग प्रविष्टि में चित्रित हैं। ये सुविधाएं पिछले जून 200 9 से खाना पकाने जा रही हैं और पिछले दिसंबर में बहस हुई थीं।

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

  # s, squash = use commit, but meld into previous commit
  # f, fixup = like "squash", but discard this commit's log message

--autosquash विकल्प आपके लिए स्वचालित रूप से प्रतिबद्धता प्रक्रिया को बनाने के बारे में है:

यदि आप जानते हैं कि आप किस चीज को स्क्वैश करना चाहते हैं तो आप इसे " squash! $other_commit_subject " के संदेश के साथ प्रतिबद्ध कर सकते हैं squash! $other_commit_subject squash! $other_commit_subject "। फिर यदि आप @git rebase --interactive --autosquash [email protected] , तो लाइन स्वचालित रूप से स्क्वैश के रूप में सेट की जाएगी, और $ other_commit_subject के विषय के साथ प्रतिबद्धता के नीचे रखी जाएगी।

(असल में, squash! केवल एक और प्रतिबद्ध संदेश की शुरुआत का उपयोग कर सकते हैं)

$ vim Foo.txt
$ git commit -am "Change all the 'Bar's to 'Foo's"
[topic 8374d8e] Change all the 'Bar's to 'Foo's
 1 files changed, 2 insertions(+), 2 deletions(-)
$ vim Bar.txt
$ git commit -am "Change all the 'Foo's to 'Bar's"
[topic 2d12ce8] Change all the 'Foo's to 'Bar's
 1 files changed, 1 insertions(+), 1 deletions(-)

$ vim Foo.txt
$ git commit -am "squash! Change all the 'Bar's"
[topic 259a7e6] squash! Change all the 'Bar's
 1 files changed, 2 insertions(+), 1 deletions(-)

देख? यहां तीसरा प्रतिबद्ध केवल पहले प्रतिबद्ध संदेश की शुरुआत का उपयोग करता है।
एक rebase --interactive --autosquash प्रासंगिक नीचे नीचे squashed प्रतिबद्ध स्थानांतरित करेगा:

pick 8374d8e Change all the 'Bar's to 'Foo's
squash 259a7e6 squash! Change all the 'Bar's
pick 2d12ce8 Change all the 'Foo's to 'Bar's

संदेश संस्करण होगा:

# This is a combination of 2 commits.
# The first commit's message is:

Change all the 'Bar's to 'Foo's

# This is the 2nd commit message:

squash! Change all the 'Bar's

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

pick 8374d8e Change all the 'Bar's to 'Foo's
fixup cfc6e54 fixup! Change all the 'Bar's
pick 2d12ce8 Change all the 'Foo's to 'Bar's

डिफ़ॉल्ट रूप से संदेश होगा:

# This is a combination of 2 commits.
# The first commit's message is:

Change all the 'Bar's to 'Foo's

# The 2nd commit message will be skipped:

#    fixup! Change all the 'Bar's

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

अब अगर आप पिछली प्रतिबद्धता के आधार पर फिक्सअप या स्क्वैश करना चाहते हैं तो आपने अभी किया है, जैकब हेल्विग (टेक्नोसॉररी नेटवर्क ब्लॉग एंट्री के लेखक) निम्नलिखित उपनामों की सिफारिश करते हैं:

[alias]
    fixup = !sh -c 'git commit -m \"fixup! $(git log -1 --format='\\''%s'\\'' [email protected])\"' -
    squash = !sh -c 'git commit -m \"squash! $(git log -1 --format='\\''%s'\\'' [email protected])\"' -

और एक रिबेज इंटरैक्टिव करने के लिए जो हमेशा स्क्वैश किए जाने वाले कार्यों के स्वचालित पुनर्वितरण से लाभान्वित होगा:

[alias]
    ri = rebase --interactive --autosquash

गिट 2.18 (क्यू 2 2018) के लिए अपडेट: " git rebase -i " कभी-कभी इंटरमीडिएट छोड़ दिया जाता है " # This is a combination of N commits " संदेश को अंतिम परिणाम में एक संपादक के अंदर मानव उपभोग के लिए कुछ कोने मामलों में तय किया गया है, जिसे ठीक किया गया है ।

प्रतिबद्ध 15f693 देखें, dc4b5bc प्रतिबद्ध करें , e12a7ef प्रतिबद्ध करें , जोहान्स dscho ( dscho ) द्वारा d5bc6f2 (27 अप्रैल 2018) प्रतिबद्ध करें
( gitster सी gitster द्वारा विलय - gitster - प्रतिबद्ध 4a3bf32 , 23 मई 2018)

rebase --skip : असफल फिक्सअप / स्क्वैश के बाद प्रतिबद्ध संदेश साफ़ करें

फिक्सअप / स्क्वैश कमांड की एक श्रृंखला के दौरान, इंटरैक्टिव रीबेस टिप्पणियों के साथ एक प्रतिबद्ध संदेश बनाता है। यह उपयोगकर्ता को संपादक में प्रस्तुत किया जाएगा यदि उनमें से कम से कम एक आदेश squash था।

किसी भी मामले में, इस तरह के फिक्सअप / स्क्वैश श्रृंखला के अंतिम चरण में, उन सभी मध्यवर्ती टिप्पणियों को हटाकर, प्रतिबद्ध संदेश को अंततः साफ कर दिया जाएगा।

हालांकि, यदि ऐसी श्रृंखला में अंतिम फ़िक्सअप / स्क्वैश कमांड विलय विवादों के साथ विफल रहता है, और यदि उपयोगकर्ता इसे छोड़ने का निर्णय लेता है (या इसे क्लीन वर्क्री पर हल करता है और फिर रीबेस जारी रखता है), तो वर्तमान कोड साफ़ करने में विफल रहता है संदेश भेजें

यह प्रतिबद्धता उस व्यवहार को हल करती है।

फिक्स आंखों की तुलना में काफी अधिक शामिल है क्योंकि यह केवल सवाल के बारे में नहीं है कि हम git rebase --skip हैं - एक git rebase --skip या स्क्वैश में git rebase --skip । यह संचित प्रतिबद्ध संदेश से छोड़े गए फिक्सअप / स्क्वैश के प्रतिबद्ध संदेश को हटाने के बारे में भी है। और यह सवाल के बारे में भी है कि क्या हमें उपयोगकर्ता को अंतिम प्रतिबद्ध संदेश संपादित करने देना चाहिए या नहीं ("क्या उस श्रृंखला में कोई स्क्वैश था जिसे छोड़ा नहीं गया था ?")।

उदाहरण के लिए, इस मामले में हम प्रतिबद्ध संदेश को ठीक करना चाहते हैं, लेकिन इसे एक संपादक में नहीं खोलें:

pick  <- succeeds
fixup   <- succeeds
squash  <- fails, will be skipped

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

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





branch