Git'te belirli bir işlem nasıl birleştirilir?


1034

GitHub'daki bir depodan bir şube çatalladım ve bana özel bir şey yaptım. Şimdi orijinal havuzun iyi bir özelliği olduğunu gördüm HEAD.

Sadece önceki taahhütler olmadan birleştirmek istiyorum. Ne yapmalıyım? Tüm taahhütleri nasıl birleştireceğimizi biliyorum:

git branch -b a-good-feature
git pull repository master
git checkout master
git merge a-good-feature
git commit -a
git push

Bunu github ile ilgili olarak yapmaya çalışıyorsanız, bu makale sizi adım adım yönlendirecektir. markosullivan.ca/how-to-handle-a-pull-request-from-github
johndpope

Yanıtlar:


1174

' git cherry-pick' burada cevabınız olmalı.

Mevcut bir taahhüdün getirdiği değişikliği uygulayın.

Bu yazıdaki kiraz toplama sonucuyla ilgili bdonlan'ın cevabını okumayı unutmayın :
"Bir şubeden tüm taahhütleri çekin, belirtilen taahhütleri bir başkasına itin" , burada:

A-----B------C
 \
  \
   D

dönüşür:

A-----B------C
 \
  \
   D-----C'

Bu taahhüdün problemi git'in önlerindeki tüm tarihi içermeyi taahhüt etmesidir

Burada C 'nin farklı bir SHA-1kimliği vardır.
Benzer şekilde, kiraz bir daldan diğerine bir taahhüt almak temelde bir yama üretmeyi, daha sonra uygulamayı, böylece tarihi de bu şekilde kaybetmeyi içerir.

Taahhüt kimliklerinin bu şekilde değiştirilmesi git'in diğer şeylerin yanı sıra birleştirme işlevselliğini bozar (ancak çok az kullanılırsa, bunun üzerinde anlaşılacak sezgisel yöntemler vardır).
Daha da önemlisi, fonksiyonel bağımlılıkları göz ardı eder - C aslında B'de tanımlanan bir işlevi kullandıysa, asla bilemezsiniz .


1
@ openid000: "daha ince taneli dallar": bdonlan'ın cevabında tam olarak önerdiği şey budur.
VonC

8
Not: "git rebase" de SHA-1'i değiştirir. Ayrıca "git Rebase vs git birleştirme (Bkz stackoverflow.com/questions/804115/git-rebase-vs-git-merge ) ve "git iş akışı"( stackoverflow.com/questions/457927/... durumlar için) nerede" git rebase "meşru.
VonC

1
"İnce taneli dallar", "kiraz toplama" ve "rebase" arasında git ile dallarda kod yönetimi için tüm olanaklara sahip olacaksınız.
VonC

@VonC "ince taneli dallar" evet. İki şubem vardı ve bir şubedeki belirli bir görselleştirme modülüne yükseltme yaptım. Bu modül diğer tüm kodlardan bağımsızdı, bu yüzden kiraz toplama bu değişiklikleri diğer şubelere de uygulamak için çok uygun oldu
Cheeku

1
Ancak, birleştirdiğinizde, taahhüt tarihinde hem C 'hem de C'nin geçerli olacağına dikkat edin.
Rahul Shah

738

Geçerli dalınıza tek bir işlem uygulamak için git cherry-pick'u kullanabilirsiniz.

Misal: git cherry-pick d42c389f


68
Kiraz toplama ile ilgili önceki yayınınız için +1 ( stackoverflow.com/questions/880957/… ). Yukarıdaki cevabımda bir alıntısını kopyalama özgürlüğünü aldım.
VonC

4
Muhtemelen git cherry-pick d42cya git cherry-pick d42c3 da çalışacaktır. Git akıllıdır. ;)
guneysus

2
ölümcül: kötü gözden geçirme
Ievgen Naida

2
Ben sadece bu komutu yerine getirdim ve işe yaramış gibi görünüyor, ama git durumu yaptığımda, "taahhüt edilecek hiçbir şey yok, ağaç temiz çalışıyor" diyor. Bitbucket web sayfamdaki İşlemler sayfasını yenilediğimde görünmüyor. Ama git logunu çalıştırdığımda görünüyor. Ve değiştirilmiş kodu görüyorum. Başka adımlar atmam gerekip gerekmediğini birisi açıklayabilir mi?
Ray

1
Ne yazık ki bu şu soruyu cevaplamıyor: Aslında bir birleştirme yaratmıyor. İşaret eden soy yok d42c389f. Belki OP kendiliğinden birleştirme yaratmayı umursamıyordu , ama fark bazen önemli.
LarsH

29

Bir örnek almaya ve anlamaya çalışalım:

Bir dal, diyelim sahip usta X <işlemek-id> işaret ederek, ve ben <sha1> Y için yeni bir şube işaret var.

Nerede Y <işlemek-id> = <usta> dal kaydedilmesini - Birkaç onaylatabilirsiniz

Şimdi Y dalı için ana dal ile yeni dal arasındaki taahhütleri boşlukla kapatmam gerektiğini söyleyin. Takip edebileceğimiz prosedür aşağıdadır:

Aşama 1:

git checkout -b local origin/new

burada yerel şube adıdır. Herhangi bir isim verilebilir.

Adım 2:

  git merge origin/master --no-ff --stat -v --log=300

Ana şubeden yeni şubeye birleştirme işlemlerini birleştirin ve ayrıca birleştirilen en fazla <n> gerçek işlemden tek satırlık açıklamalarla bir günlük kaydı birleştirme işlemi oluşturun.

Git birleştirme hakkında daha fazla bilgi ve parametre için lütfen şu adrese başvurun:

git merge --help

Ayrıca belirli bir taahhüdü birleştirmeniz gerekiyorsa, şunları kullanabilirsiniz:

git cherry-pick <commit-id>

Y3d cümlenizin tanımını değiştirdiniz mi? "Y'yi işaret eden yeni bir
dalım var

bunu birleştirmek istediğim bir dalın belirli bir taahhüt noktasından nasıl yapabilirim
Kulbhushan Singh

3

Benim kullanım durumumda da CI CD'ye benzer bir ihtiyaç vardı. Git akışını geliştirme ve master dalları ile kullandık. Geliştiriciler, bir geliştirme branşından geliştirme isteği veya çekme isteği yoluyla doğrudan değişiklikleri birleştirmekte özgürdürler. Ancak master yapmak için Jenkins ile geliştirme dalından sadece kararlı taahhütleri otomatik bir şekilde birleştiriyoruz.

Bu durumda kiraz toplama yapmak iyi bir seçenek değildir. Ancak, command-id'den bir yerel şube yaratırız ve daha sonra mvn clean doğrulamasını (maven kullanırız) master yapmak ve gerçekleştirmek için bu yerel dalı birleştiririz. Başarılı olursa, localCheckout = true seçenek ve pushChanges = false ile maven yayın eklentisini kullanarak üretim sürümü yapısını nexus'a bırakın. Sonunda her şey başarılı olduğunda değişiklikleri ve etiketi başlangıç ​​noktasına itin.

Bir örnek kod snippet'i:

Manuel olarak yapılırsa master'da olduğunuzu varsayarsak. Ancak jenkinlerde, repoya baktığınızda varsayılan dalda olacaksınız (yapılandırılmışsa master).

git pull  // Just to pull any changes.
git branch local-<commitd-id> <commit-id>  // Create a branch from the given commit-id
git merge local-<commit-id>  // Merge that local branch to master.
mvn clean verify   // Verify if the code is build able
mvn <any args> release:clean release:prepare release:perform // Release artifacts
git push origin/master  // Push the local changes performed above to origin.
git push origin <tag>  // Push the tag to origin

Bu size korkusuz birleşme veya çatışma cehennemi ile tam bir kontrol verecektir.

Daha iyi bir seçenek olduğunda tavsiyede bulunmaktan çekinmeyin.


3

Başlıca yanıtlar, belirli bir taahhütten gelen değişikliklerin mevcut şubeye nasıl uygulanacağını açıklar . "Nasıl birleştirilir" ile kastettiğiniz buysa, önerdikleri gibi kiraz toplama kullanın.

Ancak aslında bir birleşme istiyorsanız , yani iki ebeveynle yeni bir taahhüt istiyorsanız - mevcut daldaki mevcut taahhüt ve değişiklikleri uygulamak istediğiniz taahhüt - o zaman kiraz toplama bunu başaramaz.

Örneğin, oluşturma işleminiz en son etikete (kullanarak git describe) göre sürüm dizelerini otomatik olarak ayarlamak için git soyunun avantajından yararlanıyorsa gerçek birleştirme geçmişine sahip olmak arzu edilebilir .

Kiraz toplama yerine gerçek bir işlem yapabilir git merge --no-commitve ardından istemediğiniz değişiklikleri kaldırmak için dizini manuel olarak ayarlayabilirsiniz.

Diyelim ki daldasınız ve şubenin Aucundaki taahhüdü birleştirmek istiyorsunuz B:

git checkout A
git merge --no-commit B

Şimdi iki ebeveynle bir taahhüt oluşturmaya hazırsınız, mevcut ipucu Ave B. Bununla birlikte, B dalında daha önce yapılan taahhütler de dahil olmak üzere, istediğinizden daha fazla değişiklik uygulayabilirsiniz. Bu istenmeyen değişiklikleri geri almanız ve ardından taahhütte bulunmanız gerekir.

(Çalışma dizininin durumunu ve dizini birleştirme işleminden önceki haline geri döndürmenin kolay bir yolu olabilir, böylece ilk etapta istediğiniz taahhüdü kiraz olarak seçmek için temiz bir sayfa kullanabilirsiniz. O temiz levhayı nasıl elde edeceğimi bilmiyorum git checkout HEADve git reset HEADher ikisi de birleştirme durumunu kaldıracak ve bu yöntemin amacını yenecek.)

Bu nedenle, istenmeyen değişiklikleri manuel olarak geri alın. Örneğin,

git revert --no-commit 012ea56

her istenmeyen taahhüt için 012ea56.

Bir şeyleri ayarlamayı bitirdiğinizde, taahhüdünüzü oluşturun:

git commit -m "Merge in commit 823749a from B which tweaked the timeout code"

Artık sadece istediğiniz değişikliğe sahipsiniz ve soy ağacı, teknik olarak B'den birleştirdiğinizi gösteriyor.

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.