Question Puis-je récupérer une branche après sa suppression dans Git?


Si je cours git branch -d XYZ, existe-t-il un moyen de récupérer la branche? Est-il possible de revenir en arrière comme si je n'avais pas exécuté la commande delete branch?


765
2017-09-04 03:25


origine


Réponses:


Oui, vous devriez être capable de faire git reflog et trouver le SHA1 pour le commit à la pointe de votre branche supprimée, puis juste git checkout [sha]. Et une fois que vous êtes à ce commit, vous pouvez juste git checkout -b [branchname] pour recréer la branche à partir de là.


1378
2017-09-04 03:43



La plupart du temps les commits inatteignables sont dans le reflog. Alors, la première chose à essayer est de regarder le refog en utilisant la commande git reflog (qui affiche le reflog pour HEAD).

Peut-être que quelque chose de plus facile si le commit faisait partie d'une branche spécifique existe encore est d'utiliser la commande git reflog name-of-my-branch. Il fonctionne aussi avec une télécommande, par exemple si vous avez forcé la poussée.


Si vos commits ne sont pas dans votre reflog (peut-être parce que supprimé par un outil tiers qui n'écrit pas dans le reflog), j'ai réussi à récupérer une branche en réinitialisant ma branche au sha du commit trouvé en utilisant une commande comme ça (ça crée un fichier avec tous les commits pendants ):

git fsck --full --no-reflogs --unreachable --lost-found | grep commit | cut -d\  -f3 | xargs -n 1 git log -n 1 --pretty=oneline > .git/lost-found.txt

Si vous devez l'utiliser plus d'une fois (ou si vous voulez l'enregistrer quelque part), vous pouvez également créer un alias avec cette commande ...

git config --global alias.rescue '!git fsck --full --no-reflogs --unreachable --lost-found | grep commit | cut -d\  -f3 | xargs -n 1 git log -n 1 --pretty=oneline > .git/lost-found.txt'

et l'utiliser avec git rescue

Pour étudier les validations trouvées, vous pouvez afficher chaque validation en utilisant des commandes pour les examiner.

Pour afficher les métadonnées de validation (auteur, date de création et message de validation):

git cat-file -p 48540dfa438ad8e442b18e57a5a255c0ecad0560

Pour voir aussi les diffs:

git log -p 48540dfa438ad8e442b18e57a5a255c0ecad0560

Une fois que vous avez trouvé votre commit, créez une branche sur ce commit avec:

git branch commit_rescued 48540dfa438ad8e442b18e57a5a255c0ecad0560

98
2018-03-10 15:10



Si vous aimez utiliser une interface graphique, vous pouvez effectuer l'opération entière avec gitk.

gitk --reflog

Cela vous permettra de voir l'historique de validation de la branche comme si la branche n'avait pas été supprimée. Maintenant, faites un clic droit sur le dernier commit de la branche et sélectionnez l'option de menu Create new branch.


30
2018-06-02 14:28



La solution la mieux votée fait en réalité plus que demandé:

git checkout <sha>
git checkout -b <branch>

ou

git checkout -b <branch> <sha>

vous déplacer vers la nouvelle branche avec tous les changements récents que vous pourriez avoir oublié de commettre. Ce n'est peut-être pas votre intention, surtout en mode "panique" après avoir perdu la branche.

UNE solution plus propre (et plus simple) semble être le one-liner (après avoir trouvé le <sha> avec git reflog):

git branch <branch> <sha>

Maintenant, ni votre branche actuelle ni les modifications non-activées ne sont affectées. Au lieu de cela, seule une nouvelle branche sera créée jusqu'au <sha>.

Si ce n'est pas l'astuce, cela fonctionnera toujours et vous obtiendrez une branche plus courte, alors vous pouvez réessayer avec de nouvelles <sha> et le nom de la nouvelle branche jusqu'à ce que vous ayez raison.

Enfin, vous pouvez renommer la branche restaurée avec succès en ce qu'elle a été nommée ou toute autre chose:

git branch -m <restored branch> <final branch>

Inutile de dire que la clé du succès était de trouver le bon compromis <sha>, nommez donc vos commits à bon escient :)


15
2018-04-08 15:33



Ajouter à tfe répondre: il y a aussi le git-resurrect.sh script dans le contrib/ zone des sources Git (dans le dépôt git.git), ce qui pourrait vous aider.

git-resurrect <name> tente de trouver des traces d'un bout de branche   appelé <name>et essaie de le ressusciter. Actuellement, le reflet est   cherché des messages de paiement, et avec -r fusionner également des messages. Avec    -m et -t, l'historique de toutes les références est analysé Merge <name> into other/Merge <other> into <name> (respectivement) commettre des sujets, qui   est plutôt lent mais vous permet de ressusciter le sujet des autres   branches.


13
2017-09-06 19:39



Si vous n'avez pas de reflog, par exemple. parce que vous travaillez dans un référentiel nu qui n'a pas le reflog activé et que le commit que vous voulez récupérer a été créé récemment, une autre option est de trouver des objets de commit créés récemment et de les parcourir.

De l'intérieur du .git/objects répertoire run:

find . -ctime -12h -type f | sed 's/[./]//g' | git cat-file --batch-check | grep commit

Ceci trouve tous les objets (commits, fichiers, étiquettes, etc.) créés au cours des 12 dernières heures et les filtre pour afficher uniquement les validations. Vérifier ces derniers est alors un processus rapide.

Je vais essayer le script git-ressurect.sh mentionné dans La réponse de Jakub d'abord cependant.


8
2018-05-13 11:26



J'ai utilisé les commandes suivantes pour trouver et récupérer ma branche supprimée. Les premières étapes proviennent de la description de gcb.

$ git fsck --full --no-reflogs --unreachable --lost-found > lost
$ cat lost | cut -d\  -f3 > commits
$ cat commits | xargs -n 1 git log -n 1 --pretty=oneline

Recherchez maintenant l'ID de validation git (GIT-SHA) en fonction des commentaires de validation et utilisez-le dans la commande ci-dessous. Commander une nouvelle branche appelée NEW-BRANCH avec le GIT-SHA précédemment trouvé:

$ git checkout -b NEW-BRANCH GIT-SHA

6
2017-11-14 13:28



A ma connaissance, si la branche à supprimer peut être atteinte par une autre succursale, vous pouvez la supprimer en toute sécurité en utilisant

git branch -d [branch]

et votre travail n'est pas perdu. Rappelez-vous qu'une branche n'est pas un instantané, mais un pointeur sur un. Ainsi, lorsque vous supprimez une branche, vous supprimez un pointeur.

Vous ne perdrez même pas de travail si vous supprimez une branche qui ne peut pas être atteinte par une autre. Bien sûr, ce ne sera pas aussi facile que de vérifier le hash de commit, mais vous pouvez toujours le faire. C'est pourquoi Git est incapable de supprimer une branche qui ne peut pas être atteinte en utilisant -d. Au lieu de cela, vous devez utiliser

git branch -D [branch]

Cela fait partie d'une vidéo de Scott Chacon à propos de Git. Vérifiez la minute 58:00 quand il parle de branches et comment les supprimer.

Introduction à Git avec Scott Chacon de GitHub


5
2017-08-11 21:04



Pour GitHub utilisateurs sans Git installé:

Si vous voulez le restaurer à partir de GitHub site web, vous pouvez Pirater leur site Web;)

• Tout d'abord, trouvez ces SHA (commit hashes):

curl -i https://api.github.com/repos/PublicUser/PublicRepo/events

... ou pour des repos privés:

curl -su YourUserName https://api.github.com/repos/YourUserName/YourProject/events

... (le mot de passe vous sera demandé)

• Ensuite, allez à GitHub et créez une nouvelle branche temporaire qui sera supprimée pour toujours (Chrome est préférable).

• Allez dans les branches et supprimez celui-ci.

Sur la même page, sans recharger, ouvrez DevTools, panneau Réseau. Maintenant préparez-vous ...

• Cliquez sur restaurer. Vous remarquerez une nouvelle "ligne". Faites un clic droit dessus et sélectionnez "Copier en tant que cURL" et enregistrez ce texte dans un éditeur.

• Ajouter à la fin de la ligne de code copiée, celle-ci: -H "Cookie=".

Vous devriez obtenir quelque chose comme ça:

curl 'https://github.com/UserName/ProjectName/branches?branch=BranchSHA&name=BranchName' -H 'Cookie:' -H 'Origin: https://github.com' -H 'Accept-Encoding: gzip, deflate, br' -H 'Accept-Language: en-US' -H 'User-Agent: User-Agent' -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' -H 'Accept: */*' -H 'Referer: https://github.com/UserName/ProjectName/branches' -H 'X-Requested-With: XMLHttpRequest' -H 'Connection: keep-alive' --data 'utf8=%E2%9C%93&authenticity_token=token' --compressed

• Etape finale: remplacez "BranchSHA" par votre SHA-hash et BranchName avec le nom désiré (BTW, c'est génial de renommer la branche depuis le web). Si vous n'étiez pas trop lent, vous devez faire cette demande de toute façon. Par exemple, copiez-collez simplement sur un terminal.

P.S.

Je sais, ce n'est pas une solution très simple ou une bonne solution, mais juste au cas où quelqu'un, sans mot de passe root et machine virtuelle, pendant le hackathon devra faire quelque chose de bizarre comme ça? .. C'est totalement réel, merci d'avoir pris le temps et bonne chance :)

METTRE À JOUR

Ahaha, je suis tellement excitée par le fait que quelqu'un sur le World Wide Web a trouvé ma réponse et effectivement après l'avoir lue, trouvée drôle ou utile et a augmenté ma réponse hallucinante, folle et donc fausse-pratique :) C'est un monde merveilleux autour et nous, les programmeurs et les codeurs, en sommes un des plus fous <3


4
2017-08-26 05:01



J'ai rebasé une branche à distance pour essayer d'effacer quelques commits que je ne voulais pas et allais choper les bons que je voulais. Bien sûr, j'ai mal écrit les SHA ...

Voici comment je les ai trouvés (surtout une interface / interaction plus facile à partir des choses sur les réponses ici):

Tout d'abord, générez une liste de validations libres dans votre journal. Faites-le dès que possible et arrêtez de travailler, car ceux-ci peuvent être déversés par le ramasse-miettes.

git fsck --full --no-reflogs --unreachable --lost-found > lost

Cela crée un lost fichier avec tous les commits, vous devrez regarder. Pour simplifier notre vie, coupons seulement le SHA:

cat lost | cut -d\  -f3 > commits

Maintenant vous avez un commits fichier avec tous les commits que vous devez regarder.

En supposant que vous utilisez Bash, la dernière étape:

for c in `cat commits`; do  git show $c; read; done

Cela vous montrera les informations diff et commit pour chacun d'entre eux. Et attendez que vous appuyez sur Entrer. Maintenant, écrivez tous ceux que vous voulez, puis choisissez-les soigneusement. Une fois que vous avez terminé, appuyez sur Ctrl-C.


3
2017-12-10 06:40