Değişiklikleri çekildikten sonra yeni bir şubeye taşıma (ancak itme)


460

Oldukça fazla bir iş yaptım ("Şubeniz 37 komisyon tarafından 'menşe / usta' dan önde.") master. Bu taahhütler sadece yerel makinemde var ve itilmiyor origin, ancak durum diğer geliştiricilerin ittiği origin/masterve bu değişiklikleri çektiğim için biraz karmaşık .

37 yerel taahhütümü geriye dönük olarak yeni bir şubeye nasıl taşırım? Dokümanlara dayanarak, bunu yapıyor git rebase --onto my-new-branch masterveya ...origin/masteryapmalı gibi görünüyor , ancak her ikisi de bana sadece "ölümcül: Tek bir düzeltme gerekli" hatasını veriyor. man git-rebasebir düzeltme sağlamakla ilgili hiçbir şey söylemez rebaseve örnekleri bunu yapmaz, bu yüzden bu hatayı nasıl çözeceğimi bilmiyorum.

Bu olduğunu (Not değil yinelenen mevcut Move, Git yeni dalına uncommited iş veya başka Git şube içine benim yerel kaydedilmemiş değişiklikleri birleştirmek nasıl? Bu sorular yerel çalışma ağacında kararsız değişiklikler yapmadıysanız değişiklikler ile başa kadar yerel olarak taahhüt edilmiştir.)


Bu çözümü inceleyin . Kolay ve temiz görünüyor.
Tony

Bu çözümü inceleyin . Kolay ve temiz görünüyor.
Tony

Yanıtlar:


518

Taahhütlerinizi henüz başka bir yere itmediniz ve şubenizin tarihini daha sonra yeniden yazmakta özgür olduğunuz için bu iyi olmalı origin/master. İlk önce güncel git fetch originolduğundan emin olmak origin/masteriçin bir koşmak . Şu anda açık olduğunuzu varsayarsak, şunları masteryapabilmeniz gerekir:

git rebase origin/master

... hangi olmayan yere kaydedilmesini tüm yeniden görüntüler origin/masterüzerine origin/master. Rebase'in varsayılan eylemi, birleştirme taahhütlerini (örn. git pullMuhtemelen sizin tanıttığınız) yok saymaktır ve sadece taahhütlerinizin her biri tarafından sunulan yamayı uygulamaya çalışacaktır origin/master. (Yol boyunca bazı çakışmaları çözmeniz gerekebilir.) Ardından, sonuca göre yeni dalınızı oluşturabilirsiniz:

git branch new-work

... ve ardından mastersırtınızı şu konuma sıfırlayın origin/master:

# Use with care - make sure "git status" is clean and you're still on master:
git reset --hard origin/master

İle manipüle dalların bu tür yaparken git branch, git resetvb Birlikte grafik işlemek de yararlı sıkça da göz atmak gitk --allveya benzer bir aracı sadece tüm farklı hakemler nereye yönlendirildiğini anlıyorum kontrol etmek.

Alternatif olarak, ustanızın ilk sırada bulunduğu yere göre bir konu dalı oluşturmuş olabilirsiniz ( git branch new-work-including-merges) ve sonra masteryukarıdaki gibi sıfırlayabilirsiniz . Ancak, konu dalınız birleştirme içereceğinden origin/masterve değişikliklerinizi henüz itmediyseniz, geçmişin daha düzenli olması için bir yeniden taban önermenizi öneririm. (Ayrıca, sonunda konu dalınızı ana kopyayla birleştirdiğinizde, değişiklikler daha açık olacaktır.)


8
@Olie: Hayır, sorudaki ve cevabın en üstünde belirlediğim varsayımlar altında cevap doğrudur. Ayrı bir yeni branşta olması gereken taahhütler zaten var master; Rebase yeniden yazar masteryeni onaylatabilirsiniz üstünde doğrusal böylece dalı origin/mastersonra, git branch new-workbir oluşturur new-workucunda şube işaret master(güncel dalı) olmadan geçerli dalı anahtarlama new-work. Şimdi new-worktüm yeni taahhütleri içeriyor. Ardından sıfırlama, geçerli dalı (hareketsiz görüntü master) geri taşır origin/master.
Mark Longair

1
@Quintesse: İşinizi kaybettiyseniz çok üzgünüm, ama eminim bu cevap orijinal soru soran kişi tarafından açıklanan durum için doğru. (Olie'nin sözlerini umarım netleştirerek yanıtladım.) Her neyse, işinizi geri almanıza yardımcı olması durumunda, çalışmanız son birkaç gün içinde yapıldıysa (bu soru ve cevaptaki varsayımlardan biri) ) git reflog ile kolayca alabilirsiniz.
Mark Longair

5
@Olie: belki de daha iyi bir açıklama yolu: git'teki dallar, belirli bir taahhüde işaret eden etiketler gibidir; bu daldayken oluşturursanız otomatik olarak yeni taahhütlere taşınırlar veya git resetçeşitli yollarla taşınabilirler . git branch new-workSadece "(usta bu durumda olan) benim şimdiki dal üzerinde kalırken bu taahhüt Şube işaret oluşturmak" diyor. Bu yüzden , taahhütleri master'dan yeni şubeye taşıyan bir komuta sahip olmanıza gerek yok - sadece yeni bir şube oluşturuyorsunuz ve master'ı sıfırladığınızda yeni şube masterın olduğu yerde bırakılıyor
Mark Longair

1
partiye biraz geç ama @Olie, sadece yeni dalda git durumunun ustanın önünde taahhütleri göstermemesi, aslında orada olmadıkları anlamına gelmez (bu yüzden endişelendiğinizi varsayarak). Yeni şubeyi başlangıç ​​noktasına doğru itmeye çalışın: taahhütlerin orada olduğunu göreceksiniz
Félix Gagnon-Grenier

2
@ FélixGagnon-Grenier, "geç" için endişelenme - her zaman eski soruları arayan insanlar vardır ve her açıklama yardımcı olur. Teşekkürler! :)
Olie

148

Düşük bir taahhüdünüz varsa ve bunların bir mega taahhütte birleştirilip birleştirilmeyeceğini umursamıyorsanız, bu iyi çalışır ve yapmak kadar korkutucu değildir git rebase:

dosyaları ayıklama (1 yerine taahhütlerin sayısı #)

git reset --soft HEAD~1

yeni bir şube oluştur

git checkout -b NewBranchName

değişiklikleri ekle

git add -A

taahhütte bulunmak

git commit -m "Whatever"

5
Anlaması kolay bir grafik göstermek için lütfen kullanın git log --all --decorate --oneline --graph.
EliuX

Hey @EliuX - Buradaki alaka düzeyini kaçırıyorum. Genişleyebilir misiniz?
18'de Stachu

Bu, yaptığınız şeyde istenen sonucu
alıp

4
Teşekkür ederim!! Bu çok basit bir çözüm ve mükemmel çalıştı !!
Chris Sim

91

Ben de aynı sorunla karşılaştım. Paylaşmayı sevdiğim en kolay çözümü buldum.

1) Yaptığınız değişikliklerle yeni şube oluşturun.

git checkout -b mybranch

2) (İsteğe bağlı) Uzak sunucuda yeni şube kodunu itin.

git push origin mybranch

3) Ana şubeye geri ödeme yapın.

git checkout master

4) Ana şube kodunu uzak sunucu ile sıfırlayın ve yerel taahhüdü kaldırın.

git reset --hard origin/master

10
Bu gerçekten en kolay yol
dhilt

4
2. adımı dışarıda bırakabilirsiniz. En iyi yanıttan bu yana git'in değiştiğini ve bu prosedüre daha önce izin verilmediğini varsayıyorum.
Sebastian

Bence en iyi cevap bu.
Macindows

1
Bu cevabın en üste taşınması gerekiyor. Teşekkür ederim.
amit

27

Branş1'in - taahhüt edilen değişikliklerle branş2 olduğunu varsayalım -

git fetch && git checkout branch1
git log

taşımanız gereken kesin kimlikleri seçin

git fetch && git checkout branch2
git cherry-pick commit_id_first..commit_id_last
git push

Şimdi ilk şubeden unpushed taahhütlerini geri alın

git fetch && git checkout branch1
git reset --soft HEAD~1

5
Kiraz toplama gerçekten en iyi "tek bir taahhüt kopyala / taşı" komutu, esp. tarih sizin amaçlarınız için bagaj olduğunda.
John Neuhaus

Bu şu ana kadar sorunun en uygun cevabı. Komuta için teşekkürler!
Farah

son yorumunuzu güncelleyebilir misiniz? 1 veya n itilmemiş taahhütlerin sayısıdır? Bu hala bu soru için gerçekten iyi bir çözüm.
chAlexey

9

Alternatif olarak, yanlış şubeye başvurduktan hemen sonra şu adımları gerçekleştirin:

  1. git log
  2. git diff {previous to last commit} {latest commit} > your_changes.patch
  3. git reset --hard origin/{your current branch}
  4. git checkout -b {new branch}
  5. git apply your_changes.patch

Birinci ve ikinci adımlar için daha basit bir yaklaşım olduğunu hayal edebiliyorum.


6

Ne dersin:

  1. Mevcut HEAD'den şube.
  2. Yeni şubenizde değil , usta olduğunuzdan emin olun .
  3. git reset değişiklik yapmaya başlamadan önceki son işleme geri dönün.
  4. git pull sadece sıfırlama ile attığınız uzaktan değişiklikleri yeniden çekmek için.

Yoksa şubeyi yeniden birleştirmeye çalıştığınızda patlayacak mı?


2
Ah, bu temelde yukarıdaki @ Mark-Longair tarafından açıklanan B seçeneği
Tim Keating

2

İşte çok daha basit bir yol:

  1. Yeni bir şube oluştur

  2. Yeni şubenizde aşağıdakileri yapın git merge master: bu, taahhütlü (itilmemiş) değişikliklerinizi yeni şubenizde birleştirir

  3. Size yerel ana dal sil git branch -D masterKullan -Dyerine -dsen dalı silmek zorlamak istiyorum çünkü.

  4. Sadece bir yapmak git fetchana şubeniz ve yapmak git pullsize ekipleri son kod sağlamak için ana şubeniz.


1

Kullandığım daha basit bir yaklaşım (4 taahhüdü taşımak istediğinizi varsayarsak):

git format-patch HEAD~4

(4 .patchdosya için son komutu yürüttüğünüz dizine bakın )

git reset HEAD~4 --hard

git checkout -b tmp/my-new-branch

Sonra:

git apply /path/to/patch.patch

İstediğiniz sırayla.


0
  1. Kaynaklarınızın yeni kopyasını kontrol edin

    git clone ........

  2. Şubeyi istenen konumdan yapın

    git checkout {position} git checkout -b {branch-name}

  3. Uzak depo ekle

    git remote add shared ../{original sources location}.git

  4. Uzak kaynakları edinin

    git fetch shared

  5. İstenen şubeyi kontrol edin

    git checkout {branch-name}

  6. Kaynakları birleştir

    git merge shared/{original branch from shared repository}


0

Benim için en iyi yol buydu:

  1. Değişiklikleri kontrol edin ve çakışmaları birleştirin git fetch
  2. Yeni bir şube oluşturun git branch my-changesve uzaktan kumandaya itin
  3. Yeni oluşturulan dala yukarı akış değiştirme git master -u upstream-branch remotes/origin/my-changes
  4. Taahhütlerinizi yeni yukarı yönlü şubeye itin.
  5. Önceki yukarı akışa geri dön git branch master --set-upstream-to remotes/origin/master
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.