Şube tabanını değiştir


145

Bunun gibi bir ağacım var:

(commit 1) - master
                \-- (commit 2) - (commit 3) - demo
                                                \-- (commit 4) - (commit 5) - PRO

ve PRO şubesini uzmanlaşmak için taşımalıyım

(commit 1) - master
                |-- (commit 2) - (commit 3) - demo
                \-- (commit 4) - (commit 5) - PRO

git rebase masterPRO şubesinden bir denedim ama hiçbir şey olmuyor.

Açıklığa kavuşturmak için : Master'da çalışıyordum ve sonra bir ürün demosu ( git checkout -b demove bazı taahhütler) yapmam gerekiyordu . Sonra, yanlışlıkla, demodan başka bir şube oluşturuyorum ( git checkout -b PROve bazı taahhütler) ve şimdi PRO şubesini ustalaşmak ve demoyu sağlam bırakmak için taşımam gerekiyor. Sonunda, hem demo hem de PRO ustadan asılı kalacak.


Yanıtlar:


285

Bunun için kullanın --onto:

git rebase --onto newBase oldBase feature/branch

Davanız göz önüne alındığında:

git checkout PRO # Just to be clear which branch to be on.
git rebase --onto master demo PRO

Temel olarak, sonra gelen tüm kaydedilmesini almak demoiçin yukarı PROve üzerine onları rebase masterişlemek.


Durum tam tersi ise gidilecek yol bu mu? == İkinci şubenin ustasından -b'yi kontrol ediyorum, ancak ilk şubeden yapmak istedim. Ben de yaptım git rebase --onto first-branch second-branch second-branchama sözdizimini anlamadım
Fla

1
@Fla bu durumda olurgit rebase --onto first-branch master second-branch
nVitius

9
Bunu okumak kılavuzu üzerinde --ontove onlar bana yardımcı yazdı nasılgit rebase --onto newBase oldBase feature/branch
Gabe

@PhilipRego Bu yanlış. benim örneğimde origin/newBaseolduğu gibi bir şubenin adıdır newBase. Yerel deponuzda ( newBase) veya remote ( origin/newBase) üzerinde var olan bir şubeye yeniden adlandırma yapıp yapmamanıza bağlı olacaktır .
loganfsmyth

@PhilipRego Bunlar bağımsız şeyler değil. newBaseyerel bir şubenin origin/newBaseadıdır ve uzak bir şubenin adıdır. Hangisini istediğiniz, neye geri döndüğünüze bağlıdır. Birinin işe yarayıp yaramaması değil, farklı şeylere yeniden başlamaları. Orijinal soru hiçbir zaman uzaktan kumandalardan bahsetmez, bu nedenle benim örneğimde uzaktan kumanda kullanmak sorulan soruyla eşleşmez.
loganfsmyth

22

Olabildiğim kadar genel olmaya çalışacağım. Öncelikle istediğiniz şubede olduğunuzdan emin olun:

git checkout current-branch

Sonra aşağıdaki komutu kullanın (burada new-base-branchyeni üssünüz olmasını istediğiniz current-base-branchdal ve mevcut üssünüz olan daldır.)

git rebase --onto new-base-branch current-base-branch

Çatışmalarınız yoksa, o zaman harika - işiniz bitti. Eğer yaparsanız (çoğu durumda), lütfen okumaya devam edin.

Anlaşmazlıklar ortaya çıkabilir ve bunları manuel olarak çözmeniz gerekecektir. Git şimdi current-branch, current-base-branchve new-base-branch. Arasında "3 yollu birleştirme" yapmaya çalışıyor . Kabaca git dahili olarak şu şekilde çalışacaktır:

  1. Git, ilk current-base-brancholarak new-base-branch. Çatışmalar olabilir; manuel olarak çözmeniz gerekecek. Bunu yaptıktan sonra genellikle git add .ve yaparsınız git rebase --continue. Bunun için yeni bir geçici taahhüt yaratacaktır temp-commit-hash.

  2. Bundan sonra, Git şimdi current-branchüstüne yeniden basacak temp-commit-hash. Başka anlaşmazlıklar olabilir ve bunları yine manuel olarak çözmeniz gerekecektir. Bitmiş sonra, tekrar devam git add .ve git rebase --continuebundan sonra başarılı bir rebased gelmiş, current-branchüstte new-base-branch.


Not: Ortalığı karıştırmaya başlarsanız, yeniden git rebase --abortödeme işlemi sırasında istediğiniz zaman yapabilir ve başlangıç ​​noktasına geri dönebilirsiniz.


rebase": Geçersiz memba 'akım-baz-dal' ölümcül" yayınlanmıştır olarak komut sadece bana verir. Ayrıca, neden GIT'e mevcut şubenin mevcut ana dalının ne olduğunu söylemek bile gerekli - bunu zaten bilmesi gerekmiyor mu?
Matt Arnold

22

İçin Ödeme PROşubesi, Kopya en eski ( commit4 ) ve son ( commit5 ) bu dalın karmaları işlemek ve başka bir yere yapıştırın:

$ git checkout PRO
$ git log            # see the commit history
# copy the oldest & latest commit-hash 

PROŞubeyi silin (yalnızca güvenlik için bir yedek tutun). Şunlardan yeni bir PROşube oluşturun ve satın alın master:

$ git branch PRO.bac    # create a new branch PRO.bac = PRO as backup

$ git checkout master
$ git branch -D PRO     # delete the local PRO branch
$ git checkout -b PRO   # create and checkout to a new 'PRO' branch from 'master'

Al (Önceki PROşubenin taahhüt aralığını yeni PROşubeye kirazla seçin ) :

$ git cherry-pick commit4^..commit5   # cherry-pick range of commits
# note the '^' after commit4

Şimdi, her şey yolundaysa, o zaman zorla (-f) zorla dallanıp remote PROyerel PRO.bacdalı silin :

$ git log                  # check the commit history

$ git push -f origin HEAD  # replace the remote PRO by local PRO branch history
# git branch -D PRO.bac    # delete local PRO.bac branch

1

Dalları silmeyi ve yeniden oluşturmayı engellemenin yanı sıra dalları değiştirme ihtiyacını ortadan kaldıran sıfırlama ve saklamayı kullanarak biraz farklı bir yaklaşımım vardı:

$ git checkout PRO
$ git reset commit4 # This will set PROs HEAD to be at commit 4, and leave the modified commit 5 files in ur working index
$ git stash save -m "Commit message"
$ git reset commit 3
$ git stash save -m "Commit message"
$ git reset master --hard
$ git stash pop
$ git stash pop
$ git push --force # force if its already been push remotely

Şubeyi kesinleştirme temelinde yeniden başlatarak, temelde o dalların geçmişini bir seferde bir kaydetme olarak geri sararsınız.


4. satırda "commit" ve "3" arasındaki boşluğu kaldırmanız gerekir mi?
Alexis Wilke
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.