Pergunta

Eu fiz uma mudança em um script e cometeu. Então eu fiz algumas outras mudanças, e empurrou-os para um repositório remoto e tal.

Então eu percebi que a primeira mudança que eu mencionei era estúpido, e quer desfazer-lo .. Can I "Ignorar" que cometeu, sem copiar manualmente / colar o diff?

Como um exemplo: Eu tenho dois arquivos, a.py e b.py:

Commit 1:
I delete a function in a.py

Commit 2:
I change a few lines in b.py

Commit 3:
I change the docstring in a.py

Posso desfazer essa função de eliminação, e fazê-lo aparecer como "cometer 4" (em vez de excluí cometer 1)

Foi útil?

Solução

Sim, você pode usar git revert para isso. Veja a href="http://schacon.github.com/git/user-manual.html#reverting-a-commit" rel="noreferrer"> git seção do manual para obter mais informações.

A essência é que você pode dizer:

git revert 4f4k2a

Onde 4f4k2a é o id do commit que você gostaria de desfazer, e vai tentar desfazê-lo.

Outras dicas

Apenas um comentário:

git revert aCommit

faz reverter o todas commit (como em " todos os arquivos parte do commit"):
ele calcula um remendo inversa, aplica-se sobre a cabeça e cometer.

Assim, dois problemas aqui (o primeiro é facilmente resolvido):


Fácil Git (Elijah Newren) tentou trazer um "revert completa" mais para Git lista de Divulgação ; mas sem muito sucesso:

As pessoas às vezes querem "Reverter alterações".

Agora, isso pode ser:

  • as mudanças entre 32 e 29 revisões atrás,
  • que poderia ser todas as alterações desde a última confirmação,
  • poderia ser as mudanças desde 3 commits atrás, ou
  • que poderia ser apenas um específico cometer.
  • O usuário pode querer subconjunto dessas reversões para apenas arquivos específicos ,

(eg revert é documentado aqui , mas eu não tenho certeza é parte da atual distribuição de eg embora)

mas tudo se resume a "mudanças reversão" no final.

eg revert --since HEAD~3  # Undo all changes since HEAD~3
eg revert --in HEAD~8     # much like git revert HEAD~8, but nocommit by default
eg revert --since HEAD foo.py  # Undo changes to foo.py since last commit
eg revert foo.py               # Same as above
eg revert --in trial~7 bar.c baz.  # Undo changes made in trial~7 to bar.[ch]

São estes tipos de "dados de reversão" realmente tão diferente que não deve precisa ser comandos diferentes, ou que algumas dessas operações não devem ser suportados pelo comando simples reversão?
Claro, a maioria dos usuários na maioria das vezes vai provavelmente usar o "eg revert FILE1 FILE2..." forma, mas eu não vejo o mal em apoiar as capacidades extras.

Além disso ... há algo fundamental que iria manter git núcleo de adoptar tal comportamento?

Elias

Nota:. Commits por padrão não fazem sentido para o comando revert generalizada, e "git revert REVISION" seria erro com instruções (dizendo ao usuário adicionar a bandeira --em)


Vamos dizer que você tem, por 50 cometido, 20 arquivos que você percebe que o velho cometer X introduziu alterações que não deveria ter ocorrido.
Um pouco de encanamento está em ordem.
O que você precisa é uma maneira de listar todos os arquivos específicos que você precisa revert
(Como em "para cancelar as alterações feitas em cometer X, mantendo todas as alterações posteriores" ),
e, em seguida, para cada um deles:

git-merge-file -p a.py X X^

A questão aqui é recuperar a função perdida sem obliterando todas as alterações subsequentes a.py você pode querer manter.
Essa técnica é por vezes chamado de "fusão negativa".

Desde git merge-file <current-file> <base-file> <other-file> meios :
incorpora todas as mudanças que o chumbo do <base-file> para <other-file> em <current-file>, você pode restaurar a função eliminado dizendo você deseja incorporar todas as alterações.)

  • De: X (onde a função foi suprimido)
  • para: X ^ (a submissão anterior antes de X, onde a função ainda estava lá)

Nota: o '-p ' argumento que lhe permite rever primeiro as mudanças sem fazer nada sobre o arquivo atual. Quando tiver a certeza, remova essa opção.

Nota : git merge-file é não é tão simples : você não pode fazer referência a versões anteriores do arquivo apenas como aquele
. (Você teria mais e mais a mensagem frustrante: error: Could not stat X )
Você tem que:

git cat-file blob a.py > tmp/ori # current file before any modification
git cat-file blob HEAD~2:a.py > tmp/X # file with the function deleted
git cat-file blob HEAD~3:a.py > tmp/F # file with the function which was still there

git merge-file a.py tmp/X tmp/F # basically a RCS-style merge
                                 # note the inversed commit order: X as based, then F
                                 # that is why is is a "negative merge"
diff -u a.py tmp/ori # eyeball the merge result
git add a.py 
git commit -m "function restored" # and any other changes made from X are preserved!

Se isto está a ser feito para um grande número de arquivos dentro de cometer um anterior ... alguns scripts está em ordem;)

Para reverter as alterações para apenas um arquivo dentro de uma consolidação, como VonC fora pontas, eu checkout o ramo (mestre ou tronco ou qualquer outro) e depois checkout a versão do arquivo que eu queria voltar e tratá-lo como um novo commit:

$ git checkout trunk
$ git checkout 4f4k2a^ a.py
$ git add a.py
$ git diff              #verify I'm only changing what I want; edit as needed
$ git commit -m 'recover function deleted from a.py in 4f4k2a'

Há provavelmente um comando encanamento que iria fazer isso diretamente, mas eu não iria usá-lo se eu sabia disso. Não é que eu não confio em Git, mas eu não confio em mim - Eu não confiaria que eu sabia, sem olhar o que foi alterado no arquivo em que cometem e desde então. E uma vez que eu olho, é mais fácil simplesmente construir um novo commit editando o diff. Talvez isso é apenas workstyle pessoal.

Tenha um olhar em este revert git questionar . Parece haver uma questão revertendo commits mais velhos se não em uma seqüência consecutiva, incluindo o mais recente cometer.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top