120 votes

GIT restore last detached HEAD

S'il vous plaît, j'ai un gros problème dans mon projet : voici le scénario. J'ai un projet xcode sous GIT. Aujourd'hui, j'ai réalisé que le dernier commit a cassé certains tests, donc j'ai vérifié le commit précédent. J'ai utilisé SourceTree et voici l'avertissement

En faisant cela, votre copie de travail deviendra un 'detached HEAD', ce qui signifie que vous ne serez plus sur une branche. Si vous voulez commiter après cela, vous devrez probablement soit vérifier une branche à nouveau, soit créer une nouvelle branche. Est-ce que c'est correct ?

J'ai travaillé pendant toute une journée et à la fin, j'ai tout engagé. J'avais besoin de fusionner mon travail sur la branche de développement, j'ai donc vérifié la branche de développement et... mon travail a instantanément disparu :(

Je sais que c'était mal de détacher mon HEAD et Sourcetree m'a prévenu... mais il y a un moyen de restaurer mon travail ?

342voto

Brian Campbell Points 101107

Si vous tapez git reflog il vous montrera l'historique des révisions. HEAD pointé du doigt. Votre tête détachée devrait se trouver là. Une fois que vous l'avez trouvé, faites git checkout -b my-new-branch abc123 o git branch my-new-branch abc123 (où abc123 est le SHA-1 de la tête détachée) pour créer une nouvelle branche qui pointe vers votre tête détachée. Maintenant vous pouvez fusionner cette branche à votre guise.

En général, si vous extrayez une branche après avoir travaillé sur une tête détachée, Git devrait vous indiquer le commit de la tête détachée sur laquelle vous étiez, afin que vous puissiez le récupérer si nécessaire. Je n'ai jamais utilisé SourceTree, donc je ne sais pas s'il relaie ce message. Mais s'il affiche ce message, alors vous devriez pouvoir l'utiliser pour trouver le commit, et de nouveau utiliser git checkout -b o git branch pour créer une branche à partir de ce commit.

14voto

Brian LaLonde Points 11

Dans Sourcetree, vous pouvez le faire en utilisant l'interface graphique.

Trouvez d'abord le commit "perdu" en cherchant un message dans l'historique des commandes (view:Show Command Output). Il sera probablement dans la commande "Switching Branch" après le commit que vous avez perdu. Dans ce message, vous verrez probablement le commentaire du commit avec un ID de commit 1234567.

Passez à l'étape suivante avec cet identifiant d'engagement.

Cliquez sur le bouton "Branch" dans la barre d'outils supérieure et vous devriez obtenir une boîte de dialogue "New Branch" où vous pouvez spécifier un certain commit. Mettez cet ID de commit, spécifiez un nouveau nom de branche, cliquez sur "Créer une branche" et vous devriez obtenir une nouvelle branche avec votre commit perdu !

enter image description here

10voto

sohaib Points 99
  1. D'abord, exécutez git reflog pour voir l'historique.
  2. La révision la plus ancienne sera la dernière de la liste.
  3. Passez à l'engagement souhaité en utilisant git checkout -b temp e35d2b3 ici e35dd23 est la valeur de hachage de votre commit.
  4. C'est ça. Maintenant, il suffit de faire git add . etc....

Acceptez-la comme une réponse si elle résout votre problème. Sinon, veuillez partager votre commentaire.

5voto

Desert Rose Points 757

Si vous ne voulez pas garder les changements du HEAD détaché et voulez aller à la dernière branche commit utilisez directement la commande ci-dessous.

git checkout - 

Note : Je vais supprimer toutes vos modifications dans le HEAD détaché.

1voto

manuelvigarcia Points 481

Un de mes collègues vient de vivre cette situation. Dans son cas, il y avait des commits en tête détachés -ils travaillent dans R-Studio-- et l'outil les a prévenus qu'ils pouvaient créer la branche avec telle ou telle référence SHA... mais comme la seule option était "Close" --duh !! c'était une boîte d'information-- ils ont fermé le dialogue et ont perdu l'information pour toujours...

Grâce à la reflog nous avons pu constater que les changements n'étaient pas perdus. Mais dans notre cas, la git branch n'a pas fonctionné comme prévu... ou un entrant git pull a tout gâché d'une manière ou d'une autre. Nous avons dû transférer les changements de la reflog vers la branche nouvellement créée :

 git cherry-pick 0b823d42..3cce27fc

qui a placé tous les commits que nous voulions dans la branche. Ensuite, nous pouvons fusionner la branche dans develop sans problème.

Juste au cas où cela serait instructif pour quelqu'un, nous avons identifié les commits sur tête détachée dans le reflog en regardant ceux qui se trouvent entre ceux marqués par "checkout" (qui identifient le déplacement des branches) :

e09f183b HEAD@{3}: pull: Fast-forward
b5bf3e1d HEAD@{4}: checkout: moving from lost_changes to develop
b5bf3e1d HEAD@{5}: checkout: moving from 3cce27fca50177a288df0252f02edd5da5ee64fd to lost_changes
3cce27fc HEAD@{6}: commit: add statistics
417a99a4 HEAD@{7}: commit: add test
0b823d42 HEAD@{8}: commit: new utility class
d9ea8a63 HEAD@{9}: checkout: moving from develop to d9ea8a635d4c2349fcb05b3339a6d7fad5ae2a09
b5bf3e1d HEAD@{10}: pull: Fast-forward

Ceux que nous voulions étaient HEAD@{8} a HEAD@{6} (les deux inclus). On les a donc obtenus par :

git cherry-pick 0b823d42..3cce27fc

Ensuite, la résolution habituelle de la fusion et le commit final nous ont laissé la branche lost_changes contenant le travail de tête détaché que nous pensions perdu. La fusion de cette branche dans le développement a été rapide cette fois.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X