Como você pode desfazer o último git add?

193

É possível desestabilizar a última mudança faseada (não confirmada) no git ? Suponha que existam muitos arquivos no ramo atual, alguns preparados, outros não. Em algum momento, algum programador tolo acidentalmente executou:

git add -- .

...ao invés de:

git checkout -- .

Agora esse programador pode desestabilizar suas últimas alterações com algum comando mágico do git ? Ou ele deveria ter cometido antes de experimentar em primeiro lugar?

Septagrama
fonte
Heh. No entanto, temos uma pergunta útil e uma resposta.
Steveha 16/05
2
possível duplicata de Undo 'add git' antes de cometer
Jim caiu
Eu acredito que não é o duplicado. O OP na outra pergunta está pedindo uma maneira de desfazer isso ou remover esses arquivos da confirmação. Eu quero (ed) precisamente e apenas desfazer as alterações adicionadas com o último git addcomando, especialmente para os arquivos que já tinham etapas testadas e que tinham algumas alterações que deveriam ser desfeitas, não encenadas. Não posso dizer que a outra pergunta não está relacionada.
Septagram
1
Talvez ele devesse ter sido / comprometido antes de experimentar em primeiro lugar.
Android_weasel
@ android.weasel sim, isso foi há muitos anos ...
Septagram

Respostas:

299

Você pode usar git reset. Isso desestabilizará todos os arquivos que você adicionou após seu último commit.

Se você deseja desfazer apenas alguns arquivos, use git reset -- <file 1> <file 2> <file n>.

Também é possível desestabilizar algumas das alterações nos arquivos usando git reset -p.

thameera
fonte
3
Que triste. Acho que há algo errado nas minhas práticas de cometer, afinal. Aceitando esta resposta, porque você mencionou a -popção. Obrigado! :)
Septagram
Gera (para mim) o erro: fatal: falha ao resolver 'HEAD' como uma referência válida. Ainda não cometi nada (novo repo) que acabei de executar o git add. e se arrependeu. Não quero redefinir a adição inteira, apenas um diretório. git reset - dir /*.* gera o erro acima.
Francis Davey
... Ah, eu vejo o que está acontecendo comigo. Eu não tinha nada para o HEAD apontar ainda e, portanto, a redefinição do git falhou (porque opera no HEAD).
Francis Davey
42

Você não pode desfazer a última adição do git, mas pode desfazer todos os adds desde o último commit. git resetsem um argumento de confirmação redefine o índice (desestágena as mudanças faseadas):

git reset
knittl
fonte
2
"Você não pode desfazer o último git add": Uau, isso é surpreendente e potencialmente doloroso. Existe uma fonte definitiva para isso? Além disso, há uma boa razão para que seja assim? Obrigado!
Andrew Moylan 8/16
@ AndrewMoylan: bem, não há uma maneira automática de fazer isso. Você sempre pode criar um resetúnico arquivo ou reset -pdesestabilizar um pedaço específico.
knittl
15

Então, a verdadeira resposta para

Agora esse programador pode desestabilizar suas últimas alterações com algum comando mágico do git?

é realmente: Não, você não pode desfilar apenas o últimogit add .

Ou seja, se interpretarmos a pergunta como na seguinte situação:

Arquivo inicial:

void foo() {

}

main() {
    foo();
}

Primeira alteração seguida por git add:

void foo(int bar) {
    print("$bar");
}

main() {
    foo(1337);
}

Segunda alteração seguida por git add:

void foo(int bar, String baz) {
    print("$bar $baz");
}

main() {
    foo(1337, "h4x0r");
}

Nesse caso, git reset -pnão ajudará, pois sua menor granularidade são linhas. gitnão sabe disso sobre o estado intermediário de:

void foo(int bar) {
    print("$bar");
}

main() {
    foo(1337);
}

não mais.

stanm
fonte
Eu pedi porque, como um novo usuário do git, essa é uma distinção realmente importante que destaca o que meus amigos descrevem como "ter uma boa higiene no check-in" ... minha experiência pessoal - foi descrita como "carpooling" (ruim!).
benc
6

Você pode usar git reset(consulte a documentação )

Davids
fonte
3

Na data, o git solicita:

  1. use "git rm --cached <file>..." to unstagese os arquivos não estavam no repositório. Desinstala os arquivos mantendo-os lá.
  2. use "git reset HEAD <file>..." to unstagese os arquivos estavam no repositório e você os está adicionando como modificados. Ele mantém os arquivos como estão e os desestabiliza.

Pelo que sei, você não pode desfazer a git add --ação, mas pode desestabilizar uma lista de arquivos conforme mencionado acima.

theGiallo
fonte
2
  • Remova o arquivo do índice, mas mantenha-o com versão e com alterações não confirmadas na cópia de trabalho:

    git reset head <file>
    
  • Redefina o arquivo para o último estado do HEAD, desfazendo as alterações e removendo-as do índice:

    git reset HEAD <file>
    git checkout <file>
    
    # If you have a `<branch>` named like `<file>`, use:
    git checkout -- <file>

    Isso é necessário, pois git reset --hard HEADnão funcionará com arquivos únicos.

  • Remova <file>do índice e versão, mantendo o arquivo sem versão com alterações na cópia de trabalho:

    git rm --cached <file>
    
  • Remova <file>completamente a cópia de trabalho e o controle de versão:

    git rm <file>
    
Faisal
fonte
2

Se você deseja remover todos os arquivos adicionados do git para commit

git reset

Se você deseja remover um arquivo individual

git rm <file>
BSB
fonte
1

Você pode usar

git reset

para desfazer os arquivos locais adicionados recentemente

 git reset file_name

desfazer as alterações para um arquivo específico

ireshika piyumalie
fonte
0

Dependendo do tamanho e escala da dificuldade, você pode criar uma ramificação temporária (temporária) e confirmar o trabalho atual lá.

Em seguida, mude para e faça o checkout de sua ramificação original e escolha os arquivos apropriados na confirmação inicial.

Pelo menos você teria um registro permanente dos estados atual e anterior para trabalhar (até excluir esse ramo temporário).

Philip Oakley
fonte