Kayıtları Mercurial'de ezebilir miyim?


110

Gerçekten sadece bir tane olması gereken bir çift taahhütüm var. Git kullanıyor olsaydım, şunu kullanırdım:

git rebase -i <some-commit-before>

ve sonra onları ezin.

Bunu mercurial olarak yapabilir miyim? Öyleyse nasıl?

Yanıtlar:


88

Evet, bunu herhangi bir uzantı olmadan Mercurial kullanarak Değişiklik Kümelerini Birleştirerek yapabilirsiniz .

Alternatif olarak, bir uzantı kullanmak isterseniz kullanabilirsiniz:


Evet, bu cevabı genel soruya yaptığım yorumda sevdiğim dupe sorulardan çıkardım. Sanırım bu konuda cevabın bu.
Ry4an Brase

4
Küçük bir ek not: Histedit uzantısı Mercurial 2.3 ve sonraki sürümlerle birlikte dağıtılır. Sadece etkinleştirmeniz gerekir.
Paidhi

1
Değişiklik Kümelerini Birleştirme belgesinde "depoların" soyut kavramları kullanılıyor, bunlara nasıl başvurabilirim? Örneğin: hg -R oldrepo export ... üretir "iptal: depo oldrepo bulunamadı!
Aleksandr

13
Sadece 2 kaydı ezmeye çalışıyorum. Gerçekten 10'dan fazla komuta veya alternatif uzantılara sahip bir wiki sayfasına ihtiyacım var mı?
Aleksandr Levchuk

3
Yorumlara bakın. Histedit artık yerleşiktir, sadece etkinleştirmeniz gerekir (çünkü hiçbir varsayılan komut geçmişi değiştirmez)
Ry4an Brase

43

Benim favorim hg strip --keepkomuta. Ve sonra tüm değişiklikleri tek bir işlemde gerçekleştiriyorum.

Bu benim için en hızlı ve en rahat yoldur, çünkü günlük işlerim sırasında birçok küçük işlem yapmayı seviyorum;)


Not 1: stripYerleşik bir uzantının mqetkinleştirilmesi gerekir.
Not 2: Sevdiğim Git / Mercurial istemcisi (SmartGit / Hg) varsayılan tarafından ekler --keepsırasında parametresi strip. Ve daha da kullanışlı olanı: şu seçeneği sağlar join commits:]


4
Hg strip için tam komut şudur: Sonuncuyla ezmek istediğiniz ilk commit'in revizyon numarası hg strip --keep --rev [rev] nerederev
Nicolas Forney

3
@NicolasForney Tam olarak değil --rev, isteğe bağlı, tam komuthg strip --keep [rev]
G. Demecki

3.3.3'te revizyon benim için zorunludur: hg help stripverir hg strip [-k] [-f] [-n] [-B bookmark] [-r] REV...ve revizyonu atlamak bana verir abort: empty revision set.
Roman Starkov

3
Kullanmak hg stripen iyi fikir değil. Tam olarak güvenli değil. Deneyin hg histedit, hatta evrim uzantısını kullanmayı deneyin.
Martin Thomson

Git insanlar için en doğal yol gibi görünüyor;)
foo

32

Rebase uzantısı bir cazibe gibi çalıştı. 2 kaydı ezmek için:

$ hg rebase --dest .~2 --base . --collapse

Nokta, mevcut revizyon için bir kısayoldur.

Bir şubede birkaç işleminiz olduğunda ve hepsini bir araya getirmek istediğinizde daha da kolaydır:

$ hg rebase --dest {destination branch (e.g. master)} --base . --collapse

Bu nasıl çalışır:

görüntü açıklamasını buraya girin

( http://mercurial-scm.org/wiki/RebaseExtension#Collapsing adresinden )


1
İki kayıt için "~ 2" yi nerede buldunuz?
Mi-La

1
Revsets konusunda açıklanmıştır, hg help revsets'e bakın.
markand

13

Bu cevabı okuyorsanız, bu cevapta bahsedilen diğer tüm seçenekleri unutabilir foldve evrim uzantısının komutunu kullanabilirsiniz .

evolvegüvenli değiştirilebilir geçmişe sahip olmamıza yardımcı olan bir mercurial uzantısıdır, yine de deneyseldir. Bunu onu klonlama yoluyla kullanabilirsiniz repo ve bu gibi .hgrc içinde eklemeden.

[extensions]
evolve = ~/evolve/hgext/evolve.py

Ana dizininizde repo geliştirmek için klonladığınızı varsayarsak. Şimdi gitmekte iyisin. Ayrıca şuradan da yardım arayabilirsiniz hg help fold.

Katlama Komutu

foldKırılmamış doğrusal bir işlem zincirini ezmeyi / katlamayı söylüyorsunuz . Katlamanın yaptığı şey, tüm değişiklik kümelerinden değişiklikleri içeren yeni bir değişiklik kümesi yaratır ve tüm bu taahhütleri eski olarak işaretler. Bunu docs adresinde daha derinlemesine inceleyebilirsiniz .

Şimdi aşağıdaki geçmişe sahip olduğunuzu varsayalım.

a -> b -> c -> d -> e -> f -> g

Sen ezmek istiyorum e, fve g. Yapabilirsin

hg up g
hg fold -r e

Sonuç olacak

a -> b -> c -> d -> h

nerede hher üç kaydedilmesini değişiklikler içermektedir değişiklik kümesi ise e, fve g.

Değişiklik setlerini tarihin ortasından da katlayabilirsiniz, yani ucu içeren bir zincir seçmeniz gerekmez. Eğer katlamak istediğinizi varsayalım b, cve d. Yapabilirsin

hg up d
hg fold -r b
hg evolve --all

Bu sonuçlanacak

a -> i -> j

burada ikatlanmış değişiklik kümesi olup b, c, dve jaynı değişiklik kümesi olup h. Evolve kullanım kılavuzu mutlaka okunmalıdır.


Yeniden ödeme, bu uzantının çoğu (belki de tüm?) Kullanım durumlarını ve kesinlikle bu soruda sorulanı kapsıyor gibi görünüyor. Bu uzantının katil özelliği, değiştirdiğiniz revizyonları gizlemektir (silmek yerine), ancak yeniden düzenleme --keepseçeneği bunu kapsar (ardından revizyonları gizli olarak işaretleme veya sonucu kontrol ettikten sonra üzerlerinde şerit kullanma). Revizyonları diğer revizyonlar arasında taşımak bile bir dizi iki rebase komutuyla mümkündür.
Arthur Tacca

... artı, gerçekten karmaşık bir şey yapıyorsanız, yedek olarak kullanmak için her zaman önce yerel depoyu klonlayabilirsiniz. Ne kadar nadir (umarız!) Olduğunu düşünürsek, tamamen yeni bir uzantının nasıl kullanılacağını öğrenmekten daha az çaba gerektirir.
Arthur Tacca

"NameError: 'execfile' adı tanımlanmadı" - bu, evrimin temelde taş devri olan Python 2'de yazıldığı anlamına gelir.
Neil G

1
@NeilG mercurial henüz Python 3'ü desteklemiyor.
Pulkit Goyal

2
@NeilG evet, mercurial topluluğu en kısa sürede py3 desteği almak için çok çalışıyor.
Pulkit Goyal

1

Mercurial 4.8 (Kasım 2018, 9 yıl sonra) ile yeni komutu düşünebilirsiniz hg absorb(daha önce deneysel bir özellikti ).

Bkz. " Mercurial 4.8'deki Taahhüt Değişikliklerini Emmek "

Absorbe uzantısı, çalışma dizininizdeki her değişikliği alacak, dizinizdeki hangi kayıtların bu satırı değiştirdiğini belirleyecek ve bu commit'deki değişikliği otomatik olarak değiştirecektir.
Herhangi bir belirsizlik varsa (yani, aynı satırda değiştirilen birden çok işlem), o zaman absorbe, bu değişikliği göz ardı edecek ve manuel olarak çözülmesi için çalışma dizininizde bırakacaktır.

Teknik düzeyde, hg absorbtaahhüt edilmeyen tüm değişiklikleri bulur ve değiştirilen her satırı belirsiz olmayan bir önceki işlemle eşleme girişimleri.
Temiz bir şekilde haritalanabilen her değişiklik için, taahhüt edilmeyen değişiklikler uygun önceki taahhütte dikkate alınır. Operasyondan etkilenen taahhütler otomatik olarak yeniden hesaplanır.
Bir değişiklik, belirsiz olmayan bir önceki işleme ile eşleştirilemezse, taahhüt edilmeden bırakılır ve kullanıcılar mevcut bir iş akışına geri dönebilir (örneğin kullanarak hg histedit).

Otomatik yeniden yazma mantığı, hg absorbsatırların geçmişini takip ederek uygulanır: Bu, temelde yaklaşımdan farklıdır hg histeditveya çoklu girdi verilen bir dosyanın yeni bir sürümünü türetmek git rebaseiçin 3 yollu birleştirmeye dayalı birleştirme stratejilerine güvenme eğilimindedir. sürümler.

Bu yaklaşım, hg absorpsiyonunun belirsiz bir uygulama taahhüdü ile değişiklikleri atlaması gerçeğiyle birleştiğinde, hg absorpsiyonunun asla birleştirme çakışmalarıyla karşılaşmayacağı anlamına gelir!

Şimdi, belirsiz uygulama hedeflerine sahip satırları görmezden gelirseniz, yamanın klasik 3 yollu birleştirme kullanarak her zaman temiz bir şekilde uygulanacağını düşünüyor olabilirsiniz. Bu ifade mantıksal olarak doğru geliyor. Ancak bu değil: hg absorbBirleştirme tarafından yapıldığında hg histeditveya git rebase -ibaşarısız olduğunda birleştirme çatışmalarını önleyebilir .


0

Bence chistedit(Mercurial 2.3'ten beri yerleşik) buna en yakın rebase -iolanı saf Mercurial'dir ( chisteditinteraktif sürümüdür histedit). Histedit Bir kez foldkomuta Rebase en eşleştiren squashve rollkomuta Rebase en eşleştiren fixup. Daha fazla bilgi için histedit belgelerine bakın .

İşte basit bir örnek. Aşağıdakilere sahip olduğunuzu ve tüm 1e21c4b1 değişikliklerini önceki revizyona taşımak ve yalnızca önceki revizyonun mesajını saklamak istediğinizi varsayalım.

@  1e21c4b1 drees tip
|  A commit you want to squash
o  b4a738a4 drees
|  A commit
o  788aa028 drees
|  Older stuff

Kaçabilirsiniz hg chistedit -r b4a738a4b4a738a4 düzenleme geçmişi arkasına. Chistedit'te imleci 1e21c4b1'e getirin ve rbu revizyonu geri almak istediğinizi belirtmek için vurun . Histedit'teki (en eskiden en yeniye) sıranın (en yeniden en eskiye) tersine çevrildiğini unutmayın hg log.

#0  pick   160:b4a738a49916   A commit
#1  ^roll  161:1e21c4b1500c

Değişikliklerinizi seçtikten sonra, cbunları gerçekleştirmeyi seçersiniz . Sonuç şudur:

@ bfa4a3be drees ipucu | 788aa028 drees | Eski şeyler

Eğer onlar için nispeten yeniyseniz, referans için histedit dosyasındaki komut açıklamalarını sağladığından histeditdaha iyi bir seçim olabilir chistedit. Normal metin düzenlemeyi kullanarak komutları ayarlamak biraz daha fazla düzenleme gerektirir (normal yeniden temelde olduğu gibi).

Bunlardan birini kullanmak için histeditveya ~ / .hgrc dosyanıza uzantılarınızı chistediteklemeniz histeditgerektiğini unutmayın:

[extensions]
histedit =

Ben önerdi chistedito en yakın olduğu rebase -ive tarihin her yerde çalışır. Eğer gerçekten sadece mevcut revizyonu önceki revizyona dahil etmek / ince ayar yapmak istiyorsanız @G. Olanlar stripaçık olduğu için Demecki'nin önerisi iyi olabilir. Mercuria 2.8'den beri inşa edilmiştir. Yukarıdaki gibi eşdeğer sonuçları elde etmek için aşağıdakileri yapabilirsiniz:

hg strip .
hg add
hg commit --amend

Not strip, histedit gibi, içinde etkinleştirilmesi gerekir sizin ~ / .hgrc:

[extensions]
strip =

0

En son 2 kaydı sıkıştırmak (birleştirmek) istediğinizi varsayalım.

  1. Bir revizyon numarası bulun

    hg log -G -l 3
    

    olası çıktı:

    @  changeset:   156:a922d923cf6f
    |  branch:      default
    |  tag:         tip
    |  user:        naXa!
    |  date:        Thu Dec 13 15:45:58 2018 +0300
    |  summary:     commit message 3
    |
    o  changeset:   155:5feb73422486
    |  branch:      default
    |  user:        naXa!
    |  date:        Thu Dec 13 15:22:15 2018 +0300
    |  summary:     commit message 2
    |
    o  changeset:   154:2e490482bd75
    |  branch:      default
    ~  user:        naXa!
       date:        Thu Dec 13 03:28:27 2018 +0300
       summary:     commit message 1
    
  2. Yumuşak sıfırlama dalı

    hg strip --keep -r 155
    
  3. Değişiklikleri tekrar uygula

    hg commit -m "new commit message"
    

Notlar

stripyerleşik bir uzantının etkinleştirilmesini gerektirir. ~/.hgrcAşağıdaki içeriğe sahip yapılandırma dosyası oluşturun / düzenleyin :

[extensions]
strip = 

-1

Kullanırım:

hg phase --draft --force -r 267
...
hg rebase --dest 282 --source 267 --collapse
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.