Hg: Git'in Rebase gibi bir rebase nasıl yapılır


207

Git'te bunu yapabilirim:

1. Yeni özellik üzerinde çalışmaya başlayın:
$ git co -b newfeature-123 # (bir yerel özellik geliştirme dalı)
birkaç işlem yap (M, N, O)

usta A --- B --- C
                \
yeni özellik-123 M --- N --- O

2. Akış yukarı master'dan yeni değişiklikler çekin:
$ git pull
(master ff-commits ile güncellendi)

master A - B - C - D - E - F
                \
yeni özellik-123 M --- N --- O

3. Yeni özelliğim için master'ı geri kazan 
en son yukarı akış değişikliklerine karşı geliştirilebilir:
(yeni özellik-123'ten)
$ git rebase master

master A - B - C - D - E - F
                            \
yeni özellik-123 M --- N --- O


Mercurial'da aynı şeyi nasıl yapacağımı bilmek istiyorum ve web'i bir cevap için ovuşturdum, ancak bulabildiğim en iyi şey: git rebase - bunu yapabilir

Bu bağlantı 2 örnek sağlar:
1. Bunu itiraf edeceğim: (örnekteki revizyonları kendi örneğimdekilerle değiştirerek)

hg up -CF  
hg şube - yeni özellik-123  
hg nakli -a -b newfeature-123 

çok kötü değil, ancak ön-öncesi MNO'nun ardında birleştirilmemiş bir kafa olarak kalması ve güncellenen ana hattı dallayan onları temsil eden 3 yeni komisyon M ', N', O 'yaratması dışında.

Temelde sorun bu ile sonuçlanmasıdır:

master A - B - C - D - E - F
                \ \
newfeature-123 \ M '- N' - O '
                  \
yeni özellik-123 M --- N --- O

bu iyi değil, çünkü bırakılması gereken yerel, istenmeyen taahhütlerin ardında kalıyor.

  1. Aynı bağlantıdaki diğer seçenek
hg qimport -r M: O
hg qpop -a
hg yukarı F
hg şube newfeature-123
hg qpush -a
hg qdel -r qbase: qtip

ve bu istenen grafikle sonuçlanır:

master A - B - C - D - E - F
                            \
yeni özellik-123 M --- N --- O

ama bu komutlar (hepsi 6!)

$ git rebase master

Bunun Hg'deki tek eşdeğer olup olmadığını veya Git gibi basit başka bir yol olup olmadığını bilmek istiyorum.


7
"Bu iyi değil, çünkü düşürülmesi gereken yerel, istenmeyen taahhütlerin ardında kalıyor." - aslında git de aynı şeyi yapıyor. Orijinal daldaki taahhütleri değiştirmez veya kaldırmaz, sadece master'ın üstüne aynı değişiklikleri uygulayan yenileri yapar. Eskileri kullanarak hala erişebilirsiniz ve git reflogçöp toplanana kadar tamamen gitmezler. Reflog'u kullanmak zorunda kalmamak için onları adlandırılmış bir dalda tutmak istiyorsanız, yeniden bastırmadan git branch feature-123_originalönce yapın.
MatrixFrog

5
Rastgele soru: Değişiklik setlerini / dalları kendiniz çizdiniz mi veya bunu yapan bir araç var mı?
Amir Rachum

2
TextWrangler'ı "üzerine yaz" olarak ayarladım.
jpswain

Yanıtlar:


235

VonC aradığınız cevaba sahip , Rebase Uzantısı. Bununla birlikte, mercurial'da neden mq veya rebase'in varsayılan olarak etkinleştirilmediğini düşünmek için bir iki saniye düşünmeye değer: çünkü cıva tamamen silinmez değişiklik kümeleriyle ilgilidir. Tanımladığınız şekilde çalıştığımda, neredeyse her gün, işte aldığım desen:

1. Start working on a new feature:
$ hg clone mainline-repo newfeature-123
do a few commits (M, N, O)

master A---B---C
                \
newfeature-123   M---N---O

2. Pull new changes from upstream mainline:
$ hg pull

master A---B---C---D---E---F
                \
newfeature-123   M---N---O

3. merge master into my clone so that my new feature 
can be developed against the latest upstream changes:
(from newfeature-123)
$ hg merge F

master A---B---C---D---E---F
                \           \
newfeature-123   M---N---O---P

ve gerçekten gerekli olan bu. Sonunda yeni bir özellik-123 klonu ile karşılaşıyorum. En önemlisi, tarihimi hiç değiştirmedim . Birisi csets'ime bakabilir ve neye karşı kodlandıklarını ve çalışma boyunca ana hattaki değişikliklere nasıl tepki verdiğimi görebilir. Herkes bunun bir değeri olduğunu düşünmüyor, ama ben bize istediğimizi değil, gerçekte ne olduğunu göstermek için kaynak kontrolünün işi olduğuna inanıyorum - her ölümcül ve her refactor silinmez bir iz bırakmalı ve yeniden basmalı ve diğer tarih düzenleme teknikleri bunu gizler.

Sabun kutumu kaldırırken VonC'nin cevabını seç. :)


18
Not: rotadan, Git vermez tam olarak yalnızca yeni kolayca tane (oluşturmak için öncelikle tarihi yeniden izin utcc.utoronto.ca/~cks/space/blog/tech/GitNewHistory ). RebaseExtension ekleyerek Mercurial, eski bir tarihi yenisiyle değiştirmek için aynı yolu sağlar. Neden? Çünkü bir birleştirme her zaman doğru cevap değildir, özellikle de değişiklik kümeniz F'nin tepesinde evrim olarak görülmeli ve tersi değil (P, O'nun tepesinde birleşti)
VonC

19
VonC, katılıyorum, bir birleşme her zaman doğru seçim değildir, ama bence buradaki fark kişinin VCS tarihinin onlara söyleyebilmesini istediği şeydir. Tarihin her zaman "İlk başta onu entegre etmeye çalıştığım, işe yaramayan ve o zaman işe yaramaz olduğunu düşündüm" gibi sorulara cevap verebilmesi gerektiğini düşünüyorum . Bilim adamları günlükleri numaralı sayfalarla kalem halinde tutar ve AFAIC yazılım mühendisleri yazdıkları her baytı kaydetmelidir. Tarihi yeniden yazmak, hatta cet parentage, ama kesinlikle CollapseExtension, HistEdit, vb. Tamamen kişisel bir seçim meselesi.
Ry4an Brase

14
Kişisel seçim için +1. Sonuç olarak Git ile önemsiz sapmalar için rebase kullanıyorum ve önemsiz olmayanlar için birleşiyorum. Bu, önemli olduğunu düşündüğüm birleştirme geçmişini korumama izin veriyor, ancak günlüğü çoğu zaman temiz ve doğrusal tutuyor.
Kos

16
Ayrıca tonlarca etkileşimli basım yapıyorum, çünkü önce çok sayıda küçük taahhütte bulunuyorum, sonra katılıyorum, etiketliyor ve temizliyorum, sonra onları ana dalla birleştiriyor (veya yeniden birleştiriyor). Değişiklikleri kodlamanın ve yönetmenin ayrı adımlar olmasını seviyorum.
Kos

6
"Her baytı gelişim yolu boyunca kaydet" felsefesi, katkıda bulunanların bir dizi yama önerdiği ve daha sonra bunları koruyuculardan gelen geri bildirimlere dayanarak yeniden çalıştığı büyük açık kaynaklı projeler için gerçekten uygun değildir. Daha sonra, ana proje deposu, tüm değişikliklerin sadece uygun bir versiyonuna sahiptir ve ilgili tüm değişiklikler tek bir taahhütte bulunur. git interaktif rebase, çalışma değişikliklerini, ağacı kırık bırakmayan bir dizi taahhütte temizlemek için ve her şey üzerinde çalıştıktan sonra söylemeye karar verdiğinizi yansıtan taahhüt mesajları ile gerçekten iyidir.
Peter Cordes

104

Rebase Extension'ı arıyor olabilirsiniz . ( SummerOfCode 2008'in bir parçası olarak uygulanır )

Bu durumlarda, yerel değişiklikleri "ayırmak", depoyu ana akımla senkronize etmek ve daha sonra özel değişiklikleri yeni uzaktan değişikliklerin üzerine eklemek yararlı olabilir. Bu işleme rebase denir.

Ulaşım :

alternatif metin

için:

alternatif metin


Gibi aşağıda yorumladı tarafından steprobe :

Değişiklikleri çekmemeniz ve deponuzda iki dalın olması durumunda ( kullanarakkeepbranches ) şunları yapabilirsiniz :

hg up newfeature-123 
hg rebase -d master --keepbranches

( --keepbranches: Orijinal şube adını devralın.)

Mojca'dan bahsediyor:

Kullanmayı seviyorum hg rebase --source {L1's-sha} --dest {R2's-sha}ama --keepbranchessonunda ekleyebileceğimi bilmiyordum .

As aşağıda gösterildiği tarafından Jonathan Blackburn :

 hg rebase -d default --keepbranches

1
Rebase Uzantısı'na baktım, ancak hala net değil. Lütfen yukarıda açıkladığımı yapmak için gereken adımları açıklar mısınız?
jpswain

6
Değişiklikleri hg up newfeature-123hg rebase -d master --keepbranches
çekmediğiniz ve repoda

2
Rebase'de hiçbir şeyin yanlış olmadığına inanıyorum, bu sadece bir seçim meselesi. Sorun şu ki, rebase istismar ediliyor ve bu konuda @ Ry4an ile beraberim, tarihi yeniden yazmıyorum, böylece ne olduğunu ve ne zaman olduğunu öğrenebilirsiniz.
Jorge Vargas

@steprobe: --bepbranches kullanma ipucu için teşekkür ederiz. Kullanmayı seviyorum hg rebase --source {L1's-sha} --dest {R2's-sha}ama --keepbranchessonunda ekleyebileceğimi bilmiyordum . Bu, diğer alt düzey cevaplarda belirtilir, ancak açıkça bu cevaba yazmak da güzel olacaktır.
Mojca

@Mojca Sorun değil. Cevabı buna göre düzenledim.
VonC

44

Modern bir Hg kurulumunuz olduğunu varsayarsak, şunları ekleyebilirsiniz:

[extensions]
rebase = 

~ / .hgrc.

Sonra komutları kullanabilirsiniz hg rebase, hg pull --rebaseya da hg help rebase.


2
Sadece komut açısından bu eklemek için o zaman yürütmek gerekir: hg rebase -s o -d f
Simple-Solution

21

Yukarıdaki cevapların OP'nin görev kolunu sürdürmek olan amacına ulaştığını düşünmüyorum, sadece ana dalda daha sonraki bir noktaya dayanarak.

Diyelim ki bu grafikle başladım (graphlog uzantısı kullanılarak oluşturuldu. Graphlog için ciddi geek aşkı).

@  9a4c0eb66429 Feature 3 commit 2 tip feature3
|
| o  af630ccb4a80 default againagainagain  
| |
o |  98bdde5d2185 Feature 3 branch commit 1  feature3
|/
o  e9f850ac41da foo   

Feature3 dalındayım ve againagainagain taahhüdünden geri almak istiyorsanız, koşacağımı anlıyorum hg rebase -d default. Bunun sonucu:

@  89dada24591e Feature 3 commit 2 tip 
|
o  77dcce88786d Feature 3 branch commit 1  
|
o  af630ccb4a80 default againagainagain  
|
o  e9f850ac41da foo  

Görev tamamlandı? Ben öyle düşünmüyorum. Sorun şu ki, feature3 dalındaki taahhütler againagainagain üzerine yeniden temellendirildiğinde, feature3 dalı silinmiştir . Taahhütlerim, ilk etapta kaçınmaya çalıştığım varsayılan şubeye taşındı.

Git'te sonuç şöyle görünür:

@  9a4c0eb66429 Feature 3 commit 2 tip
|
o  98bdde5d2185 Feature 3 branch commit 1 **feature3**
|
o  af630ccb4a80 default againagainagain
|
o  e9f850ac41da foo

Feature3 dalının hala mevcut olduğuna dikkat edin, iki işlemin hala feature3 dalında olduğunu ve varsayılan olarak görünmez olduğunu unutmayın. Görev dalı korunmadan, bunun bir birleştirmeden işlevsel olarak nasıl farklı olduğunu görmüyorum.

GÜNCELLEME : --keepbrancheshg rebase tarafından desteklenen bayrağı keşfettim ve her şeyin okey-dokey olduğunu bildirmekten mutluluk duyuyorum. Kullanarak hg rebase -d default --keepbranches, arzuladığım Git davranışını aynen kopyalarım. Birkaç takma ad daha sonra hiç kimsenin işi gibi görünmüyorum.


7
Sadece rebase --keepbranches bayrağı keşfetti. Sorun çözüldü. Bu benim kod olsaydı ben varsayılan yapmak istiyorum, ama bu sadece benim.
Jonathan Blackburn

1
Yukarıdaki cevabınıza bu kadar bilgi eklemiş olmanızın yararlı olacağını düşünüyorum - bulmam biraz zaman aldı.
HansMari

3

Bazı insanlar her şeyin yinelemesini korumanın iyi olduğunu düşündüklerini söyleyerek, daha büyük açık kaynaklı projeler için, birleşmelerle dolu değişiklikleri kabul etmenin ve geliştirme yinelemesinin dağınık bir ana hat revizyon geçmişi yapacağını ve mevcut sürümün oraya nasıl geldiğini görmek için düzeltme geçmişi daha az yararlıdır.

Gönderilen değişiklikler, kabul edilmeden önce onları yazmayan kişiler tarafından incelendiğinde iyi çalışır, bu nedenle ana hatta yapılan değişiklikler genellikle hata ayıklanır ve çalışır. Sonra bir satırın kökeni geri izlediğinizde, onunla birlikte gelen tüm değişiklikleri görürsünüz, onun bir parçası olan değişimin gelişiminin ortasında bir nokta değil.

X265 katkıda sayfası açıklıyor üzerinde çalıştığınız bir dizi değişiklik yeniden işlemeye nasıl sunulması için hazır hale getirmeyi X265 projeye. (Git gui'nin sahne / kararsızlık farksızlığı gibi tek bir dosyadaki tüm değişiklikleri değil ama bazı değişiklikleri yapmak için TortoiseHG'nin kullanımı dahil).

İşlem, hg'nin akış yukarı ipucuna güncellenmesini ve daha sonra tüm değişikliklerin çalışma dizininde kullanılmasını sağlamaktır. Göndermek istediğiniz şeyin bir parçası olmayan herhangi birini rafa alın, sonra geri kalanını güzel taahhüt mesajları ile birçok ayrı taahhüt uygun olarak ayırın.

Sanırım revize ettiğiniz bir patchset'in önceki yinelemelerinden kaydedilmiş mesajları kopyalayıp yapıştırın ve düzenleyin. Belki de eski taahhütlerinizi (git dilinde kiraz toplama) hazırlayabilir ve ardından eski taahhüt mesajlarınızı düzenleme için bir başlangıç ​​noktası olarak almak için bunları tek tek değiştirebilirsiniz.

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.