Mercurial - volte para a versão antiga e continue a partir daí

249

Estou usando o Mercurial localmente para um projeto (é o único repositório que não há como pressionar / puxar para / de qualquer outro lugar).

Até o momento, tem uma história linear. No entanto, a coisa atual em que estou trabalhando agora é uma péssima abordagem e quero voltar à versão antes de iniciá-la e implementá-la de uma maneira diferente.

Estou um pouco confuso com os comandos branch/ revert/ update -Cno Mercurial. Basicamente, quero reverter para a versão 38 (atualmente em 45) e ter meus próximos commits 38 como pai e continuar a partir daí. Não me importo se as revisões 39-45 são perdidas para sempre ou acabam em um ramo sem saída próprio.

Qual comando / conjunto de comandos eu preciso?

Paolo
fonte
6
Para qualquer pessoa interessada, isso apareceu na barra lateral relacionada, o que é uma ótima explicação para reverter vs atualizar: stackoverflow.com/questions/2506803/…
Paolo

Respostas:

150
hg update [-r REV]

Se posteriormente você confirmar, criará efetivamente uma nova ramificação. Em seguida, você poderá continuar trabalhando apenas neste ramo ou, eventualmente, mesclar o existente.

furgão
fonte
6
O próximo commit criará uma nova ramificação. Se você não tiver certeza, basta fazer um backup do seu repositório (com cópia de trabalho), experimentá-lo - não gosta do resultado -> começar do zero sem nenhum custo
van
Esta é uma resposta duvidosa, pois combina as alterações atuais com a revisão antiga, que provavelmente é o que você não deseja fazer. A resposta correta deve ser hg revert.
Trevor de Koekkoek 3/11
A resposta é boa, exceto o pouco sobre mesclagem (não acho que o interlocutor queira mesclar).
ctrl-alt-Delor
3
O @NeonWarge REV é simplesmente um espaço reservado para a revisão. Pode ser seu número, seu hash, um marcador e assim por diante. Trevor: isso não é duvidoso porque não mescla nada. Não precisa de.
21419 DanMan
401

Aqui está a folha de dicas sobre os comandos:

  • hg updatealtera sua revisão pai da cópia de trabalho e também altera o conteúdo do arquivo para corresponder a essa nova revisão pai. Isso significa que novas confirmações continuarão com a revisão para a qual você atualiza.

  • hg revertaltera apenas o conteúdo do arquivo e deixa a revisão pai da cópia de trabalho em paz. Você geralmente usa hg revertquando decide que não deseja manter as alterações não feitas que você fez em um arquivo em sua cópia de trabalho.

  • hg branchinicia uma nova ramificação nomeada. Pense em uma ramificação nomeada como um rótulo que você atribui aos conjuntos de alterações. Portanto, se o fizer hg branch red, os seguintes conjuntos de alterações serão marcados como pertencentes ao ramo "vermelho". Essa pode ser uma boa maneira de organizar conjuntos de mudanças, especialmente quando pessoas diferentes trabalham em ramificações diferentes e você deseja ver mais tarde de onde se originou um conjunto de mudanças. Mas você não quer usá-lo na sua situação.

Se você usar hg update --rev 38, os conjuntos de alterações 39 a 45 serão deixados como um beco sem saída - uma cabeça pendente como a chamamos. Você receberá um aviso ao pressionar, pois estará criando "várias cabeças" no repositório para o qual você pressiona. O aviso está lá, já que é meio indelicado deixar essas cabeças por aí, pois sugerem que alguém precisa fazer uma fusão. Mas no seu caso, você pode simplesmente seguir em frente e hg push --forcejá que realmente deseja deixá-lo em espera.

Se você ainda não colocou a revisão 39-45 em outro lugar, mantenha-a em sigilo. É muito simples: hg clone --rev 38 foo foo-38você receberá um novo clone local que contém apenas a revisão 38. Você pode continuar trabalhando foo-38e enviar os novos (bons) conjuntos de alterações criados. Você ainda terá as revisões antigas (ruins) no seu fooclone. (Você é livre para renomear os clones da maneira que desejar, por exemplo, foopara foo-bade foo-38para foo.)

Por fim, você também pode usar hg revert --all --rev 38e confirmar. Isso criará uma revisão 46 que parece idêntica à revisão 38. Você continuará trabalhando a partir da revisão 46. Isso não criará uma bifurcação no histórico da mesma maneira explícita que hg updatefez, mas, por outro lado, você não se queixará de ter cabeças múltiplas. Eu usaria hg revertse estivesse colaborando com outras pessoas que já fizeram seu próprio trabalho com base na revisão 45. Caso contrário, hg updateé mais explícito.

Martin Geisler
fonte
2
Resposta INCRÍVEL. Eu usei hg revert --all --rev ## e ele salvou minha bunda: D
Van Thoai Nguyen
1
Não seria melhor fechar também o ramo da cabeça pendente? Isso impediria avisos futuros no repositório. Veja stackoverflow.com/a/3688320/900130
Zoltán
note: hg revert --all --rev xxx modificará os arquivos locais necessários para reverter de onde você está no seu repositório local. Portanto, você precisa atualizar antes para onde deseja reverter.
31517 Vincent
Para ramificar uma versão anterior, primeiro tive que fazer uma reversão e depois uma atualização. Dito isto, uma explicação menos opaca do que a maioria.
CodeLurker
30

Acabei de encontrar um caso de necessidade de reverter apenas um arquivo para a revisão anterior, logo após ter feito o commit e o push. A sintaxe abreviada para especificar essas revisões não é coberta pelas outras respostas, então aqui está o comando para fazer isso

hg revert path/to/file -r-2

Isso -2reverterá para a versão antes da última confirmação, usando -1apenas reverterá as alterações não confirmadas atuais.

hyde
fonte
1
Eu acho isso extremamente útil. Obviamente, para a opção -r, você pode simplesmente fornecer o número da revisão
Alex
Você também pode selecionar uma revisão específica. por exemplo,hg revert path/to/file -r478
Mt
7

IMHO, hg strip -r 39combina melhor com este caso.

Ele requer que a extensão mq seja ativada e tem as mesmas limitações do "método de repo de clonagem" recomendado por Martin Geisler: Se o conjunto de alterações foi publicado de alguma forma, (provavelmente) retornará ao seu repo em algum momento porque você mudou apenas seu repo local.

magras
fonte
Não sabia sobre este. Mais fácil e limpo do que excluir e clonar novamente o repositório. Obrigado.
Reintegrar Monica - notmaynard
6

Após o uso hg update -r REV, não ficou claro na resposta sobre como confirmar essa alteração para que você possa fazer o push.

Se você apenas tentar confirmar após a atualização, o Mercurial não acha que há alterações.

Eu tive que primeiro fazer uma alteração em qualquer arquivo (digamos em um README) para que o Mercurial reconhecesse que eu fiz uma nova alteração, então eu poderia confirmar isso.

Isso então criou duas cabeças, como mencionado.

Para me livrar da outra cabeça antes de pressionar, segui a etapa Sem fusões para resolver essa situação.

Eu fui capaz de empurrar.

Brian Gershon
fonte
você pode fazer um commit --close-branchno ramo antigo. Você também pode push -fempurrar novas cabeças, mas isso pode causar confusão quanto à atual.
ctrl-alt-Delor
5

As respostas acima foram muito úteis e eu aprendi muito. No entanto, para minhas necessidades, a resposta sucinta é:

hg revert --all --rev ${1}

hg commit -m "Restoring branch ${1} as default"

Onde ${1} é o número da revisão ou o nome da ramificação. Na verdade, essas duas linhas fazem parte de um script bash, mas funcionam bem por conta própria, se você quiser fazê-lo manualmente.

Isso é útil se você precisar adicionar um hotfix a uma ramificação de lançamento, mas precisar construir a partir do padrão (até obtermos nossas ferramentas de CI corretas e capazes de construir a partir de ramificações e posteriormente acabar com as ramificações de liberação).

Brian Carr
fonte
1

Eu instalaria o Tortoise Hg (uma GUI gratuita para o Mercurial) e usaria isso. Você pode clicar com o botão direito do mouse em uma revisão à qual deseja retornar - com todas as mensagens de confirmação na frente dos seus olhos - e em 'Reverter todos os arquivos'. Torna intuitivo e fácil reverter para frente e para trás entre as versões de um conjunto de arquivos, o que pode ser realmente útil se você deseja estabelecer quando um problema apareceu pela primeira vez.

Geoff Kendall
fonte