Başka bir git deposundan bir taahhüt seçmek mümkün mü?


728

İlk hiçbir şey bilmeyen başka bir git deposundan bir taahhüt gerektiren bir git deposu ile çalışıyorum.

Genellikle ben HEAD@{x}reflog içinde kullanarak kiraz pick- up, ama bu .gitbu reflog giriş (farklı fiziksel dizin) hiçbir şey bilmiyor, bu nasıl kiraz-seçim, ya da ben?

Kullanıyorum git-svn. Benim ilk şube kullanıyor git-svnait trunkSubversion repo ve bir sonraki şube kullanıyor git-svnSubversion dala.


2
Ben Lee'nin bu soruya bir ödül açması için verdiği sebep budur : "Ödülün yerine doğru cevaba, kabul edilen cevaba vereceğim. Bunu yapmak için sadece 24 saat beklemem gerek." Ancak, bunlardan hangisinin "doğru cevap" olması gerektiğini ve kabul edilen cevabın neden "doğru" olmadığını anlamıyorum.

1
Sorunun doğasının ne olduğu belli değil. Bu farklı depolar, hiç değilse nasıl ilişkilidir? Biri başka bir çatal mı? Yoksa aslında tamamen ayrı ve ilgisiz iki proje mi?

@ Cupcake, kabul edilen cevap iyi ve açıkça OP'ye yardımcı oldu, bu yüzden kabul edilmelidir. "Doğru" derken gerçekten "benim için doğru" (ve yorumları değerlendirerek, diğer bazı insanlar için de doğru) demek istedim. Sana ödül verdiğim şeyi, kabul edilen cevap kadar haklı olduğunu düşündüm.
Ben Lee

Yanıtlar:


559

Diğer havuzu uzaktan kumanda olarak eklemeniz ve ardından değişikliklerini almanız gerekir. Oradan taahhüdü görüyorsunuz ve kiraz toplayabilirsiniz.

Bunun gibi:

git remote add other https://example.link/repository.git
git fetch other

Artık basitçe yapmanız gereken tüm bilgilere sahipsiniz git cherry-pick.

Uzaktan kumandalarla çalışma hakkında daha fazla bilgi için: https://git-scm.com/book/en/v2/Git-Basics-Working-with-Remotes


1
Git-svn kullanıyorsam ne olur? benim ilk
şubem bagajın

1
Subversion deposunu ilk kez klonladığınızda, sadece gövdeyi değil , tüm deposu klonladığınızdan emin olun . --stdlayoutSubversion'da standart gövde / dallar / etiketler düzenini kullanıyorsanız git-svn seçeneğini kullandığınızdan da emin olun . Sonra Subversion dalı bir uzak git dalı olacaktır.
wilhelmtell

33
Github kullanıyorsanız, yama URL'sine .patch ekleyip ardından uygulayarak yamayı çekebilirsiniz git am < d821j8djd2dj812.patch. GH dışında, benzer kavramlar aşağıdaki alternatif cevapta atıfta bulunularak yapılabilir.
radicand

2
@radicand "alternatif" olan aşağıdaki cevap nedir? Lütfen bağlantı verin.

7
Başka bir repodan kiraz almak için ayrıntılı adımlar: coderwall.com/p/sgpksw/git-cherry-pick-from-another-repository
T. Kim Nguyen

855

Yanıt, verildiği gibi, format yamasını kullanmaktır, ancak soru başka bir klasörden nasıl kiraz seçileceği olduğundan, işte bunu yapmak için bir kod parçası:

$ git --git-dir=../<some_other_repo>/.git \
format-patch -k -1 --stdout <commit SHA> | \
git am -3 -k

( @cong ma'dan açıklama )

git format-patchKomut bir yama oluşturur some_other_repos onun SHA belirtilen tamamlama'( -1tek tek tek başına tamamlama). Bu yama, git amyamayı yerel olarak uygulayan boruya bağlanır ( -3yama temiz bir şekilde uygulanamazsa üç yönlü birleştirmeyi denemek anlamına gelir). Umarım açıklar.


18
Bu nokta, ama herkes bunu genişletmek harika olurdu - tam olarak neler olduğunu (özellikle bu bayraklarla) bir döküm inanılmaz faydalı olacaktır.
Nick F

46
@NickF, git format-patchkomut some_other_repoSHA tarafından belirtilen taahhüdünden bir yama oluşturur ( -1tek bir taahhüt için). Bu yama, git amyamayı yerel olarak uygulayan boruya bağlanır ( -3yama temiz bir şekilde uygulanamazsa üç yönlü birleştirmeyi denemek anlamına gelir). Umarım açıklar.
Cong Ma

3
hata: düzeltme eki başarısız oldu: somefile.cs: 85 hata: somefile.cs: düzeltme eki uygulanmıyor Düzeltme ekinizi el ile düzenlediniz mi? Endeksinde kaydedilmiş lekeler için geçerli değildir. Üç yönlü birleşmeye geri dönemez. Düzeltme eki 0001 Eklenen GUI parçalarında başarısız oldu. Başarısız olan düzeltme ekinin kopyası şu konumda bulunur: <some_other_repo> /.git/rebase-apply/patch Bu sorunu çözdüğünüzde, "git am --continue" komutunu çalıştırın. Bu yamayı atlamayı tercih ederseniz, onun yerine "git am --skip" komutunu çalıştırın. Özgün dalı geri yüklemek ve yamayı durdurmak için "git am --abort" komutunu çalıştırın.
Tom

8
@Tom kullanmayı deneyin --ignore-whitespace. Tam komut: git --git-dir=../<some_other_repo>/.git format-patch -k -1 --stdout <commit SHA> | git am -3 -k --ignore-whitespace
Jake Graham Arnold

7
@BoomShadow Çünkü çok daha basit. Uzaktan kumandayı eklemek ve getirmek diğer repodaki tüm değişiklikleri getirir. Bu komut satırı tek seferlik bir işlemdir.
Jonathon Reinhart

152

İşte uzaktan getirme-birleştirme örneği.

cd /home/you/projectA
git remote add projectB /home/you/projectB
git fetch projectB

O zaman yapabilirsin:

git cherry-pick <first_commit>..<last_commit>

hatta tüm şubeyi bile birleştirebilirsiniz

git merge projectB/master

54
git merge projectB/master çok, çok yanlış bir tek gelen değişiklikler taahhüt uygulayarak değil çünkü (a kiraz almak gibi olur), aslında birleştirilmesi ediyoruz tüm değişimlere deprojectB/masterkendi yer almayan bumasterdalı.

4
Bu varsayımın asıl posterin niyeti olduğu varsayımıydı. Aksi takdirde, evet, bu onlar için doğru seçenek değildir.
Brian

5
İki depo ilişkili olduğunda bu mükemmel bir şekilde çalışır.
Ronny Ager-Wick

1
Git deposundan bir kopya oluşturdum (sadece orijinal repoyu bozmadan "oynamak için") ve kaynağı ile güncel tutmak için Brian'ın yanıtı tam olarak ihtiyacım olan şey, yani Cupcake, ben söylemek zorundayım, bu "yanlış" değil, başka bir kullanım durumu. Ancak potansiyel felakete dikkat çekmek sizin için güzel: D
ferrari2k

6
IMO bunun kabul edilen çözüm olması gerekir. Ayrıca, uzaktan kiraz toplama işlemini bitirdikten sonra uzaktan kumandayı silmek istiyorsanız, tuşunu kullanın git remote rm projectB. Ayrıca git tag -d tag-name, uzak depodan getirilen etiketleri kaldırmak için de kullanın . Uzak taahhütler artık geçmişinizde görünmeyecek ve budama bunları sonunda depodan kaldıracaktır.
ADTC

130

Bunu yapabilirsiniz, ancak iki adım gerektirir. Bunu nasıl yapacağınız aşağıda açıklanmıştır:

git fetch <remote-git-url> <branch> && git cherry-pick FETCH_HEAD

<remote-git-url>Kiraz seçimini yapmak istediğiniz depoya url veya yol ile değiştirin .

<branch>Uzak depodan kiraz almak istediğiniz dal veya etiket adıyla değiştirin .

FETCH_HEADDaldan bir git SHA ile değiştirebilirsiniz .

Güncellendi: @ pkalinow geri bildirimine göre değiştirildi.


8
Şube adıyla çalışır, ancak SHA ile çalışmaz. Eğer istersen bir yerine bunu kullanın, onun karma ile gösterilir taahhüt kiraz-almak: git fetch <repo-url> <branch> && git cherry-pick <sha>.
pkalinow

Teşekkürler. Bu, bu amaçla oluşturduğum bir depodan diğerine bir dizi taahhüt eklemek için ihtiyacım olan şeydi.
wojciii

Bu tam olarak ne farklı müşteriler (her biri kendi depo / çatal var) için kodumuzu birçok özel uygulama ile gerekli biz bizim temel / gövde içine belirli taahhütler almak için bir yol gerekiyordu. TEŞEKKÜRLER!
RedSands

Bu, depolarda tek seferlik bir kiraz seçiminin kabul edilen cevabı olmalıdır. Zaten yerel olan depolar arasında seçim yaparken her zaman kullanıyorum, uzak URL daha sonra sadece yerel bir dosya sistemi yoludur.
Amedee Van Gasse

61

Uzaktan ekleme, şube alma ve kiraz toplama işlemlerini ekleme adımları

# Cloning our fork
$ git clone git@github.com:ifad/rest-client.git

# Adding (as "endel") the repo from we want to cherry-pick
$ git remote add endel git://github.com/endel/rest-client.git

# Fetch their branches
$ git fetch endel

# List their commits
$ git log endel/master

# Cherry-pick the commit we need
$ git cherry-pick 97fedac

Kaynak: https://coderwall.com/p/sgpksw


17

Bkz . Git ile yama oluşturma ve uygulama . (Sorunuzun ifadesinden, bu diğer havuzun tamamen farklı bir kod tabanı için olduğunu varsaydım. Aynı kod tabanı için bir havuzsa, @CharlesB tarafından önerilen şekilde bir uzaktan kumanda olarak eklemeniz gerekir. kod tabanı, sanırım yine de bir uzaktan kumanda olarak ekleyebilirsiniz, ancak tüm dalı depoya almak istemeyebilirsiniz ...)


11

Aşağıdaki gibi tek bir satırda yapabilirsiniz. Kirazla toplanan değişikliğe ihtiyaç duyan git deposunda olduğunuzu ve şubeyi düzeltmek için check-out yaptığınızı umuyoruz.

git fetch ssh://git@stash.mycompany.com:7999/repo_to_get_it_from.git branchToPickFrom && git cherry-pick 02a197e9533
# 

git fetch [şube URL'si] [Kiraz seçiminden şube] && git kiraz seçim [taahhüt kimliği]


1
Şerefe, ssh://sadece bir parçaya ihtiyacı yoktu ,https://
Leo


1

Varsayarsak Aistediğiniz Repo olduğu gelen kiraz-seçin ve Bistediğiniz biridir ekleyerek bunu yapabilirsiniz için kiraz-almak </path/to/repo/A/>/.git/objectsiçin </path/to/repo/B>/.git/objects/info/alternates. alternatesMevcut değilse bu dosyaları oluşturun .

Bu, repo B'nin repo A'daki tüm git nesnelerine erişmesini sağlar ve kiraz seçiminin sizin için çalışmasını sağlar.


0

Benim durumum, ekibin zorladığı çıplak bir repo ve hemen yanında oturan bir klonum olmasıydı. Bir Makefile'deki bu satır kümesi benim için doğru çalışıyor:

git reset --hard
git remote update --prune
git pull --rebase --all
git cherry-pick -n remotes/origin/$(BRANCH)

Çıplak repo ustasını güncel tutarak, çıplak repoda yayınlanan önerilen bir değişikliği seçebiliriz. Ayrıca, konsolide gözden geçirme ve test için birden fazla braketi seçmenin (daha karmaşık) bir yoluna sahibiz.

Eğer "hiçbir şey bilmiyor", "uzaktan kumanda olarak kullanılamaz" anlamına gelirse, bu yardımcı olmaz, ancak bu SO sorusu bu iş akışını bulmak için uğraştığım için geldi, bu yüzden geri katkıda bulunacağımı düşündüm.


-n git belgelerine göre işlem yapılmaması anlamına geliyor ve taahhütte bulunmadan önce değişiklikleri görmek çok önemli.
Canbax

0

Belirli bir dosyaya ulaşıncaya kadar belirli bir dosya için birden fazla taahhüt seçmek istiyorsanız, aşağıdakileri kullanın.

# Directory from which to cherry-pick
GIT_DIR=...
# Pick changes only for this file
FILE_PATH=...
# Apply changes from this commit
FIST_COMMIT=master
# Apply changes until you reach this commit
LAST_COMMIT=...

for sha in $(git --git-dir=$GIT_DIR log --reverse --topo-order --format=%H $LAST_COMMIT_SHA..master -- $FILE_PATH ) ; do 
  git --git-dir=$GIT_DIR  format-patch -k -1 --stdout $sha -- $FILE_PATH | 
    git am -3 -k
done
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.