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.