`Git मर्ज` और` git मर्ज --no-ff` में क्या अंतर है?


976

का उपयोग करते हुए gitk log, मैं दोनों के बीच अंतर नहीं कर सका। मैं अंतर कैसे देख सकता हूं (git कमांड या कुछ टूल के साथ)?




जवाबों:


1079

--no-ffझंडा रोकता है git mergeएक "तेजी से आगे" को क्रियान्वित करता है, तो उसे पता चलता है कि अपने वर्तमान से HEADप्रतिबद्ध आप मर्ज करने के लिए कोशिश कर रहे हैं के एक पूर्वज है। एक फास्ट-फ़ॉरवर्ड तब होता है, जब मर्ज कमिट का निर्माण करने के बजाय, git आपकी ब्रांच पॉइंटर को आने वाली कमिट पर इंगित करने के लिए ले जाता है। यह आमतौर पर तब होता है जब git pullबिना किसी स्थानीय बदलाव के किया जाता है।

हालाँकि, कभी-कभी आप इस व्यवहार को होने से रोकना चाहते हैं, आमतौर पर क्योंकि आप एक विशिष्ट शाखा टोपोलॉजी को बनाए रखना चाहते हैं (जैसे आप विषय शाखा में विलय कर रहे हैं और आप यह सुनिश्चित करना चाहते हैं कि इतिहास पढ़ते समय यह उसी तरह दिखे)। ऐसा करने के लिए, आप --no-ffध्वज को पास कर सकते हैं और हमेशा फास्ट-फ़ॉरवर्डिंग के बजाय मर्ज का निर्माण git mergeकरेंगे ।

इसी तरह, यदि आप स्पष्ट रूप से तेजी से अग्रेषित करने के लिए git pullया उपयोग git mergeकरना चाहते हैं, और आप जमानत करना चाहते हैं यदि यह तेजी से आगे नहीं बढ़ सकता है, तो आप --ff-onlyध्वज का उपयोग कर सकते हैं । इस तरह से आप नियमित रूप से git pull --ff-onlyबिना सोचे समझे कुछ कर सकते हैं , और फिर अगर यह गलतियाँ करता है तो आप वापस जा सकते हैं और तय कर सकते हैं कि आप विलय करना चाहते हैं या रिबेट करना चाहते हैं।


87
ओपी के सवाल का अधिक सीधे जवाब देने के लिए: वे हमेशा अलग नहीं होते हैं, लेकिन यदि वे हैं, तो यह स्पष्ट है gitk या git log --graphकि फास्ट-फॉरवर्ड मर्ज ने मर्ज कमिट नहीं बनाया है, जबकि गैर-फास्ट-फॉरवर्ड ने एक किया था।
Cascabel

11
एफएफ से बचने के कारण पर विस्तार करना अच्छा होगा: लेखक ने "विशिष्ट शाखा टोपोलॉजी" का उल्लेख किया है कि - इन-एफएफ मामले में अतिरिक्त मर्ज कमेटी मर्ज के मार्कर के रूप में कार्य करता है। पेशेवरों को लेखक और विलय के नामों के साथ स्पष्ट मर्ज मार्कर है। विपक्ष गैर-रेखीय इतिहास है जो रेलिंग पटरियों को परिवर्तित करने के एक सेट की तरह दिखता है। मर्ज का एक संभावित मनोवैज्ञानिक साइड इफेक्ट हालांकि योगदानकर्ताओं की लंबी समीक्षा प्रक्रिया के कारण ब्याज में कमी है: blog.spreedly.com/2014/06/24/…
व्लाद

6
क्या यह कहना उचित होगा कि --no-ffमास्टर को विकसित करने या विकसित करने के लिए एक सुविधा से एक पुल अनुरोध को मर्ज करने के समान है?
मर्लिनपैट

9
@merlinpatt ज़रूर यदि आप GitHub में पुल अनुरोध को मर्ज करते हैं तो यह उसके बराबर होता है --no-ff
लिली बॉलार्ड

1
यह एक अच्छी व्याख्या है। यार, लोगों को यह समझने के लिए कि वहाँ वास्तव में महत्वपूर्ण इतिहास क्यों है, वास्तव में महत्वपूर्ण है (मुझे शामिल!)
dudewad

1037

इस सवाल का ग्राफिक जवाब

यहाँ एक स्पष्ट व्याख्या और उपयोग के चित्रमय चित्रण के साथ एक साइट हैgit merge --no-ff :

git मर्ज में अंतर --no-ff और git मर्ज

जब तक मैंने यह नहीं देखा, मैं पूरी तरह से गिट के साथ खो गया था। का उपयोग करते हुए--no-ff करने से इतिहास की समीक्षा करने वाले किसी व्यक्ति को उस शाखा को स्पष्ट रूप से देखने की अनुमति मिलती है जिस पर आपने काम करने के लिए जाँच की थी। (यह लिंक गितुब के "नेटवर्क" विज़ुअलाइज़ेशन टूल की ओर इशारा करता है) और यहाँ चित्रण के साथ एक और बढ़िया संदर्भ है । यह संदर्भ पहले एक अच्छी तरह से git से कम परिचित लोगों पर अधिक ध्यान देने के साथ पूरक है।


मेरे जैसे नए लोगों के लिए बुनियादी जानकारी

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


उदाहरण वर्कफ़्लो

मैंने अपनी वेबसाइट पर एक पैकेज अपडेट किया और अपने वर्कफ़्लो को देखने के लिए मुझे अपने नोट्स पर वापस जाना पड़ा; मैंने इस उत्तर में एक उदाहरण जोड़ना उपयोगी समझा।

Git कमांड के मेरे वर्कफ़्लो:

git checkout -b contact-form
(do your work on "contact-form")
git status
git commit -am  "updated form in contact module"
git checkout master
git merge --no-ff contact-form
git branch -d contact-form
git push origin master

नीचे: स्पष्टीकरण सहित वास्तविक उपयोग।
ध्यान दें: नीचे का उत्पादन छीन लिया गया है; गिट काफी क्रिया है।

$ git status
# On branch master
# Changed but not updated:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   ecc/Desktop.php
#       modified:   ecc/Mobile.php
#       deleted:    ecc/ecc-config.php
#       modified:   ecc/readme.txt
#       modified:   ecc/test.php
#       deleted:    passthru-adapter.igs
#       deleted:    shop/mickey/index.php
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       ecc/upgrade.php
#       ecc/webgility-config.php
#       ecc/webgility-config.php.bak
#       ecc/webgility-magento.php

ऊपर से 3 चीजें नोटिस करें:
1) आउटपुट में आप ईसीसी पैकेज के अपग्रेड से नई फाइलों को शामिल करने सहित बदलाव देख सकते हैं।
2) यह भी देखें कि दो फाइलें हैं ( /eccफ़ोल्डर में नहीं ) मैंने इस परिवर्तन से स्वतंत्र हटा दिया। इसके बजाय उन फ़ाइल को हटाने के साथ भ्रमित करने के लिएecc , मैं cleanupबाद में उन फ़ाइलों को हटाने को प्रतिबिंबित करने के लिए एक अलग शाखा बनाऊंगा।
3) मैंने अपने वर्कफ़्लो का पालन नहीं किया! मैं git के बारे में भूल गया, जबकि मैं ecc को फिर से काम करने की कोशिश कर रहा था।

नीचे: git commit -am "updated ecc package"सामान्य रूप से सर्व-समावेशी करने के बजाय , मैं केवल /eccफ़ोल्डर में फ़ाइलों को जोड़ना चाहता था । वे हटाई गई फ़ाइलें मेरे लिए विशेष रूप से हिस्सा नहीं थीं git add, लेकिन क्योंकि वे पहले से ही गिट में ट्रैक किए गए थे, इसलिए मुझे उन्हें इस शाखा की प्रतिबद्धताओं से हटाने की आवश्यकता है:

$ git checkout -b ecc
$ git add ecc/*
$ git reset HEAD passthru-adapter.igs
$ git reset HEAD shop/mickey/index.php
Unstaged changes after reset:
M       passthru-adapter.igs
M       shop/mickey/index.php

$ git commit -m "Webgility ecc desktop connector files; integrates with Quickbooks"

$ git checkout master
D       passthru-adapter.igs
D       shop/mickey/index.php
Switched to branch 'master'
$ git merge --no-ff ecc
$ git branch -d ecc
Deleted branch ecc (was 98269a2).
$ git push origin master
Counting objects: 22, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (14/14), done.
Writing objects: 100% (14/14), 59.00 KiB, done.
Total 14 (delta 10), reused 0 (delta 0)
To git@github.com:me/mywebsite.git
   8a0d9ec..333eff5  master -> master



उपरोक्त को स्वचालित करने के लिए स्क्रिप्ट

एक दिन में 10+ बार इस प्रक्रिया का उपयोग करने के बाद, मैंने कमांड्स को निष्पादित करने के लिए बैच स्क्रिप्ट लिखने के लिए लिया है, इसलिए मैंने git_update.sh <branch> <"commit message">उपरोक्त चरणों को करने के लिए लगभग-उचित स्क्रिप्ट बनाई । यहाँ उस लिपि के लिए जिस्ट स्रोत है

इसके बजाय git commit -amमैं "संशोधित" सूची के माध्यम से उत्पादित फ़ाइलों का चयन कर रहा हूं git statusऔर फिर इस स्क्रिप्ट में उन लोगों को चिपका रहा हूं । इस बारे में आया क्योंकि मैंने दर्जनों संपादन किए लेकिन बदलावों में मदद करने के लिए विभिन्न शाखा नाम चाहते थे।


11
क्या आप --no-ffविकल्प के साथ मर्ज करने के बाद भी सुरक्षित रूप से एक शाखा को हटा सकते हैं ?
एंडी फ्लेमिंग

17
@DesignerGuy हाँ आप सुरक्षित रूप से पुरानी शाखा को हटा सकते हैं। शाखा के बारे में सोचें कि एक विशिष्ट प्रतिबद्धता के लिए सिर्फ संकेत के रूप में।
Zyphrax

2
मुझे यह पाठ लिंक किए गए पृष्ठ से मददगार लगा: बिना -no-ff के "Git के इतिहास से यह देखना असंभव है कि किन वस्तुओं ने मिलकर एक विशेषता को लागू किया है - आपको मैन्युअल रूप से सभी लॉग संदेशों को पढ़ना होगा।"
लोर्ने लालबेटे सेप

एक छवि हमेशा एक हजार शब्दों से सबसे अच्छी होती है!
बर्बाद

1
ग्राफिक दूसरी छवि में सुविधाओं की शाखा नहीं दिखाता है, क्यों नहीं? यह अभी भी मौजूद है न?
ADJenks

269

मर्ज रणनीतियाँ

स्पष्ट मर्ज : एक नया मर्ज प्रतिबद्ध बनाता है। (यदि आप उपयोग करते हैं तो यह आपको मिलेगा --no-ff।)

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

फास्ट फॉरवर्ड मर्ज: नई प्रतिबद्धता बनाए बिना, तेजी से आगे बढ़ें:

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

रीबेस : एक नया आधार स्तर स्थापित करें:

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

स्क्वैश: क्रश या निचोड़ (कुछ) बल के साथ ताकि यह समतल हो जाए:

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


11
दिलचस्प ग्राफिक, लेकिन यह वास्तव में -no-ff मामले को नहीं दिखाता है और इसलिए यहाँ सवाल का बहुत जवाब नहीं है
Vib

22
पहला, "स्पष्ट मर्ज", जिसका शीर्षक यहां "मर्ज" है, एक गैर-एफएफ मर्ज है।
bkribbs

3
उस ग्राफिक्स ने वास्तव में मुझे बहुत मदद की
एक्सएक्सज़ियन

2
प्रति प्रश्न का उत्तर नहीं देता है, लेकिन यह ग्राफ़िक अद्भुत है, UPVOTE!
सोवियतफ्रंटियर

3
तो फिर Rebase और तेजी से आगे विलय के बीच अंतर क्या है?
थानोसफिशमैन

217

--no-ffविकल्प सुनिश्चित करता एक तेजी से आगे मर्ज हो कि नहीं, और कहा कि एक नया प्रतिबद्ध वस्तु हमेशा बनाया जाएगा । यदि आप फीचर शाखाओं के इतिहास को बनाए रखना चाहते हैं तो यह वांछनीय हो सकता है।             git मर्ज --no-ff बनाम git मर्ज उपरोक्त छवि में, बाईं ओर का उपयोग करने के बाद गिट इतिहास git merge --no-ffका एक उदाहरण है और दाईं ओर का उपयोग करने का एक उदाहरण है git mergeजहां एक एफएफ मर्ज संभव था।

EDIT : इस छवि के पिछले संस्करण ने मर्ज कमिट के लिए केवल एक ही अभिभावक का संकेत दिया। मर्ज कमिट में कई पेरेंट कमिट होते हैं जो "फीचर ब्रांच" और मूल शाखा के इतिहास को बनाए रखने के लिए git का उपयोग करता है। कई मूल लिंक हरे रंग में हाइलाइट किए गए हैं।


3
हरा तीर बनाम काला तीर क्या दर्शाता है?
23

11
हरे तीर एक कमिट और एक अभिभावक के बीच एक कड़ी को इंगित करता है, जहां कमिट में एक से अधिक माता-पिता होते हैं। सामान्य आवागमन (काला) में केवल एक माता-पिता होते हैं।
डैनियल स्मिथ

9
@DanielSmith आप इस सुरुचिपूर्ण ग्राफ को कैसे बनाते हैं?
चान्सव्यू

4
एडोब इलस्ट्रेटर के साथ @chancyWu
डैनियल स्मिथ

ऐसा लगता है कि मेरी कंपनी में सभी पुल अनुरोधों को --no-ff विकल्प के साथ विलय कर दिया गया है। उस परिस्थिति में, क्या मैं अभी भी पुर्न अनुरोध करने से पहले इसे पुनः बनाने के लिए समझ में आता है?
निकपिक

37

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


क्या आप कृपया मेरे उत्तर में वर्कफ़्लो की समीक्षा करेंगे: क्या इसका मतलब है कि मुझे अब जो कुछ मिला है, उससे परे अतिरिक्त कमिट की आवश्यकता होगी? धन्यवाद।
क्रिस के

3
@ क्रिस git merge --no-ff eccआपको बस git logशाखा मास्टर के लिए एक अतिरिक्त मर्ज कमिट होगा । मामले में मास्टर की तकनीकी तौर पर जरूरत नहीं होती है, जो प्रतिबद्ध ecc के प्रत्यक्ष पूर्वज की ओर इशारा करता है, लेकिन --no-ff विकल्प निर्दिष्ट करके आप उस मर्ज कमिट के निर्माण के लिए मजबूर कर रहे हैं। इसका शीर्षक होगा:Merge branch 'ecc'
अंकुर अग्रवाल

महान सारांश! :)
एडुआर्ड

4

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

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