Exclua todos os changesets locais e reverta para árvore


95

Estou usando o Mercurial e me meti em uma confusão terrível localmente, com três cabeças. Não posso enviar push e só quero deletar todas as minhas alterações e commits locais e começar de novo com um código totalmente limpo e um histórico limpo.

Em outras palavras, quero terminar com (a) exatamente o mesmo código localmente que existe na ponta do branch remoto e (b) sem histórico de quaisquer commits locais.

Eu sei que hg update -Csubstitui todas as alterações locais. Mas como excluo qualquer commit local?

Para ser claro, não tenho interesse em preservar nenhum dos trabalhos que fiz localmente. Só quero a maneira mais simples de voltar a um checkout local totalmente limpo.


Respostas:


129

Quando a maneira mais simples (uma nova hg clone) não é prática, eu uso hg strip:

% hg outgoing -l 1
% hg strip $rev # replace $rev with the revision number from outgoing

Repita até hg outgoingficar quieto. Observe que hg strip $revoblitera $reve todos os seus descendentes.

Observe que pode ser necessário primeiro habilitar stripnas configurações do Mercurial .

PS: uma abordagem ainda mais inteligente é usar a linguagem revset e fazer:

% hg strip 'roots(outgoing())'

1
Obrigado! Acabei em uma situação que isso resolveu perfeitamente, sem qualquer problema.
eswald

1
Isso me salvou das grandes correções acima, muito simples, obrigado!
David C

3
Se alguém tiver problemas hg strip 'roots(outgoing())'para chegar ao trabalho por não reconhecer 'roots(outgoing())'. Consegui fazer funcionar hg strip "roots(outgoing())".
jsea

@SombreErmine em cmd.exe, sim.
apenas alguém de

21

Você desejará fazer um clone local onde preserva apenas os conjuntos de alterações que também estão presentes no repositório remoto. Use TortoiseHg , hg logou similar para descobrir qual de suas revisões é a última revisão que você não fez (aquela antes da bagunça começar). Usar hg outgoingpode ajudar aqui - ele listará todos os conjuntos de alterações que você fez - escolha um número de revisão anterior a qualquer um deles.

Se a revisão de destino for chamada goode seu clone for chamado foo, faça:

hg clone -r good foo foo-clean

Esta será uma operação local rápida - não há razão para baixar tudo novamente . O foo-cleanclone conterá apenas conjuntos de alterações até a revisão good. Agora você pode substituir foo-clean/.hg/hgrcpor foo/.hg/hgrcpara preservar suas configurações locais de repositório, como o caminho padrão push / pull.

Quando estiver satisfeito foo-cleancom tudo de que você precisa foo, basta excluir fooe renomear foo-cleanpara foo. Faça um hg pullpara obter quaisquer novos changesets do repositório remoto em seu clone e continue normalmente.


Se ninguém enviou novos conjuntos de alterações para o repositório remoto, então é muito simples determinar qual revisão você deseja usar como goodacima: hg id defaultirá lhe dizer o ID da dica no repositório remoto.


Estou tendo a mesma situação, mas também tenho muitos arquivos no diretório repo, mas estão no hgignore. Não é possível instalar o hg strip e gostaria de descartar os commits locais sem substituir o clone inteiro. Alguma ideia? - Ah! Se eu não adicionei nenhum arquivo, poderei apenas copiar o outro clone em meu diretório antigo !?
Peteter de

No entanto, tome cuidado com este método se você tiver vários ramos. A clonagem até uma revisão especificada obtém apenas os conjuntos de alterações no ramo da revisão especificada. Você pode então ter que fazer hg pull -ra última revisão "boa" de cada branch adicional.
Yitz

9

Está bem. Portanto, apenas exclua todo o material local, hg inito novo repositório local e hg pulla última dica que você tiver. Não se esqueça de hg updatedepois disso.


Obrigado. Quando você diz 'deletar todas as coisas locais', você quer dizer deletar todo o repositório ou apenas minhas alterações? O que hg init faz (pesquisei, mas não consigo ver uma explicação simples) e preciso usar sinalizadores com ele? Ele excluirá coisas como minhas preferências .hgrc do Mercurial?
Richard

Atualização: se eu deletar tudo no diretório raiz do projeto, digite 'hg init' e recebo 'abort: repository. já existe!'. Eu preciso configurar e trabalhar em um novo diretório? Eu prefiro não, se possível ... certamente deve haver uma maneira simples de matar tudo o que fiz localmente ?!
Richard

Sim, exclua tudo, incluindo todo o material do repositório. Comece a partir de uma nova pasta limpa. Você pode salvar suas preferências em um arquivo de backup e, em seguida, restaurá-las no novo repositório criado com o hg init reponame. Detalhes sobre init e outras coisas: hgbook.red-bean.com/read/mercurial-in-daily-use.html
alemjerus

6
alemjerus: hg init+ hg pull= hg cloneA diferença é que hg cloneé um bom .hg/hgrcarquivo para você e que hg cloneusará hardlinks para economizar espaço ao clonar no mesmo sistema de arquivos.
Martin Geisler

Richard: A saída de hg help initestá aqui: selenic.com/mercurial/hg.1.html#init Mas talvez isso seja muito conciso? Envie um e-mail para nossa lista de discussão se precisar de mais ajuda! Veja: mercurial.selenic.com/wiki/MailingLists
Martin Geisler

5

Você pode usar

revisão de faixa hg

para eliminar qualquer revisão e sua subárvore em seu repositório local.

https://www.mercurial-scm.org/wiki/Strip

Mas não tente usá-lo para nada que já tenha sido enviado.


Você pode usá-lo em uma revisão pública, mas se puxar novamente, ele reaparecerá. (hg strip só funciona com o repositório local.)
Mike Rosoft

2

Basta excluir tudo o que você tem em seu sistema local e clonar novamente o repositório remoto.


2
hg strip `hg out --modelo" {rev} {autor} \ n "| grep YOUR_AUTHOR_NAME | cut -d "" -f 1`

faz o truque para mim.

Ele remove todas as revisões que não foram enviadas para o repositório padrão que foram criadas com o seu nome de autor.

Você também pode usar este estilo para torná-lo não verificando com o repositório padrão, mas com outro Repositório

hg strip `hg out OTHER_REPO_ALIAS --modelo" {rev} {autor} \ n "| grep YOUR_AUTHOR_NAME | cut -d "" -f 1`

0

Se você estiver usando o TortoiseHg, uma maneira simples de sair de uma (pequena) bagunça é primeiro atualizar para a revisão mais recente, depois selecionar seus conjuntos de alterações e iniciar a "fusão com local". Quando a caixa de diálogo de mesclagem aparecer, simplesmente clique no pequeno ícone '+' para revelar algumas opções extras, uma das quais é "descartar conjuntos de alterações da revisão de destino de mesclagem (outra)". Isso significa que seus conjuntos de alterações ainda estarão no repo e serão enviados por push, mas não terão efeito, porque serão descartados na fusão. Se você tiver muitos conjuntos de alterações abrangendo várias cabeças, talvez não queira poluir o repo dessa maneira, mas é uma correção simples e vale a pena considerar se os conjuntos de alterações que você está descartando contêm dados que você pode querer consultar posteriormente.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.