Existe alguma maneira de excluir confirmações locais no Mercurial?

209

Então, continuo cometendo um erro bobo no Mercurial. Muitas vezes, começarei a trabalhar sem fazer um "hg pull" e uma "hg update". Quando tento enviar minhas alterações, recebo um erro.

Existe alguma maneira de excluir meus commits locais para evitar a criação de várias cabeças, ramificações etc.? Eu só quero excluir minhas confirmações locais, mesclar minhas alterações com a dica e, em seguida, confirmar novamente. Parece simples, certo? Não consigo encontrar nenhuma maneira de excluir facilmente confirmações locais, para que eu possa mesclar-me com a dica.

Mais uma vez, estou apenas tentando excluir confirmações locais feitas com "hg ci". Não quero modificar arquivos, reverter etc.

user191535
fonte
12
Não é um erro bobo, é um fluxo de trabalho normal quando várias pessoas estão trabalhando com o mesmo repositório simultaneamente.
Juozas Kontvainis

Respostas:

247

Ative o " extensão " strip " e digite o seguinte:

hg strip #changeset# --keep

Onde #changeset#está o hash do conjunto de alterações que você deseja remover. Isso removerá o referido conjunto de alterações, incluindo conjuntos de alterações que descendem dele e deixará seu diretório de trabalho intocado . Se você deseja também reverter suas alterações de código confirmadas, remova a --keepopção

Para mais informações, consulte o Extensão tira .

Se você receber "comando desconhecido 'strip'", pode ser necessário ativá-lo. Para fazer isso, localize o arquivo .hgrcou Mercurial.inie adicione o seguinte:

[extensions]
strip =

Observe que (como Juozas mencionou em seu comentário) ter várias cabeças é um fluxo de trabalho normal no Mercurial. Você não deve usar o comando strip para combater isso. Em vez disso, você deve mesclar sua cabeça com a cabeça de entrada, resolver quaisquer conflitos, testar e pressionar.

O stripcomando é útil quando você realmente deseja se livrar de conjuntos de alterações que poluem a ramificação. De fato, se você está na situação desta pergunta e deseja remover completamente todos os conjuntos de alterações "rascunhos" permanentemente, confira a resposta principal , que basicamente sugere:

hg strip 'roots(outgoing())'
Samaursa
fonte
8
@Bharath: Você precisa ativar a extensão
Samaursa
1
Desde o mercurial 2.8, a tira é uma extensão autônoma, então tudo strip = bem. WhatsNew para Mercurial 2.8
Chih-Hsuan Yen
104

Se você estiver usando o Hg Tortoise, ative a extensão " strip " em:

  1. Arquivo / Configurações / Extensões /
  2. Selecionar faixa

Em seguida, selecione a revisão inferior de onde você deseja iniciar a distribuição, fazendo right clickisso e selecionando:

  1. Modificar histórico
  2. Faixa

Bem assim:

insira a descrição da imagem aqui

Neste exemplo, ele será apagado da 19ª revisão para a última realizada (22).

EliuX
fonte
2
File/Settings/Extensions/Eu gostaria de poder adicionar mais votos. Muito obrigado!
Dyatchenko
Argh! Eu tentei isso, mas parecia despejar todas as minhas alterações, apesar de não marcar "nenhum backup" ou "descartar alterações locais". Eu queria manter essas mudanças, mas não as comprometa! Existe alguma maneira de recuperá-los agora?
precisa
2
Não consigo encontrar uma maneira de fazê-lo corretamente, mas parece manter o conteúdo que você precisa passar --keepe o TortoiseHg não oferece essa opção. Então ... você precisa fazer isso na linha de comando hg strip -r . --keep.
precisa
3
from strip help: 'Quaisquer conjuntos de alterações removidos são armazenados em ".hg / strip-backup" como um pacote (consulte "hg help bundle" e "hg help unbundle"). Eles podem ser restaurados executando "hg unbundle .hg / strip-backup / BUNDLE", em que BUNDLE é o arquivo de pacote criado pela faixa. '
precisa
No SourceTree também foi útil. Obrigado!
Ponomarenko Oleh
22

Resposta moderna (relevante apenas após o Mercurial 2.1):

Use Fases e marque as revisões que você não deseja compartilhar como secretas (privadas). Dessa forma, quando você pressiona, eles não serão enviados.

No TortoiseHG, você pode clicar com o botão direito do mouse em uma confirmação para alterar sua fase.

Além disso: você também pode usar a extensão "rebase" para mover suas confirmações locais para a cabeça do repositório compartilhado depois de puxar.

Tom Leys
fonte
Private == secret now
Dmitry Osinovskiy 27/03
15

Como todo mundo está apontando, você provavelmente deve puxar e mesclar as cabeças, mas se você realmente deseja se livrar de seus commits sem nenhuma das ferramentas EditingHistory , pode simplesmentehg clone -r o repo para obter todas as alterações, exceto essas.

Isso não os exclui do repositório original, mas cria um novo clone que não os possui. Em seguida, você pode excluir o repo modificado (se desejar).

Ry4an Brase
fonte
"Hg clone -r" exclui as alterações locais? Eu só quero excluir confirmações locais para manter as coisas simples.
user191535
4
Ele não os exclui do repositório clonado, mas cria um novo clone que não os possui. Em seguida, você pode excluir o repo modificado, se desejar.
Ry4an Brase
9

Me deparei com esse problema também. Eu fiz 2 commite queria reverter e excluir os dois commits.

$ hg rollback

Mas hg rollbackapenas reverte para o último commit, não os 2 commit. Naquela época, eu não percebi isso e mudei o código.

Quando descobri que hg rollbackhavia recuperado um commit, descobri que poderia usar hg strip #changeset#. Então, eu costumava hg log -l 10encontrar as 10 confirmações mais recentes e obter o conjunto de alterações correto que queria strip.

$ hg log -l 10
changeset:   2499:81a7a8f7a5cd
branch:      component_engine
tag:         tip
user:        myname<[email protected]>
date:        Fri Aug 14 12:22:02 2015 +0800
summary:     get runs from sandbox

changeset:   2498:9e3e1de76127
branch:      component_engine
user:        other_user_name<[email protected]>
date:        Mon Aug 03 09:50:18 2015 +0800
summary:     Set current destination to a copy incoming exchange

......

$ hg strip 2499
abort: local changes found

O que abort: local changes foundsignifica isso ? Isso significa que foram hgencontradas alterações no código que ainda não foram confirmadas. Portanto, para resolver isso, hg diffsalve o código que você alterou e hg reverte hg strip #changeset#. Bem assim:

$ hg diff > /PATH/TO/SAVE/YOUR/DIFF/FILE/my.diff
$ hg revert file_you_have_changed
$ hg strip #changeset#

Depois de fazer o acima, você pode patcho arquivo diff e seu código pode ser adicionado novamente ao seu projeto.

$ patch -p1 < /PATH/TO/SAVE/YOUR/DIFF/FILE/my.diff
Indo à minha maneira
fonte
9

Você pode contornar isso ainda mais facilmente com a extensão Rebase , basta usar hg pull --rebasee seus commits são automaticamente confirmados novamente para a revisão extraída, evitando o problema de ramificação.

muito php
fonte
1
À custa de ter um histórico impreciso e possível corrupção, se você fizer algo errado.
Ry4an Brase
5

Se você está familiarizado com o git, ficará feliz em usar o histedit que funciona assim git rebase -i.

neo
fonte
4

hg stripé o que você está procurando. É análogo git resetse você estiver familiarizado com o git.

Usar console:

  1. Você precisa saber o número da revisão. hg log -l 10. Este comando mostra os últimos 10 confirmados. Encontre o commit que você está procurando. Você precisa de um número de 4 dígitos da linha changesetchangeset: 5888:ba6205914681

  2. Então hg strip -r 5888 --keep. Isso remove o registro da confirmação, mas mantém todos os arquivos modificados e você pode confirmá-los novamente. (se você deseja excluir arquivos para remover --keephg strip -r 5888

val.sytch
fonte
1

[Hg Tortoise 4.6.1] Se for uma ação recente, você pode usar a ação "Reverter / Desfazer" (Ctrl + U).

Imagem da tartaruga HG

Tomas
fonte
Verifique novamente a inclusão de uma imagem.
Bill Keller
0

Além da excelente resposta de Samaursa, você pode usar as evolveextensões prunecomo uma versão segura e recuperável stripque permitirá que você volte no caso de fazer algo errado.

Eu tenho esses alias no meu .hgrc:

 # Prunes all draft changesets on the current repository
 reset-tree = prune -r "outgoing() and not obsolete()"
 # *STRIPS* all draft changesets on current repository. This deletes history.
 force-reset-tree = strip 'roots(outgoing())'

Note-se que prunetambém tem --keep, assim como strip, para manter o diretório de trabalho intacta permitindo-lhe comprometer os arquivos.

Euller Borges
fonte