Mercurial: Son taahhüt nasıl değiştirilir?


211

git commit --amendMercurial, yani benim çalışma kopyası bağlı taahhüt değiştirmek için bir yol arıyorum . Sadece son işlemle ilgileniyorum, keyfi daha önceki işlemle ilgilenmiyorum.

Bu değişiklik prosedürü için gereksinimler şunlardır:

  • mümkünse, herhangi bir uzantı gerektirmemelidir. Bu gerekir varsayılan olmayan uzantıları gerektirmeyen , resmi bir Mercurial yükleme ile gelmez yani uzantıları.

  • değişiklik yapma taahhüdü mevcut şubemin bir başkanı ise, yeni bir başkan oluşturulmamalıdır. Taahhüt baş değilse, yeni bir başkan oluşturulabilir.

  • prosedür olmalıdır güvenli çeşitli sebeplerden tadil eden başarısız olursa, ben düzeltilmesinde önceki gibi restore aynı çalışma kopyasını ve depo devlet olmasını istediğiniz bir şekilde. Başka bir deyişle, değişikliğin kendisi başarısız olursa, çalışma kopyasını ve depo durumunu geri yüklemek için güvenli bir yordam olmalıdır. Dosya sistemi ile ilgili sorunlara (erişim kısıtlamaları, yazma için bir dosyayı kilitleyememek gibi) değil, değişiklik prosedürü (örneğin çatışmalar) doğasında yatan "başarısızlıklardan" bahsediyorum ... )

Güncelleme (1):

  • yordam otomatikleştirilebilir olmalıdır , böylece herhangi bir kullanıcı etkileşimi gerekmeden GUI istemcisi tarafından gerçekleştirilebilir.

Güncelleme (2):

  • çalışma dizinindeki dosyalara dokunulmamalıdır (değiştirilen bazı dosyalarda dosya sistemi kilitleri olabilir). Bu özellikle, olası bir yaklaşımın hiçbir zaman temiz bir çalışma dizini gerektirmeyeceği anlamına gelir.

Yanıtlar:


289

Mercurial 2.2'nin çıkmasıyla birlikte, geçerli çalışma dizini ile son taahhüdü güncellemek için --amendile seçeneğini kullanabilirsiniz.hg commit

Gönderen komut satırı referans :

--Amend bayrağı, çalışma dizininin üst öğesini, varsa hg durumu tarafından bildirilen öğelere ek olarak üst öğedeki değişiklikleri içeren yeni bir taahhütle değiştirmek için kullanılabilir. Eski komut, .hg / strip-backup içindeki bir yedekleme paketinde saklanır (bkz. Hg yardım paketi ve hg, nasıl geri yükleneceği konusunda ayrıştırma).

Mesaj, kullanıcı ve tarih belirtilmedikçe değiştirilmiş taahhütten alınır. Komut satırında bir mesaj belirtilmediğinde, düzenleyici değiştirilen taahhüt mesajıyla açılır.

Harika olan şey, bu mekanizmanın "güvenli" olmasıdır, çünkü yerel deponun dışında zaten kullanıma sunulan geçmişi değiştirecek güncellemeleri önlemek için nispeten yeni "Aşamalar" özelliğine dayanır.


2
İyi cevap! Deneysel evrimleşme uzantısı , genel olmayan taahhütleri güvenli bir şekilde değiştirmenizi sağlar . Eski taahhüt geçersiz ve gizli olarak işaretlenir. Yayımlama yapmayan bir sunucuyla, bunu değişiklik kümelerini zorladıktan sonra bile güvenle yapabilirsiniz.
Martin Geisler

5
Sadece son taahhütteki mesajı güncellemek için: hg commit --amend -m "bu benim yeni mesajım"
Jay Sheth

52

Mercurial'ta taahhütleri düzenlemek için 3 seçeneğiniz vardır:

  1. hg strip --keep --rev -1son (1) işlemi geri alın, böylece tekrar yapabilirsiniz ( daha fazla bilgi için bu cevaba bakınız ).

  2. Mercurial ile birlikte gelen MQ uzantısını kullanma

  3. Mercurial ile gönderilmemiş olsa bile, Histedit uzantısından bahsetmeye değer

Mercurial wiki'nin Düzenleme Geçmişi sayfasına da göz atabilirsiniz .

Kısacası, düzenleme geçmişi gerçekten zor ve cesaret kırıcı . Değişikliklerinizi zaten ittiyseniz, diğer tüm klonların tam kontrolüne sahip olmanız dışında, yapabileceğiniz hiçbir şey yoktur.

git commit --amendKomuta gerçekten aşina değilim , ama AFAIK, Histedit en yakın yaklaşım gibi görünüyor, ama ne yazık ki Mercurial ile gönderilmiyor. MQ'nun kullanımı gerçekten karmaşıktır, ancak bununla neredeyse her şeyi yapabilirsiniz.


1
Geri alma nedenini kaçırdığımdan emin değilim, ama istediğim şeyi yapıyor (neredeyse). Tek sorun, orijinal taahhüdüm için bir dosya kaldırıldığında ve değiştirilmiş taahhüdüm için yeniden dirildiğinde: geri alma işleminden önce tersine çevrilecek, geri alma işleminden sonra kaldırılması planlanacak (ancak dosya hala var çalışma dizini)
mstrap

@Marc Sorununuzu anladığımdan emin değilim, ama unutma komutuna bir göz atın, sanırım aradığınız şey bu.
krtek

"Unutma" burada yararlı olacağını sanmıyorum. İşte sorun daha ayrıntılı olarak: (1) Ben revizyon 2'deyim (2) "Dosya" yı kaldırıyorum ve diğer bazı değişiklikler var (3) Değişiklik yap, revizyon 3 ile sonuçlan (4) Şimdi fikrimi değiştireceğim ve karar vereceğim "file" işleminden kaldırılmamalı, bu yüzden revizyon 3'ü değiştirmek istiyorum. Bu nedenle, artık ters çevrilmemiş olan "file" i tekrar ekleyeceğim (5) Şimdi geri dönme gerçekleştiriyorum: dirstate'i sıfırlayacak ve işaretleyecek " dosyası "olarak kaldırıldı. (6) Şimdi "hg commit" i tekrar gerçekleştirirken, "file" artık kaldırılmamasına rağmen kaldırılmış olarak kalacaktır. Bunun için otomatik bir düzeltme nasıl görünebilir?
mstrap

1
Otomatik kısım için bilmiyorum, ancak hg revert myfilesilme işlemini geri alabilirsiniz . Belki de hg addsonra dosya ile yeniden ekleme rollbackde çalışır.
krtek

3
Yayınlanan değişikliklerin geçmişini düzenlemekten kaçınılması gerektiğini kabul ediyorum, ancak yerel geçmişimi düzenlemem bir DVCS'nin en önemli özelliklerinden biri. Qimport ile MQ, saf tarih düzenleme AFAICT.
mstrap

38

Şunun için GUI eşdeğeri hg commit --amend:

Bu ayrıca TortoiseHG GUI (v2.5 kullanıyorum) çalışır:

'İşleme' görünümüne geçin veya tezgah görünümünde 'çalışma dizini' girişini seçin. 'Tamamla' düğmesi 'Geçerli düzeltmeyi değiştir' adlı bir seçeneğe sahiptir (bulmak için düğmenin açılır okunu tıklayın).

resim açıklamasını buraya girin

          ||
          ||
          \/

resim açıklamasını buraya girin

Uyarı emptoru :

Bu ekstra seçenek yalnızca cıva sürümü en az 2.2.0 ise ve geçerli revizyon herkese açık değilse bir yama değilse ve alt öğesi yoksa etkinleştirilir. [...]

Düğmeye tıklanması, düzeltmeyi 'değiştirmek' için 'taahhüt - değiştir' olarak adlandırılır.

THG dev kanalında bu konuda daha fazla bilgi


Çok faydalı, teşekkürler. THG, önceki taahhütten gelen mesaja taahhüt (değiştir) mesajını varsayılan olarak ayarlayabilecek kadar akıllıdır.
UuDdLrLrSs

7

Krtek'in yazdıklarını ayarlıyorum. Daha spesifik olarak çözüm 1:

Varsayımlar:

  • bir (!) değişiklik kümesi yaptınız ancak henüz itmediniz
  • bu değişiklik kümesini değiştirmek istediğinizde (örneğin dosya ve / veya yürütme mesajı ekleme, kaldırma veya değiştirme)

Çözüm:

  • hg rollbackson taahhüdü geri almak için kullan
  • yürürlükteki yeni değişikliklerle yeniden taahhütte bulun

Geri alma son işlemi gerçekten geri alır. Çalışma şekli oldukça basittir: HG'deki normal işlemler sadece dosyalara eklenecektir; bu bir taahhüt içerir. Mercurial, son işlemin dosya uzunluklarını takip eder ve bu nedenle dosyaları eski uzunluklarına indirerek bir adımı tamamen geri alabilir.


1
Ayarlama çözümü (1) için teşekkürler; geri alma ile ilgili sadece küçük bir sorun var, lütfen krtek'in çözümündeki yorumuma bakın.
mstrap

8
O, insanları yakalar son olmasıdır çünkü bir şey, geri alma üzerine vurgulamak işlem geri alındı alır repo, son değil işlemek. Dolayısıyla, başka bir şey repoya bir yazı yazdıysa, geri alma yardımcı olmaz. Hatırlanması gereken ince ama önemli bir şey. MQ ve histedit, geri alma penceresi kapatıldıktan sonra yardımcı olabilir, ancak yine de yalnızca belirli bir noktaya kadar.
Paul S

7

Değişikliklerinizi henüz yaymadığınızı varsayarsak, şunları yapabilirsiniz.

  • .Hgrc'nize ekleyin:

    [extensions]
    mq =
    
  • Deponuzda:

    hg qimport -r0:tip
    hg qpop -a
    

    Tabii ki revizyon sıfır ile başlamanız veya tüm yamaları pop yapmanız gerekmez, son sadece bir pop ( hg qpop) yeterlidir (aşağıya bakın).

  • .hg/patches/seriesdosyadaki son girişi veya beğenmediğiniz yamaları kaldırın . Yeniden sıralama da mümkündür.

  • hg qpush -a; hg qfinish -a
  • .diff.hg / yamalardaki dosyaları (uygulanmamış yamalar) kaldırın (sizin durumunuzda bir tane olmalıdır).

Eğer varsa istemiyoruz için hepsini geri almak için yama, sen kullanarak düzenleyebilirsiniz hg qimport -r0:tip, ardından düzenleme şeyler ve kullanım (veya benzeri) hg qrefreshdestenizin üzerinde en üstteki yama içinde değişiklikleri birleştirmek için. Okuyun hg help qrefresh.

Düzenleyerek .hg/patches/series, birkaç yamayı kaldırabilir veya bazılarını yeniden sıralayabilirsiniz. Son revizyonunuz 99 ise, sadece kullanabilirsiniz hg qimport -r98:tip; hg qpop; [edit series file]; hg qpush -a; hg qfinish -a.

Tabii ki, bu prosedür son derece cesaret kırıcı ve risklidir . Bunu yapmadan önce her şeyin bir yedeğini alın !

Bir sidenote olarak, sadece özel depolarda milyonlarca kez yaptım.


Ayrıca mq-uzantısı kullanmayı düşünmüştüm, ancak bazıları başarısız olabilir (örneğin ikili dosyalar varsa) oldukça fazla işlem gerektirir. Ayrıca, bu prosedür bir GUI istemcisinde kullanılması gerektiğinden .hg / patch / series düzenlemek zorunda kalmayacaksınız (yukarıdaki gereksinimleri güncelledim)
mstrap

Hmmm, bunun sizin için olmayacağı için üzgünüm, özel bir depoda bu gerçekten kıçını tekmeledi (yedeklerle - Ben onunla bir temsilcisi yağmaladım ^). hg qfoldBtw
hochl

MQ kullandığınız için + 1, ancak bence denize girdiniz. Sadece son taahhüdü değiştirmeyi soruyor. Ayrıca bu içe aktarma, bir birleşme işlemine başlar başlamaz oyalanacak. 'qimport -r ipucu; <öğeleri düzenle>; qrefresh -e; qfin -a 'işi yapacak (-e taahhüt mesajını düzenlemek için)
Paul S

doğru, birleştirme bir sorun, genellikle sadece bir yama pop ve kullanın hg import -r<prev>:tip. Bir çukur, alt sürümde olduğu gibi önceki sürüm için kısayol yok.
hochl

2

Mercurial'ın son sürümleri evolve, hg amendkomutu sağlayan uzantıyı içerir . Bu, sürüm kontrolünüzde değişiklik öncesi geçmişi kaybetmeden bir taahhüde değişiklik yapılmasına olanak tanır.

hg değişiklik [OPTION] ... [FILE] ...

takma adlar: yenileme

bir değişiklik kümesini güncellemelerle birleştirin ve yenisiyle değiştirin

Commits a new changeset incorporating both the changes to the given files
and all the changes from the current parent changeset into the repository.

See 'hg commit' for details about committing changes.

If you don't specify -m, the parent's message will be reused.

Behind the scenes, Mercurial first commits the update as a regular child
of the current parent. Then it creates a new commit on the parent's
parents with the updated contents. Then it changes the working copy parent
to this new combined changeset. Finally, the old changeset and its update
are hidden from 'hg log' (unless you use --hidden with log).

Uzantının tam açıklaması için https://www.mercurial-scm.org/doc/evolution/user-guide.html#example-3-amend-a-changeset-with-evolve adresine bakın evolve.


Aynı taahhüt mesajını tekrar kullanmak hoş bir özellik!
mpen

1

Orijinal sorudaki tüm sorunları çözemeyebilir, ancak bu, mercurial'ın önceki taahhüde nasıl değiştirebileceğine dair de facto yazı gibi göründüğü için, 2 sent değerinde bilgi ekleyeceğim.

Benim gibiyseniz ve herhangi bir dosya eklemeden yalnızca önceki tamamlama mesajını değiştirmek (yazım hatası düzeltmek vb.) İstiyorsanız, bu işe yarayacaktır

hg commit -X 'glob:**' --amend

Herhangi bir dahil etme veya hariç tutma deseni olmadan hg commitvarsayılan olarak çalışma dizinindeki tüm dosyaları içerir. Örüntü uygulandığında -X 'glob:**', olası tüm dosyalar hariç tutulur ve yalnızca gönderme iletisinin değiştirilmesine izin verilir.

İşlevsel olarak git commit --amenddizin / aşamada dosya olmadığı zamankiyle aynıdır .


0

Başka bir çözüm, uncommitbelirli bir dosyayı geçerli komuttan hariç tutmak için komutu kullanmak olabilir .

hg uncommit [file/directory]

Bu, geçerli taahhüdü korumak ve bazı dosyaların kesinleştirmeden seçimini kaldırmak istediğinizde çok yararlıdır (özellikle files/directoriessilindi için yararlıdır ).

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.