Git'teki başka bir daldaki bir dalı 'birleştirmek' yerine nasıl 'üzerine yazarım'?


257

İki şubem var emailve staging. stagingen sonuncusudur ve artık emailşubedeki eski değişikliklere ihtiyacım yok , ancak bunları silmek istemiyorum.

Bu yüzden, her ikisini de aynı taahhüde işaret edecek stagingşekilde tüm içeriğini dökmek istiyorum email. Mümkün mü?


Yanıtlar:


196

'Bizimki' birleştirme stratejisini kullanabilirsiniz:

$ git checkout staging
$ git merge -s ours email # Merge branches, but use our branch head

26
Bunu denedim ve bana ters gibi mi geliyor? Bu, e-posta içeriğini evrelemeye dökmez mi, tersine çevirmez mi?
— Max

27
@Max aynı karışıklığa sahiptim ve bu bana çok fazla sorun yarattı. Bu komutu daha yeni daldan (hazırlama) yapmanız ve ardından eski dalınıza (e-posta) normal bir birleştirme / PR yapmanız gerekir.
— MrGlass

7
Neden ;her komutun sonunda? Ben olmadan yaptım ;ve çalışıyor gibi görünüyor. Ayrıca bu cevap eksik, üçüncü adım eski şubeyi (e-posta) kontrol etmek ve daha sonra yeniden evrelemeyle birleştirmektir.
— Rosdi Kasım

4
git rebase -s theirs <oldbranc> <newbranch> (hangi dalda olursanız olun) iyi çalışır. Rebase'de 'onların' aslında yeni şube olduğunu unutmayın çünkü 'bizim' şu anda taahhütleri uyguladığımız kafa.
— Rolf

4
@Rolf: ama rebase birleştirme bilgisinden kurtulur ve geçmişi düzleştirir. Neyin peşinde olduğun değil. Ayrıca zaten yayınlanmış bir tarihle çalışıyorsanız iyi bir fikir değil.
— knittl

99

İki dalın 'e-posta' ve 'aşamalandırma'nın aynı olmasını istiyorsanız,' e-posta 'dalını etiketleyebilir, ardından' e-posta 'dalını' aşamalandırma 'dalına sıfırlayabilirsiniz:

$ git checkout email
$ git tag old-email-branch
$ git reset --hard staging

Ayrıca, 'e-posta' dalında 'aşamalandırma' dalını yeniden oluşturabilirsiniz. Ancak sonuç, iki dalın modifikasyonunu içerecektir.


1
muhtemelen demek istediğim git checkout, git check
— bilgimde

4
Haklısın, git komutunun tamamlanmasını sekmeye alıştım, her zaman "git check <TAB>" yazıyorum "git checkout"! Düzeltildi.
— Sylvain Defresne

17
git reset, deponuzu klonlayan diğer kişilerin repolarını kırdı
— Geoffrey De Smet

Bunun doğru cevap olduğuna inanıyorum. emailŞube başkanı sadece aynı başı işaret etmeli stagingve ikisi de aynı taahhütlere ve aynı tarihe sahip olacak.
— cicerocamargo

76

Birkaç cevap gördüm ve bunu herhangi bir çatışma olmadan düzeltmeme izin veren tek prosedür bu.

Branch_old içinde branch_new ile ilgili tüm değişiklikleri istiyorsanız, o zaman:

git checkout branch_new
git merge -s ours branch_old
git checkout branch_old
git merge branch_new

bu dört komutu uyguladıktan sonra, branch_old'u sorunsuz bir şekilde itebilirsiniz


5
HEAD'ı sıfırlamak istemediğim için cevabınız gerçekten benim sorunuma en iyi uyuyor, sadece eski dalda birleştirme yaparken yeni daldaki yeni dosyalar için bir tercih belirtin ve sorunsuz çalışın! +1
— sobalar

"Bizimki birleşmeden" sonra branch_new uzaktan kumanda için itti ve bu yöntem benim için çalıştı. Zorlamam gerekli miydi? Yoksa onsuz çalışır mıydı? (Yerel şubeyi mi yoksa uzaktan kumandayı mı kullanacağından emin değildi). Teşekkürler!
— Aspergillus oryzae

Neden sadece aşağıdakileri yapamıyorsunuz? git checkout branch_old git merge -s onlarınki branch_new stackoverflow.com/questions/14275856/… '
— Ripu Daman

Diyor ki, birleştirme stratejisi 'onların' bulamadı.
— arango_86

Benim için mükemmel çalışıyor, hiçbir şeyi sıfırlamama avantajına sahip
— Romain

68

Diğer cevaplar bana doğru ipuçlarını verdi, ama tamamen yardım etmediler.

İşte benim için işe yarayan:

$ git checkout email
$ git tag old-email-branch # This is optional
$ git reset --hard staging
$
$ # Using a custom commit message for the merge below
$ git merge -m 'Merge -s our where _ours_ is the branch staging' -s ours origin/email
$ git push origin email

Bizim stratejimizle birleşmenin dördüncü adımı olmadan, push hızlı ileri olmayan bir güncelleme olarak kabul edilir ve reddedilir (GitHub tarafından).


Bu, birleştirme-taahhüt mesajını yanlış yapar, ancak evet, harika çalışır.
— cdunn2001

cdunn2001, merak ediyorum. Beklediğiniz birleştirme taahhüdü mesajı neydi ve bu durum nasıl bozuldu?
— Shyam Habarakada

"Uzaktan izleme dalının 'kaynağını / e-postasını' e-postaya birleştir" yazıyor. Evrelemeden bahsetmez. Ama büyük bir anlaşma yok. Sadece taahhüdü değiştirin veya kullanın merge -m 'This is not my beautiful house.' -s ours origin/email.
— cdunn2001

@ShyamHabarakada, söylediğin gibi yapıyorum ve hızlı ileri olmayan güncelleme ile ilgili sorunu alıyorum. çünkü 4. adımı yaptığımda hiçbir şey olmuyor.
— kommradHomer

4. adım, orijin / e-posta kullanmanızı gerektirir, yalnızca yerel e-posta ile çalışmaz.
— Travis Reeder

45

Eğer benim gibi ve birleştirme ile uğraşmak istemiyorsanız, birleştirme yerine kuvvet kullanma dışında yukarıdaki adımları uygulayabilirsiniz, çünkü dikkat dağıtıcı bir günlük kağıdı izi oluşturacaktır:

git checkout email
git reset --hard staging
git push origin email --force

Not: Bu yalnızca GERÇEKTEN e-postayla tekrar bir şey görmek istemiyorsanız.


1
Git push origin email --force Step2 sol şubeleri ayrışırken benim için çalışmadı. Yani
— Step2'den

2
Bu tam olarak sorulan şeydir - "birleştirme yerine nasıl yazılır". Cevap kabul edilmelidir.
— jozols

17

İki dalı birleştirmek istedim, böylece tüm old_branchiçeriklernew_branch

Benim için bu bir cazibe gibi çalıştı:

$ git checkout new_branch
$ git merge -m 'merge message' -s ours origin/old_branch
$ git checkout old_branch
$ git merge new_branch
$ git push origin old_branch

10

Nasıl olur:

git branch -D email
git checkout staging
git checkout -b email
git push origin email --force-with-lease

@emptywalls çünkü kullanıcıyı sunucu tarafından reddedilebileceği konusunda uyarmadan bir zorlama uygular ya da neden gerekli olduğunu açıklamaz. Bununla birlikte, bir geliştirici projesi için uygun bir seçenek
— David Costa

@DavidCosta bu neden sunucu tarafından reddedilsin ki? Bu basit bir e-posta dalı silme ve e-postaya evreleme kopyalaması ... Bu yüzden sadece 'evreleme' içeriğini 'e-posta' içine dökmek istiyorum, böylece her ikisi de aynı taahhüdü işaret ediyor - tam olarak ne olduğunu buraya.
— Arek S

@ArekS şube "korumalı" olarak ayarlanmışsa, örneğin GitLab'de sunucu tarafı kancası tarafından reddedilebilir. Sorun şu ki, eğer birisi bu operasyondan önce şubesini e-postadan türemiş ve sonra itmeye çalışıyorsa, referanslar artık eşleşmiyor (çünkü bazı taahhütler ortadan kayboldu)
— David Costa

1
Orijinali --force'dan - force-toce-toce - kiraya verdim, bu hile tahribatsız bir şekilde yapar.
— frandroid

1
Bir dalı havaya uçurup kaynak daldan temizlemeye başlamak istiyorsanız bu en iyi yoldur.
— Shane

6

Diğer cevaplar eksik görünüyordu.
Aşağıda tam olarak denedim ve iyi çalıştı.

NOT:
1. Güvenli tarafta olmak için aşağıda denemeden önce deponuzun bir kopyasını oluşturun.

Ayrıntılar:
1. Tüm geliştirme dev dalında olur
2. qa dalı sadece dev
3'ün aynı kopyasıdır. Zaman zaman, dev kodu taşınmalı / qa dalının üzerine yazılmalıdır

bu yüzden dev dalından qa dalının üzerine yazmamız gerekiyor

Bölüm 1:
Aşağıdaki komutlarla, eski qa yeni geliştiriciye güncellendi:

git checkout dev
git merge -s ours qa
git checkout qa
git merge dev
git push

Son push için otomatik yorum aşağıda verilmiştir:

// Output:
//  *<MYNAME> Merge branch 'qa' into dev,*  

Bu yorum ters görünüyor, çünkü yukarıdaki dizi de ters görünüyor

Bölüm 2:

Aşağıda dev beklenmeyen, yeni yerel onaylatabilirsiniz vardır, gereksiz olanları
yüzden biz atmak ve dev el değmemiş yapmak gerekir.

git checkout dev

// Output:
//  Switched to branch 'dev'  
//  Your branch is ahead of 'origin/dev' by 15 commits.  
//  (use "git push" to publish your local commits)


git reset --hard origin/dev  

//  Now we threw away the unexpected commits

Bölüm 3:
Her şeyin beklendiği gibi olduğunu doğrulayın:

git status  

// Output:
//  *On branch dev  
//  Your branch is up-to-date with 'origin/dev'.  
//  nothing to commit, working tree clean*  

Bu kadar.
1. eski qa artık yeni geliştirici şube kodu tarafından yazılıyor
2. yerel temiz (uzak kökeni / geliştirici el değmemiş)


6

Bunu yapmanın en kolay yolu:

//the branch you want to overwrite
git checkout email 

//reset to the new branch
git reset --hard origin/staging

// push to remote
git push -f

Şimdi e-posta şubesi ve sahneleme aynı.


2
Uyarı: Bu, emailşubedeki tüm taahhütleri siler . emailŞubeyi silmek ve şubenin başında yeniden oluşturmak gibi staging.
— Cameron Hudson

2
git checkout email
git merge -m "Making email same as staging disregarding any conflicts from email in the process" -s recursive -X theirs staging

1
Yorum komuttaki birleştirme yorumundan ayrı yapılırsa bu cevap bana daha açık olurdu. -X'in ne yaptığını ve bu birleştirmeyi nasıl etkilediğini kısaca açıklayın. Yine de teşekkürler. Bana bakın :)
— noelicus

@ noelicus yorum için teşekkürler ve haklısın. Cevabı gelecekte düzenleyebilirim.
— Willa

0

Bu, orijinal yeni dalı değiştirmez ve son taahhütten önce daha fazla değişiklik yapma fırsatı verir.

git checkout new -b tmp
git merge -s ours old -m 'irrelevant'
git checkout old
git merge --squash tmp
git branch -D tmp
#do any other stuff you want
git add -A; git commit -m 'foo' #commit (or however you like)
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.