Git master'ı özellik şubesine birleştir


1016

Diyelim ki Git'te şu durum var:

  1. Oluşturulan bir havuz:

    mkdir GitTest2
    cd GitTest2
    git init
    
  2. Master'da bazı değişiklikler yapılır ve taahhüt edilir:

    echo "On Master" > file
    git commit -a -m "Initial commit"
    
  3. Feature1 ustası dallanmış ve bazı çalışmalar yapılmıştır:

    git branch feature1
    git checkout feature1
    echo "Feature1" > featureFile
    git commit -a -m "Commit for feature1"
    
  4. Bu arada, ana kodda bir hata bulunur ve bir düzeltme dalı oluşturulur:

    git checkout master
    git branch hotfix1
    git checkout hotfix1
    
  5. Hata, düzeltme dalında sabitlenir ve master'a geri birleştirilir (belki de bir çekme isteği / kod incelemesinden sonra):

    echo "Bugfix" > bugfixFile
    git commit -a -m "Bugfix Commit"
    git checkout master
    git merge --no-ff hotfix1
    
  6. Feature1'deki geliştirme devam ediyor:

    git checkout feature1
    

Özellik dalında düzeltmeye ihtiyacım var, belki de hata da oluştuğundan. Taahhütleri özellik branşımına çoğaltmadan bunu nasıl başarabilirim?

Unsur uygulamamla hiçbir ilgisi olmayan iki branşta iki yeni taahhüt almayı önlemek istiyorum. Çekme isteklerini kullanırsam bu özellikle benim için önemli görünüyor: Tüm bu taahhütler de çekme isteğine dahil edilecek ve zaten yapılmış olmasına rağmen gözden geçirilmesi gerekecek (düzeltme zaten anada olduğu için).

Yapamam git merge master --ff-only: "ölümcül: Hızlı ileri, iptal etmek mümkün değil", ama bunun bana yardımcı olup olmadığından emin değilim.


8
Şube feature1tamamen yerel ise, bir göz atın git rebase.
Jokester

19
Teşekkürler, bir başlangıç ​​acemi olarak, git rebasebenim için kara büyü gibi görünüyor ....
theomega

13
şube özelliği ise -sadece bu hata (orada bir engelleme hatası değilse) hata düzeltme oluşmamalıdır çünkü bu dalın amacı yeni bir özellik göstermektir. Düzeltme ile taahhüt mevcut master ile birleştirildiğinde hata düzeltilecektir.
gipi

21
Muhtemelen yeni başlayanlar için dikkat çekmeye değer 3. git branch feature1ve git checkout feature1birleştirilebilir git checkout -b feature1ve 4. tamamen azaltılabilirgit checkout -b hotfix1 master
Naruto Sempai

3
Geri dönüp kabul edilen cevabı değiştirmek ister misiniz, çünkü mevcut kabul edilen cevap çok kötü.
Yerde

Yanıtlar:


1217

Ana dalı özellik dalına nasıl birleştiririz? Kolay:

git checkout feature1
git merge master

Burada yapılamadığı için hızlı ileri bir birleştirme zorlamanın bir anlamı yoktur. Hem özellik dalını hem de ana dalını taahhüt ettiniz. Hızlı ileri almak artık mümkün değil.

GitFlow'a bir göz atın . Git için takip edilebilecek bir dallanma modelidir ve siz bilinçsizce zaten yapmışsınızdır. Ayrıca, otomatik olarak yapılması gereken şeyleri otomatik olarak yapan yeni iş akışı adımları için bazı komutlar ekleyen Git'in bir uzantısıdır.

Peki iş akışınızda ne yaptınız? Çalışmak için iki dalınız var, feature1 dalınız temelde GitFlow modelindeki "geliştirme" dalıdır.

Master'dan bir düzeltme dalı oluşturdunuz ve geri birleştirdiniz. Ve şimdi sıkışıp kaldın.

GitFlow modeli, düzeltmeyi sizin durumunuzda "feature1" olan geliştirme dalıyla da birleştirmenizi ister.

Yani asıl cevap şu olurdu:

git checkout feature1
git merge --no-ff hotfix1

Bu, düzeltme içinde yapılan tüm değişiklikleri özellik dalına ekler, ancak yalnızca bu değişiklikleri ekler . Daldaki diğer geliştirme değişiklikleriyle çakışabilirler, ancak en sonunda özellik dalını yeniden master yapmak için birleştirirseniz ana dalla çakışmazlar.

Yeniden temellendirmeye çok dikkat edin. Yalnızca yaptığınız değişikliklerin deponuzda yerel kalması durumunda yeniden oluşturun; örneğin, başka bir depoya herhangi bir şube itmediyseniz. Rebasing, yerel taahhütlerinizi dünyaya itmeden önce yararlı bir düzende düzenlemek için harika bir araçtır, ancak daha sonra yeniden basmak sizin gibi git yeni başlayanlar için işleri karıştırır.


7
Hayır. Hatayı düzelten kayıt, düzeltme dalında yalnızca bir kez görünür, ancak dal adı ana ve devel dallarıyla birleştirildikten sonra silinir. Birleştirme taahhüdü yalnızca, birleştirmenin getirdiği ve yinelenen bir taahhüt gibi görünen değişiklikleri gösterir. Ama git işte böyle işliyor: Şube ve birleşme. Gerçek geliştirme çalışması yalnızca birleştirme dışı taahhütlerde gerçekleşir ve birleştirme yalnızca sonuç çalışan bir yazılımsa kabul edilir.
Sven

42
Bu kabul edilen cevap olmalı. GitHub'ın çekme isteği özelliği ile de iyi çalışır.
Nostalg.io

125
Onun 'değerinde belirterek düşünüyorum git merge mastersenin dan birleştirilecek yerel bir yaptık yüzden bile, ustanın kopya git pullÖzelliğinizin dalında başkasının usta içine farklı bir dalı birleştikten sonra, yapmanız gerekir git checkout master, sonra git pull, sonra git checkout feature1tekrar SONRA git merge master.
damick

50
@damick Or just git fetchandgit merge origin/master
Yngvar Kristiansen

20
@damick @ yngvar-kristiansen git pull origin masterotomatik olarak orgin/mastermevcut şube ile birleşecek
L422Y

612

Şubenizi master'da yeniden kazanabilmeniz gerekir:

git checkout feature1
git rebase master

Ortaya çıkan tüm çatışmaları yönetin. Hata düzeltmeleri ile taahhütlere ulaştığınızda (zaten master'da) Git, değişiklik olmadığını ve belki de zaten uygulandığını söyleyecektir. Daha sonra (zaten master olan taahhütleri atlarken)

git rebase --skip

git logÖzellik dalınızda bir gerçekleştirirseniz, hata düzeltme işleminin yalnızca bir kez ve ana bölümde göründüğünü görürsünüz.

Daha ayrıntılı bir tartışma için, bu tam kullanım durumunu kapsayan Git kitap belgelerine git rebase( https://git-scm.com/docs/git-rebase ) bakın.

================ Ek bağlam için düzenleme ====================

Bu cevap, özellikle onun durumu dikkate alınarak @theomega tarafından sorulan soruya verilmiştir. Bu bölüme dikkat edin:

Özellik uygulamasıyla hiçbir ilgisi olmayan özellik şubemde [...] taahhütte bulunmak istemiyorum.

Özel dalını ustaya yeniden ispatlamak tam olarak bu sonucu verecek. Buna karşılık, ustası kendi dalına birleştirmek, tam olarak olmasını istemediği şeyi tam olarak yapacaktır : şubesi aracılığıyla üzerinde çalıştığı özellik uygulamasıyla ilgili olmayan bir taahhüt eklemek.

Soru başlığını okuyan kullanıcılara hitap etmek için, sorunun asıl içeriğini ve bağlamını atlayın ve ardından yalnızca (farklı) kullanım durumları için her zaman geçerli olacağını varsayarak üst cevabı körü körüne okuyun, ayrıntılı olarak açıklamama izin verin:

  • yalnızca özel şubeleri yeniden oluşturma (yani yalnızca yerel deponuzda var olan ve başkalarıyla paylaşılmayan). Paylaşılan şubelerin yeniden inşası, başkalarının sahip olabileceği kopyaları "kırar".
  • bir daldaki (ana veya başka bir daldaki) değişiklikleri herkese açık bir şubeye entegre etmek istiyorsanız (örneğin, şubeyi bir çekme isteği açmak için ittiniz, ancak şimdi ana ile çakışmalar var ve güncellemeniz gerekiyor bu çatışmaları çözmek için şubeniz) birleştirmeniz gerekir (örneğin git merge master@ Sven yanıtında olduğu gibi).
  • tercih ettiğiniz takdirde şubeleri yerel özel şubelerinizle birleştirebilirsiniz, ancak şubenizde "yabancı" taahhütlerle sonuçlanacağının farkında olun.

Son olarak, @theomega için olmasına rağmen bu cevabın durumunuza en uygun olmadığı gerçeğinden memnun değilseniz, aşağıdaki bir yorum eklemek özellikle yararlı olmayacaktır: Hangi cevabın seçildiğini kontrol etmiyorum, sadece @theomega yapar.


136
Hayır, güvenli değil: Rebase ederseniz, şubenin geçmişini değiştirirsiniz, bu da şubeyi çeken geliştiricileri etkileyecektir. inf act, git varsayılan olarak yeniden temelli bir dalı zorlamanıza izin vermez: -fdalı yeniden temelli sürümün üzerine yazmak için güncellemeye zorlamanız gerekir . Dikkatli ol!
David Sulc

17
Git kullanan profesyonel ekipler bu sorunu nasıl ele alıyor? Sadece dikkat et, dikkatlice düşün ve sonra a -f? Yoksa ihtiyacım olduğu için iş akışımın tamamı hatalı -fmı?
theomega

30
Peki, ben "kutsal" kural girişim oldu paylaşılan kod yeniden rebase (veya başka türlü değiştirmek taahhüt): sadece yerel kod için. Temel olarak, paylaşmadan önce "temizlemek" için değişikliklerinizi yeniden adlandırmalısınız. Sizin durumunuzda, yeni bir yeniden temsili şubeyi (farklı bir adla) itebilir ve meslektaşlarınızdan değişikliklerini bu şubeye dayandırmalarını isteyebilirsiniz (örn. Yerel şubelerini yeni şubeye yeniden ekleyerek yukarıdaki gibi). Ardından, feature1Github'dan silin .
David Sulc

19
Üzerinde çalıştığım profesyonel ekiplerin çoğu neredeyse hiç rebase kullanmıyorlar - varsayılan olarak her şeyi birleştiriyorlar, böylece hiçbir tarih değişikliği gerçekleşmiyor. Bu benim tercih edilen çalışma şeklim. Öte yandan, bazı takımlar taahhütleri onları itmeden önce 'temizlemek' için kullanırlar (ama asla itmeden sonra).
Jonathan Hartley

11
Evet, ASLA kamu kollarını yeniden pazarlamamalısınız. Ancak OP'nin sorusu, yapılan yeni taahhütlerin masterözel bir şubeye entegre edilmesiyle ilgiliydi ("yerel şubesinden" bahsediyor). Bu durumda, rebasegayet iyi ve bahsettiğiniz "temizlik" ile aynı kullanım durumunda.
David Sulc

69

Bu makaleye dayanarak şunları yapmalısınız:

  • yeni master sürümüne dayanan yeni bir şube yarat

    git branch -b newmaster

  • eski özellik dalınızı yenisiyle birleştirin

    git checkout newmaster

  • yeni özellik dalındaki çakışmayı çözme

İlk iki komut birleştirilebilir git checkout -b newmaster.

Bu şekilde geçmişiniz net kalır, çünkü geri birleştirmelere ihtiyacınız yoktur. Ve çok dikkatli olmanıza gerek yok, çünkü Git rebase'i yapmanız gerekmiyor.


7
ilgili git komutunu her noktayı takip ederseniz iyi olur. Aksi takdirde bana göre bu gerçekten daha güvenli ve temiz bir seçenek.
VirgileD

@zimi Uzak bir şubemiz varsa ne olur? Yeni güncelleme özelliği şubesini yeniden mi oluşturacağız? Yoksa sadece yukarı akış yönünde ayarlayabilir miyiz?
BILL

@VirgileD İlgili git komutları da dahil olmak üzere daha fazla ayrıntıyla kendi yanıtımı gönderdim .
jkdev

29

git merge

aşağıdaki adımları takip edebilirsiniz

1. origin/masterşubeden featureşubeye birleştir

# 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şubeden origin/masterşubeye birleştir

origin/masteruzak ana dal, masteryerel ana dal

$ git checkout master
$ git pull origin/master

$ git merge feature
$ git push origin/master




Rebase çok heyecanlı! Eski güzel birleştirme :)!
Mart'ta

27

Zimi'nin cevabı genellikle bu süreci açıklar. İşte özellikleri:

  1. Oluşturun ve yeni bir şubeye geçin. masterSon düzeltmeleri içerecek şekilde yeni dalın dayandığından emin olun .

    git checkout master
    git branch feature1_new
    git checkout feature1_new
    
    # Or, combined into one command:
    git checkout -b feature1_new master
    
  2. Yeni şubeye geçtikten sonra mevcut özellik dalınızdan gelen değişiklikleri birleştirin. Bu, düzeltme taahhütlerini çoğaltmadan taahhütlerinizi ekleyecektir.

    git merge feature1
    
  3. Yeni dalda, özelliğinizle ana dal arasındaki çakışmaları giderin.

Bitti! Şimdi özelliğinizi geliştirmeye devam etmek için yeni şubeyi kullanın.


2
Buradaki sorun, bir geliştiricinin master'a karşı güncelleme yapması gerektiğinde sürekli olarak yeni şubeler üretme zamanını harcamasıdır. Aktif çalışma sırasında muhtemelen günde 3 kez çok sayıda şube yapacağız. Tüm yerel çöp dallarını temizlemek ve uzaktan nasıl kurtulacağınız hakkında talimatlar yazmalısınız. Ayrıca bu dalların isimlendirilmesi konusunda tavsiyeye ihtiyacımız var, bu yüzden kafamız karışmıyor. Bu bit olmadan, bu bir şube sistemini kaosa çevirecektir.
pauljohn32

4
Haklısın, bu her zaman yapılmamalı. Yalnızca (1) özelliğinizdeki değişiklikler için özelliğiniz gerekli olduğunda veya (2) şubenizi master ile birleştirmek üzereyseniz ve çakışmalar olabilir. Dağınıklığı önlemek için dalınızı birleştirildikten sonra silebilirsiniz.
jkdev

11

İşte ana dalınızı mevcut dalınıza birleştirmek için kullanabileceğiniz bir komut dosyası.

Komut dosyası aşağıdakileri yapar:

  • Ana şubeye geçer
  • Ana dalı çeker
  • Mevcut dalınıza geri döner
  • Ana dalı geçerli dalınızla birleştirir

Bu kodu bir toplu iş dosyası (.bat) olarak kaydedin ve komut dosyasını deponuzun herhangi bir yerine yerleştirin. Sonra çalıştırmak için tıklayın ve hazırsınız.

:: 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

İhtiyaç duyduğunuz kesin taahhütleri özellik dalınıza çekmek için bir "kiraz toplama" yapabilirsiniz .

git checkout hotfix1Düzeltme1 dalına almak için bir yapın. Daha sonra git log, söz konusu taahhüdün SHA-1 karmasını (rastgele bir harfleri ve benzersiz bir şekilde kesin olarak tanımlayan büyük sayı dizisini) elde etmek için a yapın. Bunu (ya da ilk 10 karakter) kopyalayın.

Ardından, git checkout feature1özellik dalınıza geri dönmek için.

Sonra, git cherry-pick <the SHA-1 hash that you just copied>

Bu, o taahhüdü ve sadece bu taahhüdü özellik dalınıza çekecektir . Bu değişiklik dalda olacak - sadece "kiraz aldınız". Daha sonra, çalışmaya devam edin, düzenleyin, taahhüt edin, itin, vb.

Sonunda, bir daldan özellik dalınıza başka bir birleştirme yaptığınızda (ya da tam tersi) Git, söz konusu taahhütte zaten bir araya geldiğinizi anlar, tekrar yapmak zorunda olmadığını bilir ve sadece "atla".


Bunun iyi bir fikir olduğunu düşünmüyorum. Ardından, IMO, düzeltme taahhüdü, temel olarak istemediğiniz özellik dalınızın geçmişinde gerçekten görünecektir.
Martin Pecka

1
“Sonunda, bir daldan özellik dalınıza başka bir birleştirme yaptığınızda (ya da tam tersi) git git zaten birleştirdiğinizi fark edecektir [...]” - bu gerçekten böyle mi çalışıyor? git mergeBu “tekrar oynatma taahhütlerinde” işe yaradığını düşünmüyorum - ima ettiğiniz gibi görünüyor (“ve sadece atla”). Kiraz toplama ve birleştirme işlemlerinin karıştırılması problemlere yol açabilir; bkz. news.ycombinator.com/item?id=3947950
Guildenstern

0

Özellik dalındayım ve yeniden düzenleme yaptım. Ana değişiklikleri şimdi özellik dalımla birleştirmek istiyorum. Ben çok gerideyim. Not Özellik dalımda modüllerin bir yerden başka bir yere taşındığı için ana değişiklikleri yerelimde çekmek istemiyorum . Sadece çekmeden aşağıda performans buldum çalışmıyor. "Zaten güncel" yazıyor.

 //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

Aşağıdaki çalışır, not git birleştirme başlangıç ​​/ master kullanın:

 git checkout master 
    git fetch 
    git checkout my-feature-branch 
    git merge origin/master
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.