Reverter alterações em um arquivo em uma confirmação


Respostas:


222

A maneira mais limpa que eu já vi de fazer isso é descrita aqui

git show some_commit_sha1 -- some_file.c | git apply -R

Semelhante à resposta do VonC, mas usando git showe git apply.


10
Bem feito. A solução de script é um exagero para isso. Por que não pode haver apenas o nome de arquivo git revert sha-1?
Mark Edington

16
Isso funciona no meu Mac, mas no Windows (no Cygwin) ele me dá:fatal: unrecognized input
Kedar Mhaswade 16/07/2015

1
@MerhawiFissehaye: Eu acho que o git checkout só reverterá as alterações novamente para voltar ao estado em que estava o commit. Eu adicionei o nome do arquivo; git commit --amend 'para remover o arquivo do commit.
ViFI 18/10/16

3
Apenas uma dica, eu quase sempre tenho que adicionar a -3flag ao git request para mesclagem de três vias quando o patch falha, pois geralmente estou corrigindo uma alteração um pouco no tempo.
Angularsen 17/11

2
Talvez óbvio para a maioria, mas garantir some_file.cinclui o caminho para o arquivo, se houver um caso contrário você vai silenciosamente remendo nada :)
Warpling

35

Supondo que não há problema em alterar o histórico de consolidação, aqui está um fluxo de trabalho para reverter alterações em um único arquivo em uma consolidação anterior:

Por exemplo, você deseja reverter as alterações em 1 arquivo ( badfile.txt) no commit aaa222:

aaa333 Good commit
aaa222 Problem commit containing badfile.txt
aaa111 Base commit

Rebase na confirmação básica, corrija a confirmação do problema e continue.

1) Inicie o rebase interativo:

git rebase -i aaa111

2) Marque o problema de confirmação para edição no editor, alterando pickpara e(para edição):

e aaa222
pick aaa333

3) Reverta as alterações no arquivo incorreto:

git show -- badfile.txt | git apply -R

4) Adicione as alterações e corrija o commit:

git add badfile.txt
git commit --amend

5) Termine o rebase:

git rebase --continue

Só quero ressaltar que isso pressupõe que você pode editar o histórico do git. Algumas respostas acima criam um novo commit que reverte a alteração específica sem editar o histórico, o que nem sempre é possível / permitido.
Angularsen 17/11/16

Fantástico. Era exatamente isso que eu estava procurando. Eu já tinha essa ideia, mas fiquei confuso ao fazer o rebase interativo de que os arquivos ao fazer o editnão estavam aparecendo como alterados. Mas git show -- badfile.txt | git apply -Rdeu a resposta que eu precisava <3
mraxus 15/03/19

se eu entendo esse git aplicar -R remove o commit nesse arquivo, configurando-o novamente para o estado original alterado?
DaImTo

19

git revert é para todo o conteúdo do arquivo em uma consolidação.

Para um único arquivo, você pode escrevê-lo :

#!/bin/bash

function output_help {
    echo "usage: git-revert-single-file <sha1> <file>"
}

sha1=$1
file=$2

if [[ $sha1 ]]; then
git diff $sha1..$sha1^ -- $file | patch -p1
else
output_help
fi

(Nos utilitários git-shell-scripts da smtlaissezfaire )


Nota:

Outra maneira é descrita aqui se você ainda não confirmou sua modificação atual.

git checkout -- filename

git checkout possui algumas opções para um arquivo, modificando o arquivo de HEAD, substituindo sua alteração.


Dropped.on.Caprica menciona nos comentários :

Você pode adicionar um alias ao git para fazer isso git revert-file <hash> <file-loc>e reverter esse arquivo específico.
Veja esta essência .

[alias]
  revert-file = !sh /home/some-user/git-file-revert.sh

Apenas para adicionar à discussão aqui, você pode adicionar um alias ao git para fazer isso git revert-file <hash> <file-loc>e reverter esse arquivo específico. Eu tirei essa resposta (embora eu tenha que fazer algumas edições para funcionar corretamente). Você pode encontrar uma cópia do meu .gitconfige roteiro editado aqui: gist.github.com/droppedoncaprica/5b67ec0021371a0ad438
AlbertEngelB

@ Dropped.on.Caprica bom ponto. Eu o incluí na resposta para obter mais visibilidade.
VonC

12

Eu simplesmente usaria a --no-commitopção para git-revertremover os arquivos que você não deseja reverter do índice antes de finalmente enviá-lo. Aqui está um exemplo mostrando como reverter facilmente apenas as alterações para foo.c no segundo commit mais recente:

$ git revert --no-commit HEAD~1
$ git reset HEAD
$ git add foo.c
$ git commit -m "Reverting recent change to foo.c"
$ git reset --hard HEAD

O primeiro git-reset"desestabiliza" todos os arquivos, para que possamos adicionar novamente apenas o arquivo que queremos reverter. A final git-reset --hardse livra do arquivo restante revertido que não queremos manter.


9

Muito mais simples:

git reset HEAD^ path/to/file/to/revert

então

git commit --amend   

e depois

git push -f

o arquivo se foi e confirma o hash, a mensagem etc. é a mesma.


Para ser completo, você precisa de um git checkout -- path/to/file/to/revertpasso? Além disso, não é verdade que o hash é o mesmo depois, certo? A última frase pode ser melhor como algo como: "O resultado é que a última confirmação é substituída por uma nova que difere apenas no fato de não conter as alterações no arquivo revertido".
Kevin

@ Kevin você provavelmente está certo. Vou ter que checar essa última linha, mas olhando para trás de alguns anos atrás, ficaria surpreso se o hash de confirmação não fosse alterado.
Forrest

6
git reset HEAD^ path/to/file/to/revert/in/commit

O comando acima retirará o arquivo do commit, mas ele será refletido no git status.

git checkout path/to/file/to/revert/in/commit

O comando acima reverterá as alterações (como resultado, você obtém o mesmo arquivo que HEAD).

git commit

(Passe --amendpara alterar o commit.)

git push

Com isso, o arquivo que já está no commit é removido e revertido.

As etapas acima devem ser seguidas na ramificação em que a confirmação é feita.


5

Você pode seguir este procedimento:

  1. git revert -n <*commit*>( -nreverta todas as alterações, mas não as confirma)
  2. git add <*filename*> (nome do (s) arquivo (s) que você deseja reverter e confirmar)
  3. git commit -m 'reverted message' (adicione uma mensagem para reverter)
  4. depois de confirmar, descartar os outros arquivos alterados para que eles fiquem atualizados com as alterações confirmadas antes da reversão

1

Se você deseja redefinir as alterações em um arquivo a partir do seu último commit, é isso que geralmente estou usando. Eu acho que essa é a solução mais simples.

Observe que o arquivo será adicionado à área de preparação.

git checkout <prev_commit_hash> -- <path_to_your_file>

Espero que ajude :)

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.