मास्टर को फीचर शाखा में मर्ज करें


1012

मान लें कि हमारे पास Git में निम्नलिखित स्थिति है:

  1. एक निर्मित भंडार:

    mkdir GitTest2
    cd GitTest2
    git init
    
  2. मास्टर में कुछ संशोधन होते हैं और प्रतिबद्ध होते हैं:

    echo "On Master" > file
    git commit -a -m "Initial commit"
    
  3. सुविधा 1 मास्टर और कुछ काम किया जाता है:

    git branch feature1
    git checkout feature1
    echo "Feature1" > featureFile
    git commit -a -m "Commit for feature1"
    
  4. इस बीच, एक बग मास्टर-कोड में खोजा जाता है और एक हॉटफ़िक्स-शाखा स्थापित की जाती है:

    git checkout master
    git branch hotfix1
    git checkout hotfix1
    
  5. बग को हॉटफ़िक्स शाखा में तय किया गया है और मास्टर में वापस विलय कर दिया गया है (शायद एक पुल अनुरोध / कोड समीक्षा के बाद):

    echo "Bugfix" > bugfixFile
    git commit -a -m "Bugfix Commit"
    git checkout master
    git merge --no-ff hotfix1
    
  6. फीचर 1 पर विकास जारी है:

    git checkout feature1
    

कहो कि मुझे अपनी सुविधा शाखा में हॉटफ़िक्स की आवश्यकता है, हो सकता है कि बग भी वहाँ हो। मैं अपनी सुविधा शाखा में कमिट की नकल किए बिना इसे कैसे प्राप्त कर सकता हूं?

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

मैं ऐसा नहीं कर सकता git merge master --ff-only: "घातक: तेजी से आगे बढ़ना, गर्भपात करना संभव नहीं है।", लेकिन मुझे यकीन नहीं है कि इससे मुझे मदद मिली।


8
यदि शाखा feature1पूरी तरह से स्थानीय है, तो एक नज़र डालें git rebase
जोसेस्टर

19
धन्यवाद, एक शुरुआत के रूप में, git rebaseमेरे लिए काले जादू की तरह लगता है ....
ओमेगा

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

21
शायद शुरुआती के लिए ध्यान देने योग्य है कि 3 में। git branch feature1और git checkout feature1में जोड़ा जा सकता है git checkout -b feature1और 4. पूरी तरह से कम किया जा सकता हैgit checkout -b hotfix1 master
नारुतो सेम्पाई

3
क्या आप वापस आने और स्वीकृत उत्तर को बदलने के लिए तैयार होंगे, क्योंकि वर्तमान स्वीकृत उत्तर भयानक है।
ओमनीफेरियस

जवाबों:


1212

हम मास्टर शाखा को फीचर शाखा में कैसे मिलाते हैं? आसान:

git checkout feature1
git merge master

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

GitFlow पर एक नजर है । यह git के लिए एक ब्रांचिंग मॉडल है जिसका पालन किया जा सकता है, और आप अनजाने में पहले से ही कर चुके हैं। यह Git का एक विस्तार भी है जो नए वर्कफ़्लो चरणों के लिए कुछ कमांड जोड़ता है जो स्वचालित रूप से चीजें करते हैं जो आपको अन्यथा मैन्युअल रूप से करने की आवश्यकता होगी।

तो आपने अपने वर्कफ़्लो में क्या सही किया? आपके पास काम करने के लिए दो शाखाएँ हैं, आपकी सुविधा 1 शाखा मूल रूप से GitFlow मॉडल में "विकसित" शाखा है।

आपने मास्टर से एक हॉटफ़िक्स शाखा बनाई और उसे वापस मर्ज कर दिया। और अब तुम फंस गए हो।

GitFlow मॉडल आपको हॉटफ़िक्स को विकास शाखा में विलय करने के लिए कहता है, जो आपके मामले में "फीचर 1" है।

तो असली जवाब होगा:

git checkout feature1
git merge --no-ff hotfix1

यह उन सभी परिवर्तनों को जोड़ता है जो हॉटफ़िक्स के अंदर सुविधा शाखा में किए गए थे, लेकिन केवल उन परिवर्तनों को। वे शाखा में अन्य विकास परिवर्तनों के साथ संघर्ष कर सकते हैं, लेकिन वे मास्टर शाखा के साथ संघर्ष नहीं करेंगे क्या आपको अंततः सुविधा शाखा को वापस मास्टर में विलय करना चाहिए।

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


7
नहीं। बग को ठीक करने की प्रतिबद्धता केवल एक बार हॉटफ़िक्स शाखा में दिखाई देती है, भले ही शाखा का नाम मास्टर और डेवेल शाखाओं में विलय हो जाने के बाद हटा दिया जाता है। मर्ज कमेटी केवल मर्ज द्वारा पेश किए गए परिवर्तनों को दिखाती है, जो डुप्लिकेट कमिट की तरह दिखता है। लेकिन यह कैसे काम करता है: शाखा और वापस विलय। वास्तविक विकास कार्य केवल गैर-मर्ज कमिट में होता है, और यदि परिणाम कार्यशील सॉफ़्टवेयर है तो केवल मर्ज स्वीकार किया जाता है।
स्वेन

42
यह स्वीकृत उत्तर होना चाहिए। यह GitHub के पुल अनुरोध सुविधा के साथ अच्छी तरह से काम करता है।
Nostalg.io

125
मुझे लगता है कि यह ध्यान देने योग्य है कि एक मास्टर की git merge masterआपकी स्थानीय प्रति से विलीन हो जाएगी , इसलिए भले ही आपने git pullअपनी सुविधा शाखा में किसी अन्य व्यक्ति को मास्टर में विलय करने के बाद, आपने git checkout master, फिर git pull, git checkout feature1फिर और फिर से करने की आवश्यकता होगी git merge master
3

50
@ यामदिक या सिर्फ git fetchऔरgit merge origin/master
यंगवार क्रिस्टियनसेन

20
@damick @ yngvar-kristiansen git pull origin masterस्वचालित रूप orgin/masterसे वर्तमान शाखा में विलीन हो जाएगी
L422Y

612

आपको मास्टर पर अपनी शाखा को पुनः प्राप्त करने में सक्षम होना चाहिए:

git checkout feature1
git rebase master

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

git rebase --skip

यदि आप git logअपनी सुविधा शाखा पर प्रदर्शन करते हैं , तो आप देखेंगे कि बगफिक्स कमिटमेंट केवल एक बार और मास्टर भाग में दिखाई देगा।

अधिक विस्तृत चर्चा के लिए, इस सटीक उपयोग मामले को कवर करने वाले git rebase( https://git-scm.com/docs/git-rebase ) पर गिट बुक प्रलेखन पर एक नज़र डालें ।

================ अतिरिक्त संदर्भ के लिए संपादित करें ====================

यह उत्तर विशेष रूप से @theomega द्वारा पूछे गए प्रश्न के लिए प्रदान किया गया था, अपनी विशेष स्थिति को ध्यान में रखते हुए। इस भाग पर ध्यान दें:

मैं अपनी सुविधा शाखा पर रोकना चाहता हूं [...] जिसका फीचर कार्यान्वयन से कोई संबंध नहीं है।

मास्टर पर अपनी निजी शाखा को रिबास करना वास्तव में उस परिणाम को प्राप्त करेगा। इसके विपरीत, अपनी शाखा में मास्टर का विलय ठीक वही करेगा जो वह विशेष रूप से नहीं करना चाहता है : एक ऐसी प्रतिबद्धता को जोड़ना जो उस सुविधा के कार्यान्वयन से संबंधित नहीं है जो वह अपनी शाखा के माध्यम से काम कर रहा है।

प्रश्न शीर्षक पढ़ने वाले उपयोगकर्ताओं को संबोधित करने के लिए, प्रश्न की वास्तविक सामग्री और संदर्भ को छोड़ दें, और उसके बाद केवल शीर्ष उत्तर को आँख बंद करके पढ़ें यह मानते हुए कि यह हमेशा उनके (अलग) उपयोग के मामले पर लागू होगा, मुझे विस्तृत करने की अनुमति दें:

  • केवल निजी शाखाओं को रिबेट करें (अर्थात जो केवल आपके स्थानीय भंडार में मौजूद हैं और दूसरों के साथ साझा नहीं की गई हैं)। साझा की गई शाखाओं को रीबस करने से अन्य लोगों के पास होने वाली प्रतियों को "तोड़" दिया जाएगा।
  • यदि आप एक शाखा से परिवर्तन (चाहे वह मास्टर या कोई अन्य शाखा हो) को उस शाखा में एकीकृत करना चाहते हैं जो सार्वजनिक है (जैसे कि आपने शाखा को पुल अनुरोध खोलने के लिए धक्का दिया है, लेकिन अब मास्टर के साथ संघर्ष हैं, और आपको अपडेट करने की आवश्यकता है उन संघर्षों को हल करने के लिए आपकी शाखा) आपको उन्हें मर्ज करने की आवश्यकता होगी (जैसे git merge master@ स्वेन के जवाब में)।
  • यदि आप अपनी पसंद के अनुसार अपनी स्थानीय निजी शाखाओं में शाखाएँ मिला सकते हैं, लेकिन ध्यान रहे कि इसका परिणाम आपकी शाखा में "विदेशी" होगा।

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


136
नहीं, यह सुरक्षित नहीं है: यदि आप छूट देते हैं, तो आप शाखा के इतिहास को बदल रहे हैं, जो शाखा को खींचने वाले डेवलपर्स को प्रभावित करेगा। एक्ट एक्ट, git आपको डिफॉल्ट रूप से एक रिजेक्टेड ब्रांच को पुश नहीं करने देगा: आपको -fरीबेडेड वर्जन के साथ ब्रांच को ओवरराइट करने के लिए पुश करने के साथ अपडेट को मजबूर करने की जरूरत है । सावधान रहे!
डेविड सुल्क

17
पेशेवर टीम इस मुद्दे को कैसे संभालती है? क्या सिर्फ ध्यान देना, ध्यान से सोचना और फिर क्या करना -f? या क्या मेरा पूरा वर्कफ़्लो त्रुटिपूर्ण है क्योंकि मुझे इसकी आवश्यकता है -f?
ओमेगा

30
ठीक है, मैं "पवित्र" नियम का पालन करता हूं कि क्या आप साझा किए गए कोड पर रिबास (या अन्यथा परिवर्तन इतिहास नहीं) करते हैं: यह केवल आपके स्थानीय कोड के लिए है। मूल रूप से, आपको इसे साझा करने से पहले "क्लीन अप" करने के लिए अपने परिवर्तनों को वापस करना चाहिए। आपके मामले में, आप एक नई विद्रोही शाखा (एक अलग नाम के साथ) को धक्का दे सकते हैं, और सहकर्मियों को उस शाखा से अपने परिवर्तनों को आधार बनाने के लिए कह सकते हैं (अर्थात ऊपर की तरह अपनी स्थानीय शाखा को नए सिरे से बंद करके)। फिर, feature1Github से हटाएं ।
डेविड सुल्क

19
मैंने जिन पेशेवर टीमों में काम किया है उनमें से अधिकांश ने लगभग कभी भी रिबास का उपयोग नहीं किया है - वे बस डिफ़ॉल्ट रूप से सब कुछ मर्ज करते हैं, ताकि कोई इतिहास संशोधन कभी न हो। यह मेरे काम करने का पसंदीदा तरीका है। दूसरी ओर, कुछ टीमें रिबेट का इस्तेमाल 'क्लीन अप' करने से पहले करती हैं ताकि उन्हें धक्का दिया जा सके (लेकिन धक्का देने के बाद कभी भी नहीं।)
जोनाथन हार्टले

11
हां, आपको सार्वजनिक शाखाओं को कभी भी रद्द नहीं करना चाहिए। हालांकि, ओपी का सवाल masterएक निजी शाखा में किए गए नए कमिट को एकीकृत करने से संबंधित था (वह अपनी "स्थानीय शाखा" का उल्लेख करता है)। उस मामले में, rebaseठीक है और आपके द्वारा उल्लेखित "सफाई" के रूप में एक ही उपयोग का मामला है।
बजे डेविड Sulc

69

इस लेख के आधार पर , आपको यह करना चाहिए:

  • नई शाखा बनाएँ जो मास्टर के नए संस्करण पर आधारित हो

    git branch -b newmaster

  • अपनी पुरानी सुविधा शाखा को नए में मर्ज करें

    git checkout newmaster

  • नई सुविधा शाखा पर संघर्ष को हल करें

पहले दो आदेशों को संयुक्त किया जा सकता है git checkout -b newmaster

इस तरह आपका इतिहास स्पष्ट रहता है क्योंकि आपको बैक मर्ज की आवश्यकता नहीं होती है। और आपको इतना सुपर सतर्क होने की आवश्यकता नहीं है क्योंकि आपको एक जीआईटी रिबास करने की आवश्यकता नहीं है।


7
अच्छा होगा यदि आप संबंधित गिट कमांड को प्रत्येक बिंदु का पालन करें। अन्यथा यह मुझे लगता है कि यह वास्तव में अधिक सुरक्षित और स्वच्छ विकल्प है।
विर्जिलेड

@ ज़मी क्या है अगर हमारे पास एक दूरस्थ शाखा है? क्या हम नई अपडेट सुविधा शाखा को फिर से बनाएंगे? या हम सिर्फ रिमोट-अपस्ट्रीम सेट कर सकते हैं?
बिल

@VirgileD मैं अभी संबंधित git कमांड सहित अधिक विवरण के साथ अपना उत्तर पोस्ट कर रहा हूं ।
jkdev

29

git merge

आप नीचे दिए गए चरणों का पालन कर सकते हैं

1. origin/masterशाखा को featureशाखा में विलय करना

# step1: change branch to master, and pull to update all commits
$ git checkout master
$ git pull

# step2: change branch to target, and pull to update commits
$ git checkout feature
$ git pull

# step3: merge master to feature(⚠️ current is feature branch)
$ git merge master

2. featureशाखा को origin/masterशाखा में विलय करना

origin/masterदूरस्थ मास्टर शाखा है, जबकि masterस्थानीय मास्टर शाखा है

$ git checkout master
$ git pull origin/master

$ git merge feature
$ git push origin/master




लगता है कि रिबास पाखंड है! अच्छा पुराना मर्ज :)!
हमेशा

27

ज़िमी का जवाब इस प्रक्रिया का आम तौर पर वर्णन करता है। यहाँ विशेष हैं:

  1. एक नई शाखा बनाएं और स्विच करें। सुनिश्चित करें कि नई शाखा आधारित है, masterइसलिए इसमें हाल की हॉटफ़िक्स शामिल होंगी।

    git checkout master
    git branch feature1_new
    git checkout feature1_new
    
    # Or, combined into one command:
    git checkout -b feature1_new master
    
  2. नई शाखा में जाने के बाद, अपनी मौजूदा सुविधा शाखा से परिवर्तनों को मर्ज करें। यह हॉटफ़िक्स कॉम्पेक्ट को डुप्लिकेट किए बिना आपके कमिट को जोड़ देगा।

    git merge feature1
    
  3. नई शाखा पर, अपनी सुविधा और मास्टर शाखा के बीच किसी भी विवाद को हल करें।

किया हुआ! अब अपनी सुविधा को विकसित करने के लिए नई शाखा का उपयोग करें।


2
इसके साथ समस्या यह है कि एक डेवलपर लगातार नई शाखाओं को बर्बाद करने में समय बर्बाद करता है जब उन्हें मास्टर के खिलाफ अपडेट करने की आवश्यकता होती है। हम सक्रिय कार्य के दौरान प्रति दिन 3 बार बहुत सारी और बहुत सी शाखाएँ बना रहे होंगे। आपको सभी स्थानीय कचरा शाखाओं को साफ करने के बारे में निर्देश लिखना चाहिए, और रिमोट पर भी उनसे छुटकारा कैसे प्राप्त करना चाहिए। हमें इन सभी शाखाओं के नामकरण पर भी सलाह की आवश्यकता है ताकि हम भ्रमित न हों। उस बिट के बिना, यह एक शाखा प्रणाली को अराजकता में बदल देगा।
पौलज्जो ३२

4
आप सही हैं, यह हर समय नहीं किया जाना चाहिए। केवल तभी जब (1) मास्टर पर परिवर्तन आपकी सुविधा के लिए आवश्यक हैं, या (2) आप अपनी शाखा को मास्टर के साथ मिलाने वाले हैं और इसमें टकराव हो सकता है। और अव्यवस्था से बचने के लिए, आप अपनी शाखा को विलीन होने के बाद हटा सकते हैं।
जकदेव

11

यहाँ एक स्क्रिप्ट है जिसका उपयोग आप अपनी मास्टर शाखा को अपनी वर्तमान शाखा में मर्ज करने के लिए कर सकते हैं।

स्क्रिप्ट निम्न कार्य करती है:

  • मास्टर शाखा में बदल जाता है
  • मास्टर शाखा खींचता है
  • अपनी वर्तमान शाखा में वापस आ जाता है
  • अपनी वर्तमान शाखा में मास्टर शाखा को जोड़ता है

इस कोड को बैच फ़ाइल (.bat) के रूप में सहेजें और स्क्रिप्ट को कहीं भी अपने रिपॉजिटरी में रखें। फिर इसे चलाने के लिए उस पर क्लिक करें और आप सेट हैं।

:: This batch file pulls current master and merges into current branch

@echo off

:: Option to use the batch file outside the repo and pass the repo path as an arg
set repoPath=%1
cd %repoPath%

FOR /F "tokens=*" %%g IN ('git rev-parse --abbrev-ref HEAD') do (SET currentBranch=%%g)

echo current branch is %currentBranch%
echo switching to master
git checkout master
echo.
echo pulling origin master
git pull origin master
echo.
echo switching back to %currentBranch%
git checkout %currentBranch%
echo.
echo attemting merge master into %currentBranch%
git merge master
echo.
echo script finished successfully
PAUSE

10

हो सकता है कि आप अपनी सुविधा शाखा में आवश्यक सटीक प्रतिबद्ध (ओं) को खींचने के लिए "चेरी-पिक" करने में सक्षम हों।

git checkout hotfix1हॉटफिक्स 1 शाखा पर प्राप्त करने के लिए एक करें। फिर git logSHA-1 हैश (यादृच्छिक अक्षरों और संख्याओं का बड़ा क्रम) प्राप्त करने के लिए करें जो प्रश्न में प्रतिबद्ध की विशिष्ट रूप से पहचान करता है)। कॉपी करें (या पहले 10 या तो अक्षर)।

फिर, git checkout feature1अपनी सुविधा शाखा पर वापस जाने के लिए।

फिर, git cherry-pick <the SHA-1 hash that you just copied>

जो आपके कमिटमेंट शाखा में उस कमिट को, और केवल उस कमिट को खींचेगा। वह परिवर्तन शाखा में होगा - आप इसे केवल "चेरी-पिक" करें। फिर, अपने दिल की सामग्री को फिर से शुरू करें, संपादित करें, प्रतिबद्ध करें, पुश करें आदि।

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


मैं इसे एक अच्छा विचार नहीं मानता। फिर, IMO, हॉटफिक्स प्रतिबद्ध वास्तव में आपकी सुविधा शाखा के इतिहास में दिखाई देगा, जिसे आप मूल रूप से नहीं चाहते हैं।
मार्टिन पेक्का

1
"जब, अंततः, आप अपनी सुविधा शाखा (या इसके विपरीत) में एक शाखा से एक और मर्ज करते हैं, तो गिट यह पहचान लेगा कि आपने पहले ही विलय कर दिया है [...]" - क्या यह वास्तव में काम करता है? मुझे नहीं लगता कि git mergeइस "रीप्ले कमिट्स" में काम करता है -जिससे आपको लगता है कि आप ("और बस छोड़ें") से इशारा करते हैं। चेरी पिकिंग और मर्जिंग को मिलाकर जाहिर तौर पर समस्याएँ पैदा हो सकती हैं; देखें: news.ycombinator.com/item?id=3947950
गिल्डनस्टर्न

0

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

 //below does not get the latest from remote master to my local feature branch without git pull
    git checkout master 
    git fetch 
    git checkout my-feature-branch 
    git merge master

यह नीचे काम करता है, नोट git मर्ज मूल / मास्टर का उपयोग करें:

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