Tek bir Git kaydını yeniden başlatın


116

Bir şubeden başka bir şubeye tek bir taahhüdü yeniden sunmanın bir yolu var mı?

Bu şube yapısına sahibim:

-- -- -- -- -- (Master)
            \
              -- -- -- -- -- XX (Feature-branch)

Tek yapmak istediğim, son taahhüdü Feature-branchana üzerine yeniden temel almak ve bir kaydı geri almak Feature-branch.

-- -- -- -- -- XX (Master)
            \
              -- -- -- -- -- (Feature-branch)

Bunu nasıl yaparım?


3
Herhangi bir sayıda taahhüdü yeniden ödeyebiliyorsanız, neden tek bir taahhüdü yeniden ödemeyi soruyorsunuz? SO'da soru sorabilseydim, yeniden ödeme (tek bir taahhüt) ile kiraz toplama arasındaki farkın ne olduğunu sorardım.
Val

9
Çünkü kiraz toplamanın var olduğunu bilmiyordum ve "Dalda Faff", "Farklı dalda düzeltme talebi al", "düzelt", "Yanlış şubeye işle", "D'OH!" Yeter ki soruyu sormak faydalı oldu.
Kevin Meyer

Yanıtlar:


116

XX'i seçip ustalaşabilirsiniz.

git checkout master
git cherry-pick <commit ID of XX>

Ve git reset ile özellik dalından son yürütmeyi kaldırın.

git checkout Feature-branch
git reset --hard HEAD^

64
Özel olarak 'git rebase ...' olarak adlandırılan bir soru, tamamen farklı bir kavram olan ve bazen kirli olarak kabul edilen bir kiraz toplama içermektense kabul edilen yanıta nasıl sahip olabilir?
Bondax

1
Bunun alakalı olup olmadığından emin değilim, ancak yeniden temel almak istediğim işlemde bazı dosyalar taşındı ve cherry-pickbunların eski konumdan silinmiş ve yeni konumda oluşturulmuş gibi görünmesini sağladı. Sanırım rebase bunu halledebilirdi, ancak şimdiye kadar yukarı akışa geçtim, bu yüzden bunu test edemem. Her durumda, benzer bir durumunuz varsa dikkatli olun.
waldyrious

Not: değişiklikleri size itmek için Feature-branch başlangıç için yapmanız gerekecek, git push -f origin Feature-branchçünkü Feature-branchartık origin/Feature-branch.
jojo

1
Bu çözüm ile arasındaki pratik fark nedir? CharlesB'nin ?
Lii

97
git rebase --onto master branch~1 branch 

Bu, "ana dalın ucunda şubeden önceki son ile şube (yani, XX kesinleştirme) arasındaki taahhüt aralığını yeniden tabanla" diyor

Bu işlem branchipucu işleme üzerine taşındıktan sonra XX, onu geri almak istersiniz.

git checkout branch
git reset --hard branch@{1}^

"Dalın ipucunu önceki durumundan önce yürütmeye sıfırla" diyor

Yani kiraz toplaması daha basit bir çözüm ...


5
Bu benim için işe yaramıyor gibi görünüyor, XX'den önce taahhütleri kaybettim ve şube tek bir commit ile master için yeniden borçlandırıldı, ancak daha --ontoönce hiç kullanmadım, bu yüzden yanlış bir şeyler yapıyor olabilirim. BTW OP geri ödeme dedi, ancak bir seçim yapmak istiyor gibi görünüyor.
2013

1
benim hatam, yeniden temelleme gerçekten şubeyi ana bilgisayarda hareket ettiriyor, sıfırlanması gerekiyor
CharlesB

1
Bu çözüm ile tek başına bir çözüm arasındaki pratik fark nedir ?
Lii

1
@Lii tek görebildiğim 4 yerine 3 adım kullanması
CharlesB 4'17

52

Aslında yapmak oldukça basit. Çözüm, etkileşimli bir yeniden ödeme yapmak ve yeniden ödemeye dahil etmek istemediğiniz tüm taahhütleri "düşürmektir".

git rebase -i <target_branch> nerede target_branch temel almak istediğiniz şube

Ardından, açılan dosyayı ve pickistediğiniz commit'leri ve drop(veya dkısaca) getirmek istemediğiniz tüm kayıtları düzenleyeceksiniz .


6
IMO çok daha iyi bir çözüm ve aslında soruyu ele alıyor.
GabrielOshiro

Ne kadar genel, sezgisel ve kısa olduğu göz önüne alındığında, bu kabul edilen çözüm olmalıdır.
Pablo Arias

1

@Charles yanıtı doğru. Her neyse, bunu pek çok kez kullandım, en önemlisi bir projedeki belirli yapılandırmayı yeniden başlatmak için

  * a8f9182 (HEAD -> üretim) üretim yapılandırması
  | * daa18b7 (ön) üretim öncesi yapılandırması
  | /  
  | * d365f5f (yerel) yerel yapılandırma
  | /  
  * 27d2835 (dev) dünyayı kurtaracak harika yeni özellik
* | 56d2467 (ana) proje için sıkıcı son teknoloji
| /

bunun için yeni bir komut oluşturduğumu:

$ kedi ~ / bin / git-rebaseshot 
COMMIT = $ 1
DEST = $ {2: -Merkez}
git rebase $ {COMMIT} ^ $ {COMMIT} - $ DEST'e

normalde bu komut için dal adlarını otomatik olarak tamamlamak istersiniz, bu nedenle bu işlevi kaynak olarak ekleyin (.bashrc veya .profile ekleyerek):

_git_rebaseshot () 
{ 
    __gitcomp_nl "$ (__ git_refs)"
}

git autocomplete, onu arayacak

bu komutu şu şekilde kullanabilirsiniz:

# rebase config on prepro on actual HEAD
$ git rebaseshot prepro 
# rebase config on local onto dev
$ git rebaseshot local dev
# rebase production config on master
$ git rebaseshot pro master

Özellikleri doğru şekilde böldüğünüzde olasılıklar sonsuzdur.

* a8f9182 (HEAD -> postgres) BBDD yapılandırması
* a8f9182 (yerel) yerel yapılandırma
* a8f9182 (hata ayıklama) günlük düzeyi yapılandırması
* a8f9182 (dev) yeni özellik
|

Sanırım insanların yapmaktan hoşlandığı yorgan budur .

bu komut, sağladığınız sha / ref ile yine de çalışacaktır:

$ git rebaseshot <Feature branch> master
$ git rebaseshot <commit of XX> master

//, Bunu eylem halinde görebileceğimiz herhangi bir projeye bağlantı verebilir misiniz?
Nathan Basanese

Doğası gereği, rebaseshot için mevcut şubeler yerel repo dışında taahhüt edilmez. Master'ın üstünde birkaç dal oluşturun (günlük seviyesi, veritabanı bağlantısı, konfigürasyon) ve aralarında komut kullanın. Etkisini görmek açık.
albfan

//, bazı sorunlarla karşılaştım. Tekrar deneyeceğim.
Nathan Basanese

0

İşte başka bir seçenek:

  1. Özellik dalının bir kopyasını içeren bir uzaktan kumandanız olduğundan emin olun
  2. Yerel özellik dalını silin
  3. Ana birimden yeni sildiğiniz eski özellik dalıyla aynı ada sahip yeni bir dal oluşturun ve kullanıma alın
  4. kiraz-istediğiniz özellik dalının uzak kopyasından bir kaydı seçin.

Komutlar şöyle görünür:

git checkout Feature-branch
git push -u origin HEAD
git checkout master
git branch -D Feature-branch
git checkout -b Feature-branch
git cherry-pick HASH-OF-XX

Bu bir geri ödeme komutu hayır değil, ama ruhen bir geri ödeme.

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.