Desfazer modificações de cópia de trabalho de um arquivo no Git?

Após o último commit, eu modifiquei um monte de arquivos em minha cópia de trabalho, mas eu quero desfazer as alterações em um desses arquivos, como em redefinir para o mesmo estado que o commit mais recente.

No entanto, eu só quero desfazer as alterações de cópia de trabalho apenas desse arquivo sozinho, nada mais com ele.

Como faço isso?

Você pode usar

git checkout -- file 

Você pode fazê-lo sem o -- (como sugerido por nimrodm), mas se o nome do arquivo se parece com um branch ou tag (ou outro identificador de revisão), pode ficar confuso, então usar -- é melhor.

Você também pode verificar uma versão específica de um arquivo:

 git checkout v1.2.3 -- file # tag v1.2.3 git checkout stable -- file # stable branch git checkout origin/master -- file # upstream master git checkout HEAD -- file # the version from the most recent commit git checkout HEAD^ -- file # the version before the most recent commit 
 git checkout   

Eu usei isso hoje porque eu percebi que meu favicon tinha sido substituído alguns commits atrás quando eu atualizei para o drupal 6.10, então eu tive que recuperá-lo. Aqui está o que eu fiz:

 git checkout 088ecd favicon.ico 

Apenas use

 git checkout filename 

Isso replaceá o nome do arquivo pela versão mais recente do ramo atual.

AVISO: suas alterações serão descartadas – nenhum backup é mantido.

Se o seu arquivo já está preparado (acontece quando você faz um git adicionar etc depois que o arquivo é editado) para unstage suas mudanças.

Usar

 git reset HEAD  

Então

 git checkout  

Se ainda não foi preparado, basta usar

 git checkout  

Se você quiser apenas desfazer as alterações do commit anterior para aquele arquivo, você pode tentar isto:

 git checkout branchname^ filename 

Isso fará o checkout do arquivo como estava antes do último commit. Se você quiser mais alguns commits, use a notação branchname~n .

Eu sempre me confundo com isso, então aqui está um caso de teste de lembrete; digamos que temos esse script bash para testar o git :

 set -x rm -rf test mkdir test cd test git init git config user.name test git config user.email test@test.com echo 1 > a.txt echo 1 > b.txt git add * git commit -m "initial commit" echo 2 >> b.txt git add b.txt git commit -m "second commit" echo 3 >> b.txt 

Neste ponto, a mudança não é testada no cache, então o git status é:

 $ git status On branch master Changes not staged for commit: (use "git add ..." to update what will be committed) (use "git checkout -- ..." to discard changes in working directory) modified: b.txt no changes added to commit (use "git add" and/or "git commit -a") 

Se a partir deste ponto, nós fazemos git checkout , o resultado é este:

 $ git checkout HEAD -- b.txt $ git status On branch master nothing to commit, working directory clean 

Se em vez disso fizermos git reset , o resultado é:

 $ git reset HEAD -- b.txt Unstaged changes after reset: M b.txt $ git status On branch master Changes not staged for commit: (use "git add ..." to update what will be committed) (use "git checkout -- ..." to discard changes in working directory) modified: b.txt no changes added to commit (use "git add" and/or "git commit -a") 

Então, neste caso – se as mudanças não são testadas, o git reset não faz diferença, enquanto o git checkout sobrescreve as mudanças.


Agora, digamos que a última mudança do script acima é preparada / armazenada em cache, ou seja, também fizemos git add b.txt no final.

Neste caso, o git status neste ponto é:

 $ git status On branch master Changes to be committed: (use "git reset HEAD ..." to unstage) modified: b.txt 

Se a partir deste ponto, nós fazemos git checkout , o resultado é este:

 $ git checkout HEAD -- b.txt $ git status On branch master nothing to commit, working directory clean 

Se em vez disso fizermos git reset , o resultado é:

 $ git reset HEAD -- b.txt Unstaged changes after reset: M b.txt $ git status On branch master Changes not staged for commit: (use "git add ..." to update what will be committed) (use "git checkout -- ..." to discard changes in working directory) modified: b.txt no changes added to commit (use "git add" and/or "git commit -a") 

Então, neste caso – se as mudanças forem encenadas, o git reset basicamente fará alterações em mudanças não sincronizadas – enquanto o git checkout sobrescreverá completamente as mudanças.

Eu restaurar meus arquivos usando o id SHA, O que eu faço é git checkout

Eu tenho feito através do git bash:

(use "git checkout -- ..." to discard changes in working directory)

  1. Status do Git. [Então, vimos um arquivo modificado.]
  2. git checkout – index.html [eu mudei no arquivo index.html:
  3. git status [agora essas alterações foram removidas]

insira a descrição da imagem aqui

Se você ainda não enviou ou compartilhou seu commit:

 git diff --stat HEAD^...HEAD | \ fgrep filename_snippet_to_revert | cut -d' ' -f2 | xargs git checkout HEAD^ -- git commit -a --amend 

Essa resposta é para o comando necessário para alterações locais não-processadas que estão em vários arquivos específicos na mesma ou em várias pastas (ou diretórios). Isso responde especificamente à pergunta em que um usuário tem mais de um arquivo, mas o usuário não quer desfazer todas as alterações locais:

se você tiver um ou mais arquivos, poderá aplicar o comando samne ( git checkout -- file ) a cada um desses arquivos, listando cada um de seus locais separados por espaço, como em:

 git checkout -- name1/name2/fileOne.ext nameA/subFolder/fileTwo.ext 

ocupe-se do espaço abve entre name1 / name2 / fileOne.ext nameA / subFolder / fileTwo.ext

Para vários arquivos na mesma pasta:

Se acontecer de você precisar descartar as alterações para todos os arquivos em um determinado diretório, use o checkout do git da seguinte forma:

 git checkout -- name1/name2/* 

O asterisco acima faz o truque de desfazer todos os arquivos naquele local, sob name1 / name2.

E, da mesma forma, o seguinte pode desfazer as alterações em todos os arquivos para várias pastas:

 git checkout -- name1/name2/* nameA/subFolder/* 

mais uma vez lembre-se do espaço entre name1 / name2 / * nameA / subFolder / * no exemplo acima.

Nota: nome1, nome2, nomeA, subpasta – todos esses nomes de pasta de exemplo indicam a pasta ou pacote onde o (s) arquivo (s) em questão podem estar residindo.

Para mim só esta funcionou

 git checkout -p filename 

insira a descrição da imagem aqui

Se já estiver confirmado, você poderá reverter a alteração para o arquivo e confirmar novamente, em seguida, efetivar o novo commit com o último commit.