web-dev-qa-db-fra.com

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

Si je lance 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?

951
prosseek

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


Merci à @Cascabel pour cette version condensée/à une ligne.

Vous pouvez le faire en une étape:

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

La plupart du temps, les commits inaccessibles se trouvent dans la liste des modifications. Donc, la première chose à essayer est de regarder le reflog en utilisant la commande git reflog (qui affiche le reflog pour HEAD ).

Peut-être quelque chose de plus simple si la validation faisait partie d’une branche spécifique encore existante consiste à utiliser la commande git reflog name-of-my-branch. Cela fonctionne aussi avec une télécommande, par exemple si vous avez forcé Push (conseil supplémentaire: toujours préférez git Push --force-with-lease au lieu de cela afin de mieux éviter les erreurs et est plus restaurable).


Si vos commits ne sont pas dans votre reflog (peut-être parce qu'ils ont été supprimés par un outil tiers qui n'écrit pas dans le reflog), j'ai récupéré avec succès une branche. en remettant ma branche dans le sha de la validation trouvée en utilisant une commande comme celle-ci (elle crée un fichier contenant toutes les commises suspendues):

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 souhaitez 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 examiner les validations trouvées, vous pouvez afficher chaque validation en utilisant certaines 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

Pour ceux qui sont sous Windows et qui aiment les interfaces graphiques, vous pouvez facilement récupérer les validations (ainsi que les fichiers intermédiaires non gérés) avec GitExtensions en utilisant la fonction Repository => Git maintenance => Recover lost objects...

135
Philippe

Si vous souhaitez utiliser une interface graphique, vous pouvez effectuer toute l'opération avec gitk.

gitk --reflog

Cela vous permettra de voir l'historique de validation de la branche comme si celle-ci n'avait pas été supprimée. Maintenant, il vous suffit de cliquer avec le bouton droit sur la dernière validation dans la branche et de sélectionner l'option de menu Create new branch.

41
nobar

La solution la plus votée fait plus que demandé:

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

ou

git checkout -b <branch> <sha>

déplacez-vous vers la nouvelle branche avec toutes les modifications récentes que vous auriez peut-être oublié de valider. Ce n'est peut-être pas votre intention, surtout lorsque vous êtes en "mode panique" après la perte de 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>

Désormais, ni votre branche actuelle ni les modifications non validées ne sont affectées. Au lieu de cela, seule une nouvelle branche sera créée jusqu’au <sha>.

S'il ne s'agit pas du conseil, il fonctionnera toujours et vous obtiendrez une branche plus courte. Vous pourrez alors réessayer avec le nouveau <sha> et le nouveau nom de la branche jusqu'à ce que vous obteniez le résultat correct.

Enfin, vous pouvez renommer la branche restaurée avec succès en ce qu’elle ait é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 commit <sha>, alors nommez bien vos commits :)

19
Dmitri Zaitsev

Ajout de tfe answer : il y a aussi le git-resurrect .sh script dans la zone contrib/ des sources Git (dans le référentiel git.git), ce qui pourrait vous aider.

git-resurrect <name> tente de trouver les traces d'une astuce de branche appelée <name> et tente de la ressusciter. Actuellement, les messages d'extraction sont recherchés dans le reflog et, avec -r, fusionnent également les messages. Avec -m et -t, l'historique de toutes les références est scanné pour Merge <name> into other/Merge <other> into <name> (respectivement) commettre des sujets, ce qui est plutôt lent mais vous permet de ressusciter le sujet d'autres personnes. branches.

14
Jakub Narębski

Pour GitHub utilisateurs sans Git installé:

Si vous souhaitez le restaurer à partir du site Web GitHub , vous pouvez utiliser leur API pour obtenir une liste des événements liés au référentiel:

Premier

  • trouvez ces SHA (commit hashes):

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

    ... ou pour des pensions privées:

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

    (on vous demandera le mot de passe GitHub)

    • (Si le rapport requiert une autorisation à deux facteurs, voir les commentaires sur cette réponse ci-dessous.)

Suivant

  • allez sur 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-la.

Sur la même page, sans recharger , ouvrez DevTools, le 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 maintenant obtenir quelque chose comme:

    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

Dernière étape

  • remplacez "BranchSHA" par votre SHA-hash et BranchName par le nom de votre choix (en passant, il est très utile de renommer une branche à partir du Web). Si vous n'étiez pas trop lent, vous devez quand même faire cette demande. Par exemple, il suffit de copier/coller dans un terminal.

P.S.

Je me rends compte que ce n'est peut-être pas la "solution la plus simple" ni la "bonne" solution, mais elle est proposée au cas où quelqu'un le jugerait utile.

9
Maxim Mazurok

Si vous n'avez pas de reflog, par exemple. étant donné que vous travaillez dans un référentiel nu sur lequel le relogement n'est pas activé et que le commit que vous souhaitez récupérer a été créé récemment, une autre option consiste à rechercher les objets commit récemment créés et à les parcourir.

Depuis le répertoire .git/objects, exécutez:

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

Ceci trouve tous les objets (commits, fichiers, balises, etc.) créés au cours des 12 dernières heures et les filtre pour afficher uniquement les commits. Leur vérification est alors un processus rapide.

J'essaierais le script git-ressurect.sh mentionné dans réponse de Jakub d'abord.

9
Robert Knight

J'ai utilisé les commandes suivantes pour trouver et récupérer ma branche supprimée. Les premières étapes sont tirées 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'identifiant 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
8
Patrick Koorevaar

A ma connaissance, si une autre branche peut joindre la branche à supprimer, 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 celui-ci. Ainsi, lorsque vous supprimez une branche, vous supprimez un pointeur.

Vous ne perdrez même pas votre 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 ne peut pas supprimer une branche inaccessible en utilisant -d. Au lieu de cela, vous devez utiliser

git branch -D [branch]

Cela fait partie d'une vidéo à regarder absolument de Scott Chacon à propos de Git. Vérifiez la minute 58:00 quand il parle des branches et de leur suppression.

Introduction à Git avec Scott Chacon de GitHub

7
fabiopagoti

Pour récupérer une branche supprimée, commencez par consulter l'historique du reflog,

git reflog -n 60

Où n fait référence aux n derniers commits. Trouvez ensuite la tête appropriée et créez une branche avec cette tête.

git branch testbranch HEAD@{30}
4
sajin tm

Je rebasai une branche de la télécommande pour essayer de supprimer quelques commits dont je ne voulais pas et que je cherchais les bons que je voulais. Bien sûr, j'ai mal écrit les SHA ...

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

Commencez par générer une liste des commits en vrac dans votre journal. Faites-le dès que possible et arrêtez de travailler, car ceux-ci peuvent être déchargés par le ramasse-miettes.

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

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

cat lost | cut -d\  -f3 > commits

Maintenant vous avez un fichier commits 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'eux. Et attendez que vous appuyiez Enter. Maintenant, écrivez toutes celles que vous voulez, puis sélectionnez-les. Une fois que vous avez terminé, appuyez simplement sur Ctrl-C.

4
gcb

Assurez-vous d'effectuer tout cela localement et assurez-vous que votre référentiel est dans l'état souhaité avant de le transférer dans Bitbucket Cloud. Il peut également être judicieux de cloner votre référentiel actuel et de tester ces solutions en premier.

  1. Si vous venez de supprimer la branche, vous verrez quelque chose comme ceci dans votre terminal:
    Deleted branch <your-branch> (was <sha>)

2.Pour restaurer la branche, utilisez:

    git checkout -b <branch> <sha>

Si vous ne connaissez pas le 'sha', vous pouvez:

  1. Trouvez le 'sha' pour le commit au sommet de votre branche supprimée en utilisant:
    git reflog
  1. Pour restaurer la branche, utilisez:
    git checkout -b <branch> <sha>

Si vos commits ne sont pas dans votre refog:

  1. Vous pouvez essayer de récupérer une branche en réinitialisant votre branche sur le sha du commit trouvé en utilisant une commande comme:
    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

2.Vous pouvez ensuite afficher chaque commit en utilisant l’un des suivants:

    git log -p <commit>
    git cat-file -p <commit>
2
uyghurbeg

GRAND OUI

si vous utilisez GIT , suivez ces étapes simples https://confluence.atlassian.com/bbkb/how-to- restaurer-une-supprimé-branche-765757540.html

si vous utilisez smartgit et que vous avez déjà poussé cette branche , allez à Origine, recherchez cette branche et faites un clic droit, puis passez à la caisse

2
Aljohn Yamaro

Tout d’abord, allez dans git batch le déplacement vers votre projet comme:

cd Android studio project
cd Myproject
then type :
git reflog

Vous avez tous une liste des modifications et le numéro de référence prend le numéro de référence, puis passez à la caisse.
de Android studio ou du git betcha. une autre solution prend le numéro de référence et va sur Android studio cliquez sur git branches vers le bas, puis cliquez sur la balise de vérification ou la révision après le numéro de référence puis lol vous avez les branches.

1

En ajoutant à la réponse de tfe, vous pouvez récupérer avec le processus mentionné, à moins que les commits ne soient pas récupérés. La branche Git est simplement un pointeur sur une validation particulière dans l'arbre de validation. Mais si vous supprimez le pointeur et que les commits de cette branche ne sont pas fusionnés dans une autre branche existante, alors git le traite comme des commits suspendus et les supprime lors du garbage collection, qu'il peut exécuter automatiquement à intervalles réguliers.

Si votre branche n'a pas été fusionnée avec une branche existante et si elle a été collectée, vous perdrez tous les validations jusqu'au point où la branche a été créée depuis une branche existante.

1
Rajeshwar Agrawal

Un problème connexe: je suis arrivé sur cette page après avoir recherché "comment savoir quelles sont les branches supprimées".

Lors de la suppression de nombreuses vieilles branches, j’ai estimé que j’avais effacé par erreur une des nouvelles branches, mais je ne connaissais pas le nom pour le récupérer.

Pour savoir quelles branches ont été supprimées récemment, procédez comme suit:

Si vous allez sur votre URL Git, cela ressemblera à ceci:

https://your-website-name/orgs/your-org-name/dashboard

Ensuite, vous pouvez voir le flux de ce qui est supprimé, par qui, dans un passé récent.

1

Le simple fait d'utiliser git reflog ne m'a pas renvoyé le sha. Seul le commit id (qui a 8 caractères et un sha est beaucoup plus long)

J'ai donc utilisé git reflog --no-abbrev

Et ensuite, procédez comme indiqué ci-dessus: git checkout -b <branch> <sha>

0
MarvinVK