A mudança mercurial muda para uma nova filial

124

Tenho várias alterações confirmadas no meu repositório local, mas ainda não foram enviadas. Como em um recurso está demorando mais do que o esperado, desejo trocar essas alterações em uma ramificação nomeada antes de enviar por push. Como posso fazer isso?

Casebash
fonte

Respostas:

153

Conforme sugerido por Mark, o MqExtension é uma solução para o seu problema. IMHO um fluxo de trabalho mais simples é usar a extensão rebase . Suponha que você tenha uma história como esta:

@  changeset:   2:81b92083cb1d
|  tag:         tip
|  summary:     my new feature: edit file a
|
o  changeset:   1:8bdc4508ac7b
|  summary:     my new feature: add file b
|
o  changeset:   0:d554afd54164
   summary:     initial

Isso significa que a revisão 0é a base na qual você começou a trabalhar no seu recurso. Agora você quer ter revisões 1-2em uma ramificação nomeada, digamos my-feature. Atualize para revisão 0e crie esse ramo:

$ hg up 0
$ hg branch my-feature
$ hg ci -m "start new branch my-feature"

A história agora é assim:

@  changeset:   3:b5939750b911
|  branch:      my-feature
|  tag:         tip
|  parent:      0:d554afd54164
|  summary:     start new branch my-feature
|
| o  changeset:   2:81b92083cb1d
| |  summary:     my new feature: edit file a
| |
| o  changeset:   1:8bdc4508ac7b
|/   summary:     my new feature: add file b
|
o  changeset:   0:d554afd54164
   summary:     initial

Use o rebasecomando para mover as revisões 1-2para a revisão 3:

$ hg rebase -s 1 -d 3

Isso resulta no seguinte gráfico:

@  changeset:   3:88a90f9bbde7
|  branch:      my-feature
|  tag:         tip
|  summary:     my new feature: edit file a
|
o  changeset:   2:38f5adf2cf4b
|  branch:      my-feature
|  summary:     my new feature: add file b
|
o  changeset:   1:b5939750b911
|  branch:      my-feature
|  summary:     start new branch my-feature
|
o  changeset:   0:d554afd54164
   summary:     initial

É isso aí. Conforme mencionado nos comentários à resposta de Mark, mover-se por conjuntos de alterações já enviados geralmente é uma má idéia, a menos que você trabalhe em uma equipe pequena, na qual poderá se comunicar e reforçar a manipulação do histórico.

Oben Sonne
fonte
4
IMHO, a desvantagem desta solução é que ela introduz um commit fictício "start new branch my-feature" (isto é, um que não altera nenhum arquivo).
sschuberth
9
@sschuberth: Eu acho que ser explícito é uma coisa boa aqui. Se o conjunto de alterações extra for um problema para você, combine-o com o seguinte (por exemplo, usando o foldcomando da extensão histedit agora incorporada ).
Oben Sonne
6
@AmirRachum: hg log -G( GraphlogExtension ). Tirei algumas linhas manualmente, mas ela também pode ter sido renderizada automaticamente usando estilos de log personalizados .
Oben Sonne
1
@sschuberth Eu concordo. Minha solução alternativa é refazer sua consolidação não-fictícia no pai do commit fictício com o sinalizador --keepbranches e, em seguida, hg retira seu commit fictício. É muito trabalhoso mudar o nome de um ramo, mas às vezes Mercurial é burro assim.
weberc2
30

Você pode usar o MqExtension . Digamos que os changesets a serem movidos são as revisões 1-3:

hg qimport -r 1:3    # convert revisions to patches
hg qpop -a           # remove all them from history
hg branch new        # start a new branch
hg qpush -a          # push them all back into history
hg qfin -a           # finalize the patches
Mark Tolonen
fonte
Quero importar 63:64 e 66:68. Estou ficando revisão 65 não é o pai de 64
Casebash
O que você quer fazer com 65? O Mq só pode converter conjuntos de alterações consecutivos de uma cabeça. Ele transforma conjuntos de alterações normalmente imutáveis ​​em patches mutáveis ​​que podem ser editados. Isso altera os hashes (afetando todos os filhos), para que você não possa pular.
precisa saber é o seguinte
Eu tenho um número de alterações (incluindo 65) que eu fiz no ramo principal e
enviei
1
Não edite conjuntos de alterações que foram enviados por push. Mq altera os hashes para que eles sejam efetivamente novos conjuntos de alterações. Edite apenas o histórico que não foi enviado.
precisa saber é o seguinte
Se você já empurrou 65, definitivamente não deve mover 63 e 64, e apenas optar por mover 66:68 (novamente, somente se você não os empurrou).
Matt #
9

Eu prefiro a solução de patch descrita aqui por Mark Tolonen

O que eu tenho:

hg log -G

#default branch
@  changeset:   3:cb292fcdbde1
|
o  changeset:   2:e746dceba503
|
o  changeset:   1:2d50c7ab6b8f
|
o  changeset:   0:c22be856358b

O que eu quero:

  @  changeset:   3:0e85ae268e35
  |  branch:      feature/my_feature
  |
  o  changeset:   2:1450cb9ec349
  |  branch:      feature/my_feature
  |
  o  changeset:   1:7b9836f25f28
  |  branch:      feature/my_feature
  |
 /
|
o  changeset:   0:c22be856358b

comandos do mercurials:

hg export -o feature.diff 1 2 3
hg update 0
hg branch feature/my_feature
hg import feature.diff

Aqui está o estado do meu repositório local

@  changeset:   6:0e85ae268e35
|  branch:      feature/my_feature
|
o  changeset:   5:1450cb9ec349
|  branch:      feature/my_feature
|
o  changeset:   4:7b9836f25f28
|  branch:      feature/my_feature
|
| o  changeset:   3:cb292fcdbde1
| |
| o  changeset:   2:e746dceba503
| |
| o  changeset:   1:2d50c7ab6b8f
|/
|
o  changeset:   0:c22be856358b

Agora eu preciso excluir as revisões 1 2 e 3 do meu ramo padrão. Você pode fazer isso com o comando strip da extensão do mq. hg stripremove o conjunto de alterações e todos os seus descendentes do repositório.

Habilite a extensão adicionando as seguintes linhas ao seu arquivo de configuração (.hgrc ou Mercurial.ini):

vim ~/.hgrc e adicione :

[extensions]
mq =

E agora retire esse repositório da revisão 1.

hg strip 1

E aqui estamos

@  changeset:   3:0e85ae268e35
|  branch:      feature/my_feature
|
o  changeset:   2:1450cb9ec349
|  branch:      feature/my_feature
|
o  changeset:   1:7b9836f25f28
|  branch:      feature/my_feature
|
o  changeset:   0:c22be856358b

nota: changesets são diferentes, mas as revisões são as mesmas

Guillaume Vincent
fonte
5

Para aqueles inclinados a usar GUI

  1. Vá para Tortoise Hg-> File-> Settingsdepois marque rebase.

insira a descrição da imagem aqui

  1. Reinicie a interface do usuário da tartaruga

  2. Crie uma nova ramificação para onde você moverá as alterações. Clique no nome do ramo atual -> escolha Open a new named branch-> escolha o nome do ramo.

insira a descrição da imagem aqui

  1. Se as alterações que você deseja mover não foram feitas public(por exemplo draft), vá para 5. (Se as alterações já foram publicadas e você não é um desenvolvedor sênior, você deve conversar com alguém sênior (obter um bode expiatório), pois você pode estragar tudo. , Eu não assumo nenhuma responsabilidade :)).

Vá para View-> Show Console(ou Ctrl+ L) e, em seguida, escreva no console hg phase -f -d 2- onde 2 é a revisão mais baixa, você passará para o novo ramo.

  1. Vá para ramificação e revisão (deve ser a revisão superior, se você estiver movendo as alterações para uma nova ramificação criada na etapa 3.) Right Mouse->Update

  2. Vá para o ramo e a versão em que você moverá as alterações de Right Mouse-> Modify History->Rebase

insira a descrição da imagem aqui

  1. Clique Rebasee reze para que não haja conflitos, se necessário.

  2. Envie alterações, neste ponto, todas as revisões ainda devem ser draft.

  3. Vá para a revisão superior na ramificação na qual você estava movendo as alterações para Right Mouse-> Change Phase to-> Public.

insira a descrição da imagem aqui

Espero que isso poupe algum tempo.

Matas Vaitkevicius
fonte
Bom trabalho! tentando fazer isso, apenas uma pergunta: por que mudar a fase para pública no final? "Qualquer conjunto de alterações visto em um repositório remoto é público"; portanto, quando você pressiona, ele não é definido como público?
21716 Joshua Duxbury
@JoshLeeDucks Ao pressionar, eles não mudam mais para publicautomagicamente (pelo menos para mim, eles não).
Matas Vaitkevicius