Existe uma diferença entre "Hash -hard hash de" Git Reset -e "Hash de checkout do git"?

StackOverflow https://stackoverflow.com/questions/2541545

  •  23-09-2019
  •  | 
  •  

Pergunta

Enquanto reset e checkout Tenha usos diferentes na maioria das vezes, não consigo ver que diferença existe entre esses dois.

Provavelmente existe um ou ninguém teria se incomodado em adicionar um --hard opção para fazer algo o básico checkout pode fazer.

Talvez haja uma diferença é a maneira como você verá a história?

Foi útil?

Solução

Esta resposta é citada principalmente da minha resposta para uma pergunta anterior: Reset Git em inglês simples.

Os dois são muito diferentes. Eles resultam no mesmo estado para o seu índice e árvore de trabalho, mas o histórico e o ramo atual resultantes não são os mesmos.

Suponha que sua história se pareça com isso, com a filial mestre atualmente check -out:

- A - B - C (HEAD, master)

E você corre git reset --hard B. Você vai conseguir isso:

- A - B (HEAD, master)      # - C is still here, but there's no
                            # branch pointing to it anymore

Você realmente obteria esse efeito se usar --mixed ou --soft Também - a única diferença é o que acontece com sua árvore de trabalho e índice. No --hard caso, a árvore de trabalho e correspondência de índice B.

Agora, suponha que você corra git checkout B em vez de. Você entenderia isso:

- A - B (HEAD) - C (master)

Você acabou em um estado de cabeça isolada. HEAD, árvore de trabalho, índice todos correspondem B, o mesmo que com a redefinição dura, mas o ramo mestre foi deixado para trás em C. Se você fizer um novo compromisso D Neste ponto, você conseguirá isso, o que provavelmente não é o que você deseja:

- A - B - C (master)
       \
        D (HEAD)

Então, você usa a compra para, bem, confira esse compromisso. Você pode mexer com isso, fazer o que quiser, mas deixou seu galho para trás. Se você deseja que o ramo também seja movido, você usa a redefinição.

Outras dicas

Se a documentação fornecida com o Git não o ajudar, dê uma olhada em Uma referência visual git por Mark Lodato.

Em particular se você estiver comparando git checkout <non-branch> com git reset --hard <non-branch> (HotLinked):

git checkout master~3
(fonte: github.com)

git reset --hard master~3

Observe que no caso de git reset --hard master~3 Você deixa para trás uma parte do DAG de revisões - algumas das confirmações não são referenciadas por nenhuma filial. Esses são protegidos por (por padrão) 30 dias por Reflogue; Eles acabariam sendo podados (removidos).

git-reset hash define a referência da filial ao hash dado e opcionalmente verifica, com--hard.

git-checkout hash define a árvore de trabalho para o hash dado; E, a menos que o hash seja um nome de filial, você acabará com uma cabeça destacada.

Por fim, o GIT lida com 3 coisas:

                   working tree (your code)
-------------------------------------------------------------------------
                     index/staging-area
-------------------------------------------------------------------------
      repository (bunch of commits, trees, branch names, etc)

git-checkout Por padrão, apenas atualiza o índice e a árvore de trabalho e pode opcionalmente atualizar algo no repositório (com o -b opção)

git-reset Por padrão, apenas atualiza o repositório e o índice e, opcionalmente, a árvore de trabalho (com o --hard opção)

Você pode pensar no repositório como este:

 HEAD -> master

 refs:
    master -> sha_of_commit_X
    dev -> sha_of_commit_Y

 objects: (addressed by sha1)

    sha_of_commit_X, sha_of_commit_Y, sha_of_commit_Z, sha_of_commit_A ....

git-reset manipula o que as referências do ramo apontam.

Suponha que sua história se pareça com a seguinte:

           T--S--R--Q [master][dev]
          / 
   A--B--C--D--E--F--G [topic1]
                   \
                    Z--Y--X--W [topic2][topic3]

Lembre -se de que os ramos são apenas nomes que avançam automaticamente quando você se compromete.

Então você tem os seguintes ramos:

 master -> Q
 dev -> Q
 topic1 -> G
 topic2 -> W
 topic3 -> W

E sua filial atual é topic2, isto é, a cabeça aponta para o tópico2.

HEAD -> topic2

Então, git reset X redefinirá o nome topic2 apontar para x; Ou seja, se você formar um comprometimento no tópico do ramo 2, as coisas ficarão assim:

           T--S--R--Q [master][dev]
          / 
   A--B--C--D--E--F--G [topic1]
                   \
                    Z--Y--X--W [topic3]
                           \
                            P [topic2]
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top