Eu sempre pensei git reset
e git checkout
como o mesmo, no sentido de que ambos trazem o projeto de volta para um commit específico. No entanto, acho que eles não podem ser exatamente iguais, pois isso seria redundante. Qual é a diferença real entre os dois? Estou um pouco confuso, pois o svn só precisa svn co
reverter o commit.
ADICIONADO
VonC e Charles explicaram as diferenças entre git reset
e git checkout
muito bem. Meu entendimento atual é que git reset
reverte todas as alterações de volta para um commit específico, enquanto que git checkout
mais ou menos se prepara para um branch. Achei os dois diagramas a seguir bastante úteis para chegar a esse entendimento:
ADICIONADOS 3
Em http://think-like-a-git.net/sections/rebase-from-the-ground-up/using-git-cherry-pick-to-simulate-git-rebase.html , a finalização da compra e a redefinição podem emular a rebase.
git checkout bar
git reset --hard newbar
git branch -d newbar
fonte
-- files
variantes; não tenho certeza.) Esse diagrama faz parecer que a principal diferença é se elas afetam o índice ou o WD. Veja minha resposta sobre isso. Os diagramas 2 e 3 são muito úteis para ver a diferença real. Os diagramas 4 e 5 são úteis para verificar se você entende o que esses comandos fazem, mas realmente não o ajudam a chegar lá.think-like-a-git.net
são necessárias etapas adicionais (fornecidas no artigo vinculado ) para evitar a perda de dados.Respostas:
git reset
é especificamente sobre a atualização do índice , movendo o HEAD.git checkout
é sobre atualizar a árvore de trabalho (para o índice ou a árvore especificada). Ele atualizará o HEAD apenas se você efetuar o checkout de uma ramificação (caso contrário, você terminará com um HEAD desanexado ).(na verdade, com o Git 2.23 Q3 2019, isso será
git restore
, não necessariamentegit checkout
)Por comparação, como o svn não tem índice, apenas uma árvore de trabalho
svn checkout
copiará uma determinada revisão em um diretório separado.O equivalente mais próximo para
git checkout
:svn update
(se você estiver no mesmo ramo, o mesmo URL SVN)svn switch
(se você fizer o checkout, por exemplo, da mesma ramificação, mas de outro URL de repo SVN)Todas essas três modificações árvore de trabalho (
svn checkout
,update
,switch
) tem apenas um comando no git:git checkout
.Mas como o git também tem a noção de índice (essa "área de preparação" entre o repositório e a árvore de trabalho), você também tem
git reset
.Thinkeye menciona nos comentários o artigo " Redefinir Desmistificado ".
Nesses pontos, porém:
LarsH acrescenta nos comentários :
De Novo concorda nos comentários :
fonte
git reset
é sobre modificar o "rótulo" do ramo e, opcionalmente, atualizar o índice ou a árvore de trabalho como efeito colateral.git checkout
trata da atualização da árvore de trabalho e da alternância da ramificação "selecionada" atualmente (oHEAD
).git reset
é 100% sobre oHEAD
. Ele funciona mesmo no modo HEAD desanexado ( stackoverflow.com/a/3965714/6309 ), o que significa que não há ramificação (!). O git checkout também funciona em um modo HEAD desanexado ou pode ser usado para fazer checkout de um SHA1 em um modo HEAD desanexado: novamente, nenhuma ramificação envolvida nesse caso.git checkout a839e8f
atualiza HEAD para apontar para confirmara839e8f
.Na sua forma mais simples,
reset
redefine o índice sem tocar na árvore de trabalho, enquantocheckout
altera a árvore de trabalho sem tocar no índice.Redefine o índice para corresponder
HEAD
, árvore de trabalho deixada em paz:Conceitualmente, isso faz check-out do índice na árvore de trabalho. Para fazê-lo realmente fazer qualquer coisa que você precisaria usar
-f
para forçá-lo a substituir as alterações locais. Este é um recurso de segurança para garantir que o formulário "sem argumento" não seja destrutivo:Depois de começar a adicionar parâmetros, é verdade que há alguma sobreposição.
checkout
geralmente é usado com uma ramificação, etiqueta ou confirmação. Nesse caso, ele será redefinidoHEAD
e o índice para o commit fornecido, além de executar a verificação do índice na árvore de trabalho.Além disso, se você fornecer
--hard
parareset
você pode pedirreset
para substituir a árvore de trabalho, bem como a redefinição do índice.Se você atualizou uma ramificação, existe uma diferença crucial entre
reset
echeckout
quando você fornece uma ramificação ou confirmação alternativa.reset
alterará a ramificação atual para apontar para a confirmação selecionada enquantocheckout
deixará a ramificação atual em paz, mas fará o checkout da ramificação fornecida ou confirmará.Outras formas
reset
ecommit
envolvem caminhos de fornecimento.Se você fornecer caminhos para
reset
você, não poderá fornecer--hard
ereset
alterará apenas a versão de índice dos caminhos fornecidos para a versão no commit fornecido (ouHEAD
se você não especificar um commit).Se você fornecer caminhos para
checkout
, comoreset
ele atualizará a versão de índice dos caminhos fornecidos para corresponder à confirmação fornecida (ouHEAD
), mas sempre fará o checkout da versão de índice dos caminhos fornecidos na árvore de trabalho.fonte
Um caso de uso simples ao reverter a alteração:
1. Use reset se desejar desfazer a preparação de um arquivo modificado.
2. Use o checkout se desejar descartar as alterações nos arquivos não estágios.
fonte
A principal diferença em poucas palavras é que
reset
move a referência de ramificação atual , enquantocheckout
não move (move HEAD).Como o livro do Pro Git explica em Redefinir desmistificado ,
Veja também a resposta de VonC para um trecho de texto e diagrama muito útil do mesmo artigo, que não vou duplicar aqui.
É claro que há muito mais detalhes sobre o que efeitos
checkout
ereset
pode ter sobre o índice ea árvore de trabalho, dependendo de quais parâmetros são usados. Pode haver muitas semelhanças e diferenças entre os dois comandos. Mas, a meu ver, a diferença mais crucial é se eles movem a ponta do ramo atual.fonte
Os dois comandos (reset e checkout) são completamente diferentes.
checkout X
NÃO Éreset --hard X
Se X for um nome de filial,
checkout X
alterará a filial atual, enquantoreset --hard X
não será.fonte
breves mnemônicos:
fonte