Alternar temporariamente a cópia de trabalho para uma confirmação Git específica

248

Como mudar para o commit específico do Git sem perder todos os commits feitos depois dele ?

Quero que os arquivos locais sejam alterados, mas o banco de dados das confirmações permanecerá intacto, apenas o ponteiro da posição atual está definido como confirmação atualmente selecionada.

Desejo alterar o estado dos arquivos para confirmação específica, executar o projeto e, quando terminar, restaurar os arquivos de volta à última confirmação.

Como fazer isso sem compactar a pasta do projeto inteiro?

Paulo
fonte

Respostas:

344

Se você estiver em um determinado ramo mybranch, vá em frente e git checkout commit_hash. Então você pode retornar ao seu ramo por git checkout mybranch. Eu tive o mesmo jogo dividindo um bug hoje :) Além disso, você deve saber sobre o git bisect .

Alexander Pavlov
fonte
6
Observe que você pode fazer isso apenas git checkout commit_hashse estiver em um repositório limpo e não precisar fazer ramificações. Pode ser mais fácil para alguns casos de uso (como o meu).
Enderland
@enderland: sua cabeça sempre aponta em algum ramo, normalmente :)
Alexander Pavlov
Eu tive um problema em que tive que usar todo o hash de confirmação porque um parcial não foi aceito.
mightyiam
6
Upvote para a git bisectreferência; que ferramenta extremamente útil!
Niek
54

Primeiro, use git logpara ver o log, escolha a confirmação desejada, anote o hash sha1 usado para identificar a confirmação. Em seguida, corra git checkout hash. Depois que você terminar git checkout original_branch,. Isso tem a vantagem de não mover o HEAD, simplesmente muda a cópia de trabalho para um commit específico.

Femaref
fonte
4
Eu acho que você quer dizer git checkout <original_branch>. git checkout HEADé efectivamente um NOOP
Abe Voelker
3
git reset --hard <hash>altera o HEAD da ramificação atual, enquanto git checkout <hash>você recebe um checkout desanexado que não altera nenhuma ramificação, e você pode retornar facilmente sem conhecer o hash ID original de sua ramificação, como mostrado nesta resposta.
Jofel
Pergunta do @Femaref Beginner: dado o contexto desta pergunta (alterne temporariamente para um commit anterior), por que seria uma vantagem ou desvantagem mover ou não o HEAD?
noz sobre natty
@nuttyaboutnatty Supondo que minha edição seja aprovada, ela deve responder à sua pergunta. HEAD realmente é movido em qualquer evento; mas em uma verificação geral, a referência da ramificação que HEAD aponta não é movida.
Echristopherson
15

Além das outras respostas aqui, mostrando como git checkout <the-hash-you-want>vale a pena saber que você pode voltar para onde estava usando:

git checkout @{-1}

Isso geralmente é mais conveniente do que:

git checkout what-was-that-original-branch-called-again-question-mark

Como você pode antecipar, git checkout @{-2}o levará de volta ao ramo em que se encontrava git checkouthá dois segundos e da mesma forma para outros números. Se você se lembra de onde estava para números maiores, deveria receber algum tipo de medalha por isso.


Infelizmente para a produtividade, git checkout @{1}não o leva ao ramo em que você estará no futuro, o que é uma pena.

Benjohn
fonte
1
Observe que git checkout -é um apelido abreviado paragit checkout @{-1}
Nathanael
@ Nathanael OMGOD , de jeito nenhum ... isso muda tudo! Bom obrigado! … Eu incorporaria isso na resposta, mas acho que também é útil conhecer a @{n}sintaxe geral , pois ela funciona com muitos comandos git. Achei difícil adicionar sua abreviação sem tornar a resposta um pouco confusa. Em vez disso, votei no seu comentário - espero que as pessoas o vejam. Obrigado novamente.
Benjohn em 25/03
1
Sem problemas. Esta discussão é tangencial à questão real de qualquer maneira. Mais um bônus! Costumo usar a mesma sintaxe para mesclar recursos em um release. por exemplo, git merge -para mesclar o ramo que você fez check-out pela última vez no ramo que fez check-out no momento. É como cd -no bash.
Nathanael