Taahhütleri birleştirmek yerine değişiklikleri tek bir dosyada nasıl birleştiririm?


383

İki dalım (A ve B) var ve A dalından tek bir dosyayı B Dalından karşılık gelen tek bir dosyayla birleştirmek istiyorum.


2
Burada zaten tartışıldı stackoverflow.com/questions/449541/…
positron

27
Bu diğer gönderiye verilen yanıtların çoğu, dosyaları değil, taahhütleri seçici olarak nasıl birleştireceğinizle ilgilidir . Bu, seçilen yanıtı yanlış yapar. Soru hala cevapsız.


Bu cevap gitmek için bir yol, IMO. git diff branch_name > patch git apply patch. stackoverflow.com/a/9473543/1091853
19:55

Yanıtlar:


631

Ben de aynı problemle karşılaştım. Kesin olmak gerekirse, iki şubem var Ave Baynı dosyalarla ama bazı dosyalarda farklı bir programlama arayüzü var. Şimdi, fiki daldaki arayüz farklılıklarından bağımsız olan dosya yöntemleri dalda değiştirildi B, ancak değişiklik her iki dal için de önemli. Böylece, sadece dosyayı birleştirmek için gereken fşube Bdosyasına fşube A.

Bütün değişiklikler her iki branşta kararlı olduklarını varsayarsak basit bir komut zaten benim için sorun çözüldü Ave B:

git checkout A

git checkout --patch B f

İlk komut şubeye A, Bdosyanın sürümünü birleştirmek istediğim yere geçer f. İkinci komut , of file dosyasını yamalar . Yamanın tek parçalarını bile kabul edebilir / atabilirsiniz. Yerine herhangi burada taahhüt belirtebilir, böyle olmak zorunda değildir .fHEADBBHEAD

Topluluk düzenleme : füzerindeki dosya henüz Bmevcut değilse seçeneği Akaldırın --patch. Aksi takdirde, "Değişiklik Yok" alırsınız. İleti.


10
Bu yalnızca bir dosyayı güncellemek istiyorsanız çalışır. B dalından A dalına yeni bir dosya eklemek istersem ne olur?
Umair A.

25
@UmairAshraf --patch seçeneğini kaldırarak B'den A'ya yeni bir dosya ekleyebilmeniz gerekir.
bbak

9
Hmmm ... bunu denediğimde "değişiklik yok" mesajını alıyorum, ama açıkça değişiklikler var. Tamam, ilgili dosyanın olduğu klasörde olmalıydım. Düzenleme: Bu büyük olasılıkla stackoverflow üzerinde gördüğüm bir sorun benim en sevdiğim çözüm olabilir:
D

2
Bunu git checkout --patch B -- fişe almak için kullanmak zorunda kaldım.
user545424

8
Dosyada birden fazla değişiklik (iri parça) varsa ve hepsini sahneye koymak istiyorsanız, her seferinde abasmak yerine etkileşimli aşamada basabileceğinizi eklemeniz yeterlidiry . Veya git checkout B -- fbunun yerine komutu kullanın.
Dmitry Gonchar

17

İşte bu durumlarda yaptığım şey. Bu bir çamur ama benim için iyi çalışıyor.

  1. Çalışma kolunuz dışında başka bir şube oluşturun.
  2. git pull / git kopyalamak istediğiniz dosyayı içeren düzeltmeyi (SHA1) birleştirir. Bu, tüm değişikliklerinizi birleştirecek, ancak bu dalı yalnızca bir dosyayı almak için kullanıyoruz.
  3. Çakışmaları vb. Düzelterek dosyanızı araştırın.
  4. çalışma şubenizi kontrol edin
  5. Birleştirmeden taahhüt edilen dosyayı teslim al.
  6. Tamamlayın.

Yamalamayı denedim ve durumum bunun için çok çirkindi. Kısacası şöyle görünecektir:

Çalışma Dalı: Bir Deney Dalı: B (katlamak istediğim değişiklikleri içeren file.txt dosyasını içeriyor.)

git checkout A

A temelli yeni şube oluşturun:

git checkout -b tempAB

B'yi tempAB ile birleştir

git merge B

Birleştirmenin sha1 karmasını kopyalayın:

git log

commit 8dad944210dfb901695975886737dc35614fa94e
Merge: ea3aec1 0f76e61
Author: matthewe <matthewe@matthewe.com>
Date:   Wed Oct 3 15:13:24 2012 -0700

Merge branch 'B' into tempAB

Çalışma şubenizi kontrol edin:

git checkout A

Düzeltilen dosyanızı kontrol edin:

git checkout 7e65b5a52e5f8b1979d75dffbbe4f7ee7dad5017 file.txt

Ve işte buna sahip olmalısınız. Sonucunu taahhüt et.


3
Yani tüm bunları tek bir dosyayı birleştirmek için mi yapmalıyız? Dosyayı kopyalayıp diğer şubeye yapıştırmak daha kolay olmaz mıydı
Robin

1
@Robin muhtemelen hayır, çünkü birleştirme dosyada A ve B dalı arasında farklılık gösteren değişiklikleri koruduğu için, dosyayı kopyalamak çalışma dalı A ile B'den getirmek istemeyeceğiniz ek farkların üzerine yazacaktır. bu girişimler / düzenlemeler. örneğin, şüpheli başka yollarla başlamaktan Auzaklaşmıştır B. Kopyalama bu farklılıkların üzerine yazılacaktır.
19:29

14

Bu git'in dahili diftoolünü kullanır. Belki küçük bir iş ama doğrudan ileri.

#First checkout the branch you want to merge into
git checkout <branch_to_merge_into>

#Then checkout the file from the branch you want to merge from
git checkout <branch_to_merge_from> -- <file> 

#Then you have to unstage that file to be able to use difftool
git reset HEAD <file> 

#Now use difftool to chose which lines to keep. Click on the mergebutton in difftool
git difftool

#Save the file in difftool and you should be done.

1
--(Boş bağımsız değişken etiketi) kullanımını açıklığa kavuşturmak için git checkout docs: ARGUMENT DISAMBIGUATION şunu söylüyor: " git checkout -- <pathspec>bu yolları dizinden çıkarmak istiyorsanız kullanın." Bunun nedeni, aynı ada sahip bir dalınız ve bir dosya / yolunuz olabilir. Bu gibi durumlarda, sizden her ikisi de mevcut olduğunda dalın veya yolun kontrol edilmesi gerekip gerekmediğini netleştirmek istemiyorsanız, git varsayılan olarak dalı ödemeyi seçer. Bununla birlikte, --önekliler git yerine dosya / yolu kullanıma alır.
SherylHohman

8

Bu yaklaşımı basit ve kullanışlı buldum: Başka bir şubeden belirli dosyaları "birleştirmek"

Anlaşıldığı gibi, çok çalışıyoruz. İyi arkadaşımız git checkout, iş için doğru araçtır.

git checkout source_branch <paths>...

Git checkout'a A özellik dalının adını ve ana dalımıza eklemek istediğimiz belirli dosyaların yollarını verebiliriz.

Daha fazla anlayış için lütfen makalenin tamamını okuyun


2
Bu dosyaların üzerine yazar, onları birleştirmez
Alex G

Sizin için, ne yaptığınıza ve neyi başarmaya çalıştığınıza bağlıdır. Buradaki fikir B dalı A'nın çatalıdır, B'deki 4 dosyayı değiştirirsiniz, ancak B'den A'ya yalnızca 2'yi birleştirmek istersiniz. Düzenli birleştirme 4'ün tümünü birleştirir, burada seçebilirsiniz. Bu, geçersiz kılınmış gibi görünebilir çünkü B aslında daha yeni dosyalar içerir. Deneyiminizi bazı kanıtlarla desteklemeniz gerekir.
Pawel Cioch

Üzerine yazıldığını kabul ediyorum. bence o komuttaki -pseçeneği kullanmak istedin. Daha sonra, çalışma ağacı dosyanızda, yama değişikliklerinden önce maalesef, kontrolünüzden daldan ayrılmış olan bölümlerin üzerine yazılır.
19:40

Fikir 2009'dan beri, git yeni sürümü farklı davranıyor ve ihtiyaçları -p ya da başka bir şey ama geri gönderirken benim için çalışıyordu, ama yine de belki dosyaların geçersiz kılınması umurumda değildi en son sürüm ihtiyacım olan
şeydi


3

Aşağıdaki komut (1) doğru dalın dosyasını karşılaştırır, ana (2) etkileşimli olarak hangi değişikliklerin uygulanacağını sorar.

git checkout --patch master


0

Düzenlemem reddedildi, bu yüzden uzak bir daldan birleştirme değişikliklerini nasıl ele alacağımı ekliyorum.

Bunu yanlış birleştirme işleminden sonra yapmanız gerekirse, şöyle bir şey yapabilirsiniz:

# If you did a git pull and it broke something, do this first
# Find the one before the merge, copy the SHA1
git reflog
git reset --hard <sha1>

# Get remote updates but DONT auto merge it
git fetch github 

# Checkout to your mainline so your branch is correct.
git checkout develop 

# Make a new branch where you'll be applying matches
git checkout -b manual-merge-github-develop

# Apply your patches
git checkout --patch github/develop path/to/file
...

# Merge changes back in
git checkout develop
git merge manual-merge-github-develop # optionally add --no-ff

# You'll probably have to
git push -f # make sure you know what you're doing.

0

Mevcut dalın B olduğunu varsayarsak:

$ git diff A <file-path> > patch.tmp
$ git apply patch.tmp -R

Bunun yalnızca yerel dosyadaki değişiklikler için geçerli olduğunu unutmayın. Daha sonra taahhütte bulunman gerekecek.


Benim için bu bir üretirerror: <file-path>: already exists in working directory
kontur

Geçerli dizinde belirli bir dosya veya dosya yolu kullanmalısınız. Ben kullanacağımgit diff Branch_A <file-path, filename> -- hash_commit > file_name.temp
R.Chatsiri

0

Birleştirmek için dosyanın eski sürümüne göz atabilir, farklı bir ad altında kaydedebilir, ardından iki dosyada birleştirme aracınız ne olursa olsun çalıştırabilirsiniz.

Örneğin.

git show B:src/common/store.ts > /tmp/store.ts (burada B, şube adı / taahhüt / etikettir)

meld src/common/store.ts /tmp/store.ts


0

Olarak yapacağım

git format-patch branch_old..branch_new file

bu dosya için bir yama oluşturur.

Hedef branch_old'a yama uygula

git am blahblah.patch


Ekstra güvenlik için yamaya kolayca bakabilir misiniz?
XavierStuvw
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.