Dans git, j'essayais de faire un squash commit
en fusionnant dans une autre branche et en remettant HEAD
à l'endroit précédent via :
git reset origin/master
Mais j'ai besoin de sortir de cette situation. Comment puis-je remettre HEAD à l'emplacement précédent ?
J'ai le fragment SHA1 (23b6772
) du commit vers lequel je dois le déplacer.
Comment puis-je revenir à ce commit ?
Avant de répondre, ajoutons un peu de contexte, en expliquant ce qu'est cette "tête".
HEAD
est simplement une référence au commit actuel (le plus récent) sur la branche actuelle.
Il ne peut y avoir qu'un seul HEAD
à un moment donné. (sauf git worktree
)
Le contenu de HEAD
est stocké dans .git/HEAD
et contient les 40 octets SHA-1 du commit courant.
detached HEAD
Si vous n'êtes pas sur le dernier commit - ce qui signifie que HEAD
pointe vers un commit antérieur dans l'historique - il est appelé detached HEAD
.
[!Entrez la description de l'image ici][1]][1]
Sur la ligne de commande, cela ressemblera à ceci- SHA-1 à la place du nom de la branche puisque le HEAD
ne pointe pas vers le bout de la branche courante
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 extraire la nouvelle branche pointant vers le commit désiré.
Cette commande effectuera un checkout vers un commit donné.
A 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
également.
git reflog
affichera tout changement qui a mis à jour le HEAD
et le check out de l'entrée reflog désirée remettra le HEAD
à ce commit.
Chaque fois que le HEAD est modifié, il y aura une nouvelle entrée dans le reflog
.
git reflog
git checkout HEAD@{...}
Ceci vous ramènera au commit souhaité
[!entrer la description de l'image ici][4]][4]
git reset --hard <commit_id>
"Déplace" ; votre HEAD vers le commit désiré.
# 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.
git rebase --no-autostash
.git revert <sha-1>
"Annuler" ; le commit ou l'intervalle de commit donné.
La commande reset "annulera" ; tous les changements effectués dans le commit donné.
Un nouveau commit avec le patch d'annulation sera commis tandis que le commit original restera dans l'historique.
# 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, reset && ; checkout
modifient le HEAD
.
[!entrer la description de l'image ici][6]][6]
[1] : http://i.stack.imgur.com/OlavO.png [2] : http://i.stack.imgur.com/U0l3s.png [3] : https://i.stack.imgur.com/qplvo.png [4] : http://i.stack.imgur.com/atW9w.png [5] : https://github.com/git/git/blob/master/Documentation/RelNotes/2.7.0.txt [6] : http://i.stack.imgur.com/NuThL.png
Voici une approche qui peut être très simple et facile à retenir. Vérifiez 2 conditions et terminez par 1 commande. Vous êtes alors sur la bonne voie.
vous êtes dans 'detached head' ;
(i.e. tapez git status
; vous voyez HEAD detached at <commit_id>
)
une branche existante vous convient
(i.e. tapez git branch -v
; vous voyez un nom de branche avec des messages de commit associés représentant le travail que vous voulez continuer)
extrayez simplement cette branche
(i.e. tapez git checkout <branch_name>
; vous voyez Switched to branch <branch_name>
).
Vous pouvez maintenant continuer à ajouter et à valider votre travail comme avant ; les modifications seront suivies sur <branch_name>
.
Notez que si vous aviez sauvegardé du travail pendant que HEAD était détaché, dans la plupart des cas, ce travail sera fusionné automatiquement dans le processus ci-dessus. Si vous voyez un message concernant un conflit de fusion, ne paniquez pas. Il existe plusieurs excellents tutoriels avec des étapes simples pour résoudre le conflit et terminer la fusion.
La question peut être lue comme suit :
J'étais en état détaché avec HEAD
à 23b6772
et j'ai tapé git reset origin/master
(parce que je voulais écraser). Maintenant que j'ai changé d'avis, comment puis-je revenir à l'état détaché de HEAD
à 23b6772
?
La réponse la plus simple est : git reset 23b6772
.
Mais j'ai posé cette question parce que j'en avais marre de taper (copier & coller) les hashs de commit ou leur abréviation à chaque fois que je voulais faire référence au HEAD
précédent et j'ai cherché sur Google s'il existait une sorte de raccourci.
git reset -
(ou dans mon cas git cherry-pick -
)
Ce qui, incidemment, est la même chose que cd -
pour revenir au précédent répertoire courant dans *nix ! Donc, hourra, j'ai appris deux choses avec une seule pierre.