Pergunta sobre mercurial, rollback – No mercurial, como aplico um patch reverso a um arquivo específico?

19

Relacionado aMercurial: Mesclando um arquivo entre filiais em um repo Estou tentando executar uma operação de restauração em um único arquivo, mesmo que esse arquivo tenha sido um dos muitos participantes na revisão que está sendo restaurada.

HG sendo a ferramenta orientada a changeset que é, não quer operar em arquivos.

O mais próximo que pude encontrar foi usar hg export para criar um diff, editar manualmente o diff e, em seguida, hg import para corrigir o arquivo na ordem inversa.

..mas então eu bati nessa situação chata ondehttp://hgbook.red-bean.com/read/finding-and-fixing-mistakes.html afirma que há uma opção - reversa parahg patch quando não houver.

Então, a coisa mais próxima que posso pensar é gerar um patch editado manualmente, e então usar o patch de baunilha -R para aplicar um patch reverso.

ohg backout comando parece ser útil aqui, mas na verdade é um arenque vermelho.

Tem que ser um jeito melhor, não?

A opção --reverse éremendo, nãopatch hg. balpha

Sua resposta

3   a resposta
22

Você pode fazer isso usando apenas o-I (inclua nomes correspondentes aos padrões fornecidos) argumento para o backout com uma única linha:

hg backout --merge -I thefiletorevert -m 'message' OFFENDINGREVISIONID

Exemplo de Script:

hg init testrepo
cd testrepo
echo -e "line1\n\nline3" > file1
echo -e "line1\n\nline3" > file2
hg commit -A -m 'changes to two files'
perl -pi -e 's/line1/line 1/' file1
perl -pi -e 's/line1/line 1/' file2
hg commit -m 'put spaces in line1'
perl -pi -e 's/line3/line 3/' file1
perl -pi -e 's/line3/line 3/' file2
hg commit -m 'put spaces in line3'
hg backout --merge -I file1 -m 'remove spaces from line1' 1

Amostra de saída:

adding file1
adding file2
reverting file1
created new head
changeset 3:6d354f1ad4c5 backs out changeset 1:906bbeaca6a3
merging with changeset 3:6d354f1ad4c5
merging file1
0 files updated, 1 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)

Conteúdo do arquivo resultante:

file1:line1
file1:line 3
file2:line 1
file2:line 3

observe que arquivo1 está faltando espaço na linha um após o backout do changeset do meio, e o log detalhado mostra apenas um arquivo alterado no backout:

$ hg log -v -r tip
changeset:   3:6d354f1ad4c5
tag:         tip
parent:      1:906bbeaca6a3
user:        Ry4an Brase <[email protected]>
date:        Mon Sep 14 12:17:23 2009 -0500
files:       file1
description:
remove spaces from line1
Legal. Se você fosse postar um exemplo com o retorno de uma mudança enterrada, eu a marcaria corretamente. djsadinoff
retrocedendo o meio do changeset Ry4an Brase
Eu acho que entendo esta solução, mas este caso parece mais simples que o meu, já que aqui você está desistindo (um dos arquivos) da mudança de ponta, enquanto o balpha lida com meu caso mais geral de fazer uma mudança histórica. djsadinoff
Não, isso funcionaria bem para um changeset não-tip, embora isso exigiria que você 'hg merge' no final. No entanto, você ainda teria um gráfico de histórico que reflete com precisão o que aconteceu e altera o parentesco, ao contrário do copy-it-over do balpha, que produziria um changelog linear. Ry4an Brase
6

Aqui está o que eu faria: Use um novo clone da revisão da dica.

hg backout --merge -r revision_where_the_change_happened

para mesclar as alterações invertidas na cópia de trabalho.

Agora copie o arquivo em questão para sua cópia de trabalho regular e confirme

hg commit -m "Reversed the changes to file.h made in revision bla"

e jogue fora o clone que você criou acima.

Dessa forma, o mercurial não sabe que existe uma conexão entrerevision_where_the_change_happened e este commit. Se você quiser mercurial para lembrar isso, em vez disso, um

hg revert {all files except the one in question}

depois de mesclar o backout, confirme na cópia de trabalho e antes de confirmar. Pela segunda maneira, você não precisa trabalhar em um clone, porque você quer manter o commit do backout.

Eu diria que a escolha de qual caminho você usa depende de quão grande parte do changeset foi a alteração específica do arquivo.

3

Use o comando revert.

hg revert -r1 file

Isso deve reverter o conteúdo do arquivo para a versão na revisão 1. Você pode, então, editá-lo e confirmá-lo normalmente.

É correto que você possa redefinir um arquivo para uma versão anterior como essa. Funcionaria aqui mesmo se o arquivo não fosse alterado desde a versão ruim. Mas, se mais edições forem feitas, uma simples reversão não funcionará. Em vez disso você teria que atualizar para a revisão ruim, reverter o arquivo para uma boa versão, fazer um commit e mesclar as duas cabeças. Eu acredito que isso é basicamente o que o backout faz por você. Martin Geisler

Perguntas relacionadas