Em vários lugares, inclusive no vídeo dessa aula, eu já me deparei com o informação de que o comando git restore <nome do arquivo>
vai restaurar esse arquivo na árvore de trabalho a partir do HEAD (último commit).
No entanto, a documentação do git deixa bem claro que a fonte (source) só será o HEAD quando a opção --staged
é empregada, o que realiza a restauração do arquivo, a partir do HEAD, para o índice, conforme abaixo:
"By default, if --staged is given, the contents are restored from HEAD, otherwise from the index. Use --source to restore from a different commit."
Dessa forma, para restaurar arquivos na árvore de trabalho a partir do HEAD, é necessário rodar o comando git restore --source <hash ou parte do hash do commit desejado, podendo ser o último> <nome do arquivo>
De forma concisa: git restore -s@ <nome do arquivo>
O que acontece é que é muito comum que o estado (versão) do arquivo que se quer restaurar na árvore de trabalho, e que está presente no último commit, é a mesma versão que ainda está no índice, visto que os arquivos passam pelo caminho árvore > índice > commit e quando se realiza o commit, o índice continua com a cópia desse arquivo (na mesma versão enviada ao commit). Então, quando se usa o comando git restore sem se passar nenhuma outra opção, o comando substitui a versão do arquivo que está na sua árvore de trabalho pela versão que está no índice, mas que, por usa vez, é a mesma versão que está no último commit. Acredito que daí vem a compreensão errônea de que o arquivo está sendo restaurado a partir da versão presente no último commit, mas não está! Está sendo restaurado a partir da versão do índice que, 'por acaso' é a mesma do último commit.
Mas, em algumas situações, as versões do índice e do HEAD podem conter diferenças, como por exemplo se você fez alguma modificação posterior ao último commit no arquivo na árvore de trabalho e o adicionou ao índice. Assim, se vc desistir dessas alterações e quiser voltar para a versão do último commit no arquivo da sua árvore de trabalho, git restore
sem opções não vai funcionar. Ou você terá que restaurar a versão no índice com git restore --staged, que pegará a versão do HEAD e substituirá no índice, e depois rodar o git restore
, ou rodar o git restore -s@ <nome do arquivo>
.
E porque eu estou escrevendo isso tudo? Porque vi essa informação errada em muitos lugares para além desse vídeo. Até na Gemini. E essas informações que, pelo que pesquisei na documentação do Git e confirmei na prática por mim mesmo, estão erradas, me renderam dias de pesquisa mais minuciosa para entender exatamente o que o comando git restore
faz.
Lembrando e resumindo: quando se quer restaurar arquivos na árvore de trabalho, o git restore
, por padrão, vai pegar a versão desse mesmo arquivo logo 'acima', no índice. E quando se quer restaurar arquivos no índice, a camada logo 'acima' será o HEAD (último commit, normalmente), e é lá que será usada como fonte daquele arquivo para a restauração, que pode ser feita quando se usa a opção --staged
.
Por isso mesmo que se diz que se vc fez alterações em um arquivo na sua árvore e adicionou essa versão desse arquivo no índice, para 'desfazer' essa inclusão, se roda o comando git restore --staged
. Na verdade, o que acontece é que aquela versão 'nova' que vc adicionou ao índice e que vc se arrependeu, ao rodar o comando git restore --staged
, essa versão 'nova' que está no índice é substituída pela versão presente no último commit.
É por isso que ao se rodar o comando git status
após, será possível perceber que não existem mudanças para serem 'commitadas' com relação a esse arquivo, visto que as versões do índice e do HEAD serão idênticas. Então, git restore --staged <nome arquivo>
não apaga ele do índice (para isso, se não me engano, seria o comando git rm --cached <nome arquivo>
). Para confirmar que o arquivo continua no índice após o git restore --staged
, basta rodar o comando git ls-files --staged
. Ele não é apagado de lá.
De forma similar ao modo de funcionamento (no que tange às comparações) do git restore
, o comando git status
compara árvore de trabalho com o nível "imediatamente acima": o índice, e o índice e o nível "imediatamente acima": o HEAD, além de verificar arquivos novos (não rastreados).
Peço desculpas, antecipadamente, se cometi algum equívoco! Não sou nada mais que um iniciante.
Espero, sinceramente, ter contribuído.
ps. cached
é sinônimo de staged
.