Qual é a diferença entre Git Revert, Checkout e Reset?

274

Eu estou tentando aprender a restaurar ou arquivos e projetos de reversão a um estado anterior, e não entendem a diferença entre git revert, checkoute reset. Por que existem três comandos diferentes para aparentemente o mesmo propósito e quando alguém deve escolher um sobre o outro?

haziz
fonte

Respostas:

461

Esses três comandos têm finalidades completamente diferentes. Eles não são nem remotamente semelhantes.

git revert

Este comando cria uma nova confirmação que desfaz as alterações de uma confirmação anterior. Este comando adiciona novo histórico ao projeto (não modifica o histórico existente).

git checkout

Este comando faz check-out do conteúdo do repositório e o coloca em sua árvore de trabalho. Também pode ter outros efeitos, dependendo de como o comando foi chamado. Por exemplo, também pode alterar em qual filial você está trabalhando atualmente. Este comando não faz nenhuma alteração no histórico.

git reset

Este comando é um pouco mais complicado. Na verdade, ele faz algumas coisas diferentes, dependendo de como é invocado. Ele modifica o índice (a chamada "área de preparação"). Ou ele altera o que confirma um cabeçalho de ramificação atualmente apontando. Este comando pode alterar o histórico existente (alterando o commit que uma ramificação faz referência).

Usando estes comandos

Se uma confirmação foi feita em algum lugar na história do projeto, e você mais tarde decidir que a confirmação está errada e não deveria ter sido feita, então git reverté a ferramenta para o trabalho. Isso desfará as alterações introduzidas pelo commit incorreto, registrando o "desfazer" no histórico.

Se você modificou um arquivo em sua árvore de trabalho, mas não confirmou a alteração, pode usar git checkoutpara fazer check-out de uma cópia nova do repositório.

Se você fez um commit, mas não o compartilhou com mais ninguém e decide que não o deseja, poderá git resetreescrever o histórico para que pareça que você nunca fez esse commit.

Estes são apenas alguns dos cenários de uso possíveis. Existem outros comandos que podem ser úteis em algumas situações, e os três comandos acima têm outros usos também.

Dan Moulding
fonte
13
Portanto, os três comandos podem ser usados ​​para desfazer algum trabalho, o que significa que eles não são tão "completamente diferentes". Mesmo conceito, contextos diferentes.
Bruno Santos
16
@BrunoSantos: castiçais, canos de chumbo, punhais e cordas podem ser usados ​​para matar pessoas, mas isso não significa que nenhuma dessas coisas seja particularmente semelhante.
Dan Molding
12
@ Dan Mounlding - Na verdade, existem muitos casos em que git resete git checkoutpodemos fazer exatamente a mesma coisa. Dizer que "não são nem remotamente parecidos" não é apenas um exagero: não é nem remotamente verdade. Esses dois comandos podem fazer muitas coisas diferentes, algumas das quais se sobrepõem completamente. Exemplo: git reset --harde git checkout -- .fará exatamente a mesma coisa. E logicamente falando, git reset --hard <path>e git checkout <path>também deve fazer exatamente a mesma coisa - o git, no entanto, impede que você faça isso. Confundir esses dois comandos é MUITO fácil.
DanGordon
5
@ DanGordon Sei que provavelmente teremos apenas uma diferença de opinião aqui. No entanto, acho que devo dar uma explicação. Você não pode fazer o git reset --hard <path>que pode git checkout <path>exatamente porque os dois comandos fazem algo completamente diferente. git resetdiz ao Git para mover HEAD para um commit diferente. git checkoutpor outro lado, não pede ao Git que faça nada com o HEAD. Ele deixa o HEAD sozinho e apenas faz check-out de um arquivo. Sim, você pode criá-los de uma maneira que eles tenham efeitos semelhantes. Mas o que eles realmente fazem é totalmente diferente.
Dan Molding
46

Digamos que você tenha confirmados:

C
B
A

git revert B, criará uma confirmação que desfaz alterações B.

git revert A, criará uma confirmação que desfaz alterações A, mas não toca nas alteraçõesB

Observe que se as alterações em Bdependem de alterações A, a reversão de Anão é possível.

git reset --soft A, alterará o histórico e o repositório de confirmação; o diretório de teste e o trabalho ainda estarão no estado de C.

git reset --mixed A, alterará o histórico, o repositório e a preparação da consolidação; O diretório de trabalho ainda estará no estado de C.

git reset --hard A, alterará o histórico de consolidação, repositório, preparo e diretório de trabalho; você voltará ao estado Acompletamente.

Akavall
fonte
1
Então resposta intuitiva .. como sobre check-out
MJ Estúdio
29
  • git reverté usado para desfazer uma confirmação anterior. No git, você não pode alterar ou apagar um commit anterior. (Na verdade, você pode, mas pode causar problemas.) Portanto, em vez de editar o commit anterior, o revert introduz um novo commit que reverte o anterior.
  • git reset é usado para desfazer alterações em seu diretório de trabalho que ainda não foram confirmadas.
  • git checkouté usado para copiar um arquivo de outra confirmação para sua árvore de trabalho atual. Não confirma automaticamente o arquivo.
Jonathan
fonte
7
Eu acredito que você está errado sobre "git reset". "git reset" redefine seu HEAD para um dos commit anteriores, não redefine seu diretório de trabalho. O diretório de trabalho é "redefinido" por "git checkout [nome do arquivo]"
luigi7up 4/14/14
11
git reset --softredefine apenas o HEAD, git reset --hardredefine o HEAD e seu diretório de trabalho.
Ehryk
git reset --mixed (padrão): uncommit + mudanças unstage
NattyC
21
  • git checkout modifica sua árvore de trabalho,
  • git reset modifica em qual referência o ramo em que você está aponta,
  • git revert adiciona uma confirmação desfazendo alterações.
dan_waterworth
fonte
4
git reset não modifica apenas a confirmação apontada por uma ramificação , também é usada para desestabilizar arquivos do índice e pode modificar a cópia de trabalho com git reset --mixed(o padrão).
git reset --soft: descomprima as alterações, as alterações são mantidas em etapas (índice). git reset --mixed (padrão): descomprometida + alterações unstage, as alterações são deixadas na árvore de trabalho. git reset --hard: descomprimir + unstage + excluir alterações, nada resta.
NattyC
6

Redefinir - no nível de confirmação, a redefinição é uma maneira de mover a ponta de uma ramificação para uma confirmação diferente. Isso pode ser usado para remover confirmações da ramificação atual.

Reverter - reverter desfaz um commit criando um novo commit. Essa é uma maneira segura de desfazer alterações, pois não há chance de reescrever o histórico de consolidação. Compare isso com o git reset, que altera o histórico de confirmação existente. Por esse motivo, o git revert deve ser usado para desfazer alterações em uma ramificação pública e o git reset deve ser reservado para desfazer alterações em uma ramificação privada.

Você pode dar uma olhada neste link - Redefinir, Checkout e Reverter

Sachchidanand Singh
fonte