Como faço para colocar um monte de mudanças não comprometidas de lado enquanto trabalho em outra coisa


98

Se eu tiver um monte de alterações não confirmadas e quiser deixá-las de lado enquanto trabalho em outra coisa, e mais tarde (fi depois de vários dias), volte a elas e continue trabalhando. Qual seria o fluxo de trabalho mais fácil para fazer isso? (Até agora eu só tenho experiência com as funcionalidades básicas do Mercurial). Meu método usual era criar um novo branch usando clone, mas pode haver maneiras melhores.

Respostas:


133

Você tem várias opções:

  1. Arquive os itens. Isso salva as alterações e as remove do diretório de trabalho para que a ramificação possa continuar. Não cria um conjunto de mudanças.

    hg shelve --all --name "UnfinishedChanges"
    
    hg unshelve --name "UnfinishedChanges"
    

    Atualizar / editar : podem ser necessárias versões mais recentes do mercurial

    hg shelve -n "UnfinishedChanges"
    hg unshelve "UnfinishedChanges"
    

    Você ainda pode usar --namecomo uma alternativa para -n, mas o mercurial parece não gostar --namemais. Além disso, o --allnão é mais necessário e o mercurial vai de fato pirar com ele.

  2. Patch enfileire os itens usando mq. Isso não é muito diferente de arquivar em alguns aspectos, mas se comporta de maneira diferente. O resultado final é o mesmo, as alterações são removidas e podem ser reaplicadas opcionalmente mais tarde. Quando enviados, os patches são conjuntos de alterações lógicos; quando ativados, eles são salvos em outro lugar e não fazem parte do histórico do conjunto de alterações.

    hg qnew "UnfinishedWork"
    hg qrefresh
    hg qpop
    
    hg qpush "UnfinishedWork"
    
  3. Comprometa-os localmente, atualize para o conjunto de mudanças anterior e continue trabalhando e faça uso de branches anônimos (ou cabeçotes múltiplos). Se você quiser as mudanças, pode mesclar cabeçalhos. Se você não quiser as alterações, pode remover o conjunto de alterações.

    hg commit -m"Commiting unfinished work in-line."
    hg update -r<previous revision>
    
    hg strip -r<revision of temporary commit>
    
  4. Comprometa-os com um branch nomeado. O fluxo de trabalho então se torna o mesmo da opção 3 - mesclar ou separar quando estiver pronto.

    hg branch "NewBranch"
    hg commit -m"Commiting unfinished work to temporary named branch."
    hg update <previous branch name>
    

Pessoalmente, uso a opção 3 ou 4, pois não me importo em remover conjuntos de alterações ou fazer check-in do código parcial (contanto que isso não seja empurrado eventualmente). Isso pode ser usado em conjunto com o novo material da Fase para ocultar seus conjuntos de mudanças locais de outros usuários, se necessário.

Também uso o rebasecomando para mover conjuntos de alterações para evitar mesclagens, onde uma mesclagem não acrescentaria nada ao histórico do código. Mesclagens Tenho a tendência de salvar para atividades entre ramos importantes (como ramos de lançamento) ou atividades de um ramo de recurso de vida mais longa. Há também o histeditcomando que uso para compactar conjuntos de alterações, onde a "tagarelice" deles reduz o valor.

As filas de patches também são um mecanismo comum para fazer isso, mas têm semântica de pilha. Você empurra e ativa os patches, mas um patch que está "por baixo" de outro patch na pilha requer que o que está no topo também seja empurrado.

Aviso , como com todas essas opções, se os arquivos tiverem mais alterações desde as alterações temporárias que você arquivou / enfileirou / ramificou, haverá resolução de mesclagem necessária ao desfazer o arquivamento / empurrar / mesclar.


Obrigado pela ótima resposta e exemplos úteis. Você sabe se usar marcadores hg também é uma opção?
Erik

@Erik Possivelmente, mas não tenho experiência em usá-lo.
Adam Houldsworth

2
marcadores podem ser usados ​​para ajudar com a opção 3 - você pode usar um para rotular a revisão que você criou para esconder sua mudança. Eles não podem fazer a tarefa sozinhos.
Steve Kaye

opção --allnão é reconhecida. é um comportamento padrão arquivar todas as alterações de qualquer maneira.
naXa de

@naXa Olá amigo, se um dos meus comandos estiver um pouco incorreto (talvez porque a versão tenha mudado), sinta-se à vontade para editar a resposta e aprovarei se necessário :-)
Adam Houldsworth

23

Pessoalmente, não gosto de nenhuma das respostas postadas até agora:

  1. Não gosto de clone branching porque gosto que cada projeto tenha apenas um diretório. Trabalhar em diretórios diferentes ao mesmo tempo bagunça completamente a história dos arquivos recentes dos meus editores. Sempre acabo mudando o arquivo errado. Então eu não faço mais isso.
  2. Eu uso shelvepara soluções rápidas (apenas para mover minhas alterações não confirmadas para outro branch, se perceber que estou no ramo errado). Você está falando sobre dias, de jeito nenhum eu engavetaria algo por dias.
  3. Eu acho que mqé muito complicado para uma situação tão comum

Acho que a melhor maneira é simplesmente confirmar suas alterações, depois voltar para o changeset antes de iniciar essas alterações e trabalhar a partir daí. Existem alguns problemas menores, deixe-me ilustrar:

Digamos que você tenha o changeset A. Em seguida, você inicia suas alterações. Neste ponto, você deve deixá-lo de lado por um tempo. Em primeiro lugar, comprometa o seu trabalho:

hg ci -m "Working on new stuff"

Se desejar, você pode adicionar um marcador para tornar mais fácil voltar mais tarde. Eu sempre crio marcadores para meus branches anônimos.

hg bookmark new-stuff

Volte para o conjunto de alterações antes dessas modificações

hg update A

A partir daqui, você trabalha e gera o changeset C. Agora que você tem 2 cabeças (B e C), você será avisado quando tentar empurrar. Você pode enviar apenas um branch, especificando o chefe desse branch:

hg push -r C

Ou você pode alterar a fase do new-stuffbranch para secreta. Changesets secretos não serão enviados.

hg phase -r new-stuff --secret --force

Obrigado pela resposta detalhada! Eu realmente gosto de ler o fluxo de trabalho das pessoas para esses problemas (comuns?).
Erik

Acho que mqé um pouco complicado apenas para esta situação, mas tem uma gama de utilizações suficientemente ampla, incluindo esta, que vale a pena investir tempo para se tornar fluente com ele.
Norman Gray

12

Para manter as alterações locais não confirmadas, a maneira mais fácil para mim é salvá-las como um arquivo de patch.

hg diff > /tmp/`hg id -i`.patch

e quando você precisa retornar ao estado anterior:

hg up <REV_WHERE_SAVED>
hg patch --no-commit /tmp/<REV_WHERE_SAVED>.patch

Eu me despiria /tmpe hg id -ifuncionaria no Windoze também.
anatoly techtonik

E hg upnão é necessário lá.
anatoly techtonik

1
@techtonik O que acontecerá se eu aplicar o patch em outra revisão? Especialmente se os arquivos corrigidos forem modificados.
mapcuk de

O Mercurial tentará mesclá-lo e você terá que lidar com o conflito de qualquer maneira.
anatoly techtonik

6

Você pode simplesmente clonar seu repo várias vezes. Eu costumo ter um clone raiz, então vários filhos a partir daí. Exemplo:

  • MyProject.Root
  • MyProject.BugFix1
  • MyProject.BugFix2
  • MyProject.FeatureChange1
  • MyProject.FeatureChange2

Os 4 filhos são todos clonados a partir da raiz e empurram / puxam para / da raiz. O root então faz push / pull do repositório master na rede / internet em algum lugar. A raiz atua como uma espécie de área de preparação pessoal.

Portanto, no seu caso, você simplesmente clonaria um novo repo e começaria a trabalhar. Deixe seu trabalho 'arquivado' sozinho no outro repo. É simples assim.

A única desvantagem é o uso de espaço em disco, mas se isso fosse uma preocupação, você não estaria usando DVCS de qualquer maneira;) Ah, e meio que polui sua lista de "projetos recentes" do Visual Studio, mas e aí.

[Editar os seguintes comentários]: -

Para concluir então ... o que você está fazendo está perfeitamente bem e normal. Eu diria que é a melhor maneira possível de trabalhar quando o seguinte for verdade: 1) é de curta duração 2) você não precisa colaborar com outros desenvolvedores 3) as alterações não precisam sair do seu PC até que sejam confirmadas / push time.


Alguma razão para não usar branches? É para isso que eles servem e são consideravelmente mais rápidos do que clonagem de repo.
Adam Houldsworth

Em minha pergunta, afirmei o seguinte: Meu método usual era criar um novo branch usando clone, mas pode haver maneiras melhores.
Erik

1
@AdamHouldsworth, tecnicamente são ramos ... apenas aqueles de curta duração. Fazer um galho com nome para um trabalho de curta duração é completamente estúpido. Abusa do propósito denominado ramos que são para histórias de trabalho de longa duração.
nbevans

@NathanE Se você acha que branches nomeados para trabalhos de curta duração é "completamente estúpido", então também há ramificações anônimas, prateleiras ou fila de correções como outras opções leves. A reclonagem, na minha opinião, é igualmente estúpida em face de outras opções - um benefício potencial é ter dois conjuntos de código abertos em duas instâncias do VS, mas raramente tenho que fazer isso, então usar clones, é claro, não me sirva. Apenas para esclarecimento, eu não fui o downvoter.
Adam Houldsworth

@NathanE Eles também não são exclusivos para "histórias de trabalho duradouras", isso é apenas algo em que eles são bons se você seguir a integração contínua. Direto dos documentos : "Ramificações ocorrem se as linhas de desenvolvimento divergem", se você está arquivando um item de trabalho para trabalhar em outra coisa, isso para mim soa como divergência, por mais duradouro que seja.
Adam Houldsworth
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.