Comment déplacer HEAD back vers un emplacement précédent? (Détachée de la tête)

en git, j'ai essayé de faire un squash commit en fusionnant dans une autre branche et puis en réinitialisant HEAD à l'endroit précédent via:

git reset origin/master

mais je dois sortir de là. Comment puis-je revenir à l'endroit précédent?

j'ai le SHA1 frag ( 23b6772 ) de s'engager à ce que j'ai besoin de le déplacer.

Comment puis-je revenir à cet engagement?

82
demandé sur CodeWizard 2015-12-30 00:53:03

3 réponses

avant de répondre permet d'ajouter un arrière-plan, expliquant ce qu'est ce HEAD .

First of all what is HEAD?

HEAD est simplement une référence à la propagation actuelle (la dernière) sur la branche courante.

Il ne peut y avoir qu'un seul HEAD à tout moment. (à l'exclusion de git worktree )

Le contenu de HEAD est stocké dans .git/HEAD et il contient les 40 octets SHA-1 de la propagation courante.


detached HEAD

si vous n'êtes pas sur le dernier commit-ce qui signifie que HEAD pointe à un commit antérieur dans l'histoire son appelé detached HEAD .

enter image description here

sur la ligne de commande il ressemblera à ceci-SHA-1 au lieu du nom de la branche puisque le HEAD ne pointe pas vers le bout de la branche actuelle

enter image description here


quelques options pour récupérer d'une tête détachée:


git checkout

git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back

ceci va vérifier la nouvelle branche pointant vers la propagation désirée.

Cette commande va passer à une validation donnée.

À ce stade, vous pouvez créer une branche et commencer à travailler à partir de ce point.

# Checkout a given commit. 
# Doing so will result in a `detached HEAD` which mean that the `HEAD`
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>

# create a new branch forked to the given commit
git checkout -b <branch name>

git reflog

Vous pouvez toujours utiliser le reflog .

git reflog affichera toutes les modifications qui ont mis à jour le HEAD et la vérification de l'entrée désirée reflog placera le HEAD de nouveau à cette propagation.

chaque fois que la tête est modifiée il y aura une nouvelle entrée dans le reflog

git reflog
git checkout HEAD@{...}

Cela va vous ramener à votre souhaité s'engager

enter image description here


git reset --hard <commit_id>

Déplacer " de votre TÊTE en arrière pour l'souhaité s'engager.

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts, if you've modified things which were
# changed since the commit you reset to.
  • Note: ( Since Git 2.7 )

    vous pouvez aussi utiliser le git rebase --no-autostash .


git revert <sha-1>

"annuler"la plage de propagation.

La commande reset" défait " toute modification apportée à la propagation.

Un nouveau commit avec le patch undo sera Commité alors que le commit original restera aussi dans l'histoire.

# add new commit with the undo of the original one.
# the <sha-1> can be any commit(s) or commit range
git revert <sha-1>

ce schéma illustre quelle commande fait quoi.

Comme vous pouvez le voir il reset && checkout modifier le HEAD .

enter image description here

207
répondu CodeWizard 2018-05-17 14:00:42

Voici une approche qui peut être très simple et facile à retenir. Vérifiez 2 conditions et terminez avec 1 commande. Alors tu es de retour sur la bonne voie.

si

vous êtes dans " détaché de la tête

(c'est à dire de type git status ; vous voyez HEAD detached at <commit_id> )

et

une succursale existante répond à vos besoins

(i.e. tapez git branch -v ; vous voyez un nom de branche avec un des messages de commit représentant les travaux que vous souhaitez continuer)

puis

il suffit de vérifier cette branche (c'est à dire de type git checkout <branch_name> ; vous voyez Switched to branch <branch_name> ).

résultats

vous pouvez maintenant continuer à ajouter et à effectuer votre travail comme avant; les changements seront suivis sur <branch_name> .

notez que si vous aviez sauvegardé le travail pendant que la tête était détachée, dans la plupart des cas ce travail sera fusionné automatiquement dans le processus ci-dessus. Si vous voyez un message à propos d'un conflit de fusion, ne paniquez pas. Il y a plusieurs grands tutoriels avec des étapes simples pour corriger le conflit et compléter la fusion.

8
répondu Kay V 2017-01-02 14:39:37

la question peut se lire comme suit:

j'étais en état détaché avec HEAD à 23b6772 et tapé git reset origin/master (parce que je voulais écraser). Maintenant que j'ai changé d'Avis, Comment revenir à HEAD être à 23b6772 ?

la réponse directe étant: git reset 23b6772

mais j'ai répondu à cette question parce que j'en avais marre de taper (copie & coller) commit hashs ou son abréviation chaque fois que je voulais faire référence à la précédente HEAD et Googlais pour voir s'il y avait une sorte de raccourci.

Il s'avère qu'il y est!

git reset - (ou dans mon cas git cherry-pick - )

qui, soit dit en passant, était le même que cd - pour retourner au précédent répertoire courant in * nix! Alors hourra, j'ai appris deux choses avec une pierre.

3
répondu antak 2017-07-22 04:46:29