2010-08-21 5 views
8

J'avais plusieurs branches séparées, et je voulais les fusionner, car chacune d'elles était une mise à jour d'une partie différente du programme.Corriger le repo Git après une fusion incorrecte

Je suppose que j'étais censé les fusionner mais à la place j'ai couru un git commit -a après avoir mâché chaque branche.

Puis j'ai réalisé que tout le programme remontait dans le temps, donc j'ai exécuté un git reset --soft HEAD (j'ai lu dans un article quelque part que cela devrait aider), mais cela n'a rien fait.

J'ai également reçu ce message de git à propos de la suppression manuelle de certains ./git/index.lock, donc je l'ai déplacé à ./git/backup_of_index.lock, mais cela n'a pas semblé faire quoi que ce soit non plus.

Comment réparer mon référentiel et fusionner toutes les branches?

+3

revenir à une ancienne sauvegarde fonctionne toujours pour moi –

+8

Tout d'abord, faire une sauvegarde complète de votre arbre de travail et le dossier '.git' maintenant et le mettre dans un endroit sûr, en lecture seule de préférence. D'après ce que vous avez dit, il semble très improbable que vous ayez perdu votre travail (pas de 'reset --hard', et on dirait que vous étiez en train de jouer avec des choses commises sur des branches). Une fois que vous avez fait cela aller et trouver un expert git sur une chaîne interactive quelque part qui peut vous parler de la façon de rechercher et de restaurer votre état précédent. stackoverflow n'est presque certainement pas le forum pour cela, car vous avez besoin d'aide interactive, pas seulement un Q & A. –

+0

Merci à tous, je vais utiliser toutes les suggestions et comprendre quelque chose, je ne peux pas vraiment choisir une réponse pour le moment. –

Répondre

1

erreurs:

  1. «J'ai commencé à jouer avec git sur mon nouveau projet »
  2. « Je voulais juste les fusionner comme chacun d'entre eux ont été une mise à jour à différentes parties du programme »

Vous ne devriez pas jouer avec un territoire inconnu lorsque votre code a un sens. Si vous souhaitez faire cela, au moins avoir un plan de repli. La reprise après sinistre ne semble importante que pour ceux qui en ont le plus besoin, mais à ce moment-là, il est trop tard.

Je suis tout pour l'expérimentation mais je déteste voir ce genre de situation, je me sens mal pour le développeur car je connais bien ses chaussures mais après avoir appris cette erreur une fois que vous ne l'oublierez jamais. Avant de décider de jouer, prenez votre code et jetez-le ailleurs pour que lorsque sh * t touche le ventilateur, vous pouvez retourner dans votre zone de confort et continuer à travailler comme un développeur heureux et revenir à jouer après avoir obtenu votre travail effectué.

+0

Bien que je sois d'accord avec vos arguments, ce n'est pas une réponse à la question. Il devrait être affiché en tant que commentaire (bien que je sache que les commentaires ne peuvent pas contenir autant de texte). – Jeff

+4

J'ai commencé à taper dans le commentaire et j'ai manqué de place. : -/ – Chris

4

À moins d'avoir piraté les données du répertoire .git, il est peu probable que vous ayez perdu quoi que ce soit. Vous pouvez avoir un désordre terrible à nettoyer, et cela peut prendre beaucoup de travail sur ce que vous avez fait et où c'est, mais vous n'avez probablement rien perdu.

Voilà les bonnes nouvelles. La mauvaise nouvelle est qu'il sera diaboliquement difficile pour quiconque de vous aider beaucoup.

Il est probable que vous ayez besoin d'identifier toutes les branches et de remonter en arrière les validations sur chacune d'entre elles. Vous devrez décider si toutes ces opérations 'git commit -a' étaient une bonne idée. Cela semble improbable - vous devrez donc peut-être effectuer vos fusions correctement, en travaillant depuis l'avant-dernier commit sur chaque branche.

Vous devez également décider ce que vous essayez vraiment de faire.

Il semble que vous vouliez fusionner un certain nombre de branches - appelez-les BranchA, BranchB et BranchC - sur la branche principale, maître. Mais ce n'est pas clair c'est ce que vous avez essayé. Etant donné que les choses sont un peu en désordre, je recommande de créer une autre branche que nous pouvons appeler 'Fixup'. Créez ceci à partir de la tête de la branche principale.Ensuite, fusionnez la version appropriée de BranchA, BranchB et BranchC dans la branche Fixup. À chaque étape, vérifiez que le code fonctionne correctement - en transmettant sa suite de tests, etc. Vérifiez chaque fusion séparément sur la branche Fixup.

Lorsque vous êtes satisfait que la branche Fixup est correcte, revenez à la branche principale et fusionnez la branche Fixup à la version maître.


Charles Bailey fait la suggestion très raisonnable (dans un commentaire à la question): avant de faire quoi que ce soit d'autre, faire une copie de sauvegarde de ce que vous avez, exactement comme il est actuellement. Ensuite, continuez avec les opérations de nettoyage. Et sa suggestion d'obtenir de l'aide interactive est également judicieuse.

14

La commande git la plus importante dans cette situation est git reflog. Le reflog suit toutes les modifications apportées à chaque tête de branche particulière, et la commande git reflog répertorie toutes les modifications apportées à la tête de branche remontant dans le temps.

Si vous pouvez identifier un "bon" identifiant de validation en utilisant le reflog (et il sera là, quelque part), alors vous êtes en avance sur votre position actuelle. Si un bon engagement id est dire, abc123, la commande:

git checkout -b rescue abc123 

crée une nouvelle branche appelée rescue à l'engagement id abc123. Quand j'apprenais git, j'ai eu un genre similaire de "où diable suis-je et comment suis-je arrivé ici?" moment. J'ai découvert le refog sur un different Stack Overflow question, et c'est la chose la plus précieuse à savoir sur Git.

+0

Je seconde ce commentaire comme celui que vous devriez faire attention à Jonathan. Lancez 'git reflog' (ou' git log -g' pour obtenir les mêmes informations avec d'autres données), trouvez le dernier commit qui était bon et récupérez une branche à ce point. –

+0

En outre, il ya un peu de documentation sur une situation comme celle-ci ici: http://progit.org/book/ch9-7.html#data_recovery –

+0

Je venais ici pour dire "reflog!" juste à partir du titre de la question seul. – masonk

1

L'une des choses géniales à propos de Git est que vous pouvez facilement dupliquer l'ensemble de votre dépôt de travail. Cela vous permet de conserver une copie de sauvegarde pendant que vous expérimentez avec le branchement et la fusion.

Mon approche proposée pour résoudre votre problème actuel:

  1. Créer une copie de sauvegarde de l'intégralité de votre référentiel
  2. expérience des copies de jet-loin du dépôt
  3. Chaque fois que vous bousiller un throw- loin le dépôt - jetez-le et recommencez avec une nouvelle copie de votre sauvegarde
  4. Finalement, vous allez commencer à maîtriser le piratage repo - vous aurez récupéré votre travail, et vous vous sentirez bien de ce que vous avez appris

De plus, j'espère que vous utilisez gitk (ou similaire) pour examiner les effets de vos changements - il peut vraiment vous aider à visualiser les différentes lignes de code et la façon dont ils sont liés.

gitk --all ## show me all the branches 
+0

Aussi (encore mieux?): 'Gitk --reflog' - Je pense que c'est une nouvelle fonctionnalité, mais très utile. – nobar