Pousser un dépôt Git existant vers Github envoie seulement environ la moitié des commits

StackOverflow https://stackoverflow.com/questions/237408

  •  04-07-2019
  •  | 
  •  

Question

J'ai développé un référentiel Git local depuis quelques jours: il contient dix-huit validations jusqu'à présent. Ce soir, j'ai créé un référentiel privé Github auquel j'espérais pouvoir accéder; Cependant, lorsque je l'ai fait, cela n'a fini que de pousser huit des dix-huit commits vers Github. J'ai supprimé le dépôt Github et j'ai essayé à nouveau, avec le même résultat.

Avez-vous une idée de la raison pour laquelle cela pourrait se produire? J'ai déjà fait cette procédure auparavant sans succès, donc je suis un peu perplexe.

Mettre à jour : il n'y a toujours eu que la branche principale de ce référentiel. Juste pour répondre à quelques unes des réponses affichées ...

Était-ce utile?

La solution

J'ai jeté un coup d'œil au référentiel en question et voici ce qui se passait:

  • À un moment donné, rpj avait exécuté git checkout [commit id] . Cela a orienté HEAD vers un commet en vrac plutôt que vers une branche reconnue. Je crois que c’est le "HEAD suspendu". problème auquel fait référence CesarB.
  • Ne réalisant pas ce problème, il continua à faire des changements et à les commettre, ce qui souleva HEAD à chaque fois. Cependant, HEAD ne faisait que pointer une chaîne de commits en suspens, et non une branche reconnue.
  • Quand il est allé pousser ses modifications, git a tout poussé vers le haut du maître, ce qui n’était qu’à peu près à mi-chemin de l’arbre où il se trouvait.
  • La confusion a suivi

Ce diagramme devrait le rendre plus clair:

                 -- D -- E -- F
                /             ^
   A -- B -- C -              |
   ^         ^               HEAD
   |         |
 remote    master

Lorsqu'il a essayé d'appliquer ses modifications, seul A à C a été poussé et à distance est passé à C . D par le biais de F , il n'a pas pu envoyer les commits, car ils ne sont pas référencés par une branche connue.

Voici ce que vous voyez lorsque vous êtes dans cet état:

$ git branch
* (no branch)
master

La solution consiste à déplacer maître vers F dans la chaîne des commits en suspens. Voici comment je l'ai fait.

  • Créez une branche légitime pour l'état actuel:

    git checkout -b tmp

    • La branche tmp pointe maintenant sur commit F dans le diagramme ci-dessus
  • avancez maître vers tmp

    maître de caisse git

    tmp de fusion de git

    • master pointe maintenant sur commit F .
  • Jeter votre branche temporaire

    branche git -d tmp

  • Vous pouvez facilement accéder au référentiel distant et celui-ci devrait envoyer toutes vos modifications.

Autres conseils

À partir de Git 1.7.3, vous pouvez le faire avec une simple commande:

git checkout -B master

Le commutateur -b signifie "créer une branche ici avant de l'extraire" et -B en est la version inconditionnelle, "même si la branche existe déjà - en Dans ce cas, déplacez-le ici avant de le vérifier ».

Une solution très simple pour résoudre ce type de problème consiste à simplement supprimer la branche master et à la recréer. Après tout, les branches dans git ne sont que des noms pour les commits et la branche master n’a rien de spécial.

En supposant que la validation actuelle soit celle que vous voulez que maître soit, il vous suffit de faire

git branch -D master

pour supprimer la branche maître existante, puis faites

git checkout -b master

a) crée une nouvelle branche appelée maître qui pointe vers la validation actuelle et b) met à jour HEAD pour pointer vers la branche maître . Après cela, HEAD sera attaché à master et donc master sera déplacé à chaque fois que vous validez.

Vérifiez si vous poussez les branches correctes et que celles-ci possèdent réellement ce que vous pensez avoir. En particulier, vérifiez si vous n’avez pas de tête séparée, ce qui peut être assez déroutant s’il n’est pas fait exprès.

Le moyen le plus simple de vérifier consiste à utiliser gitk --all , qui affiche graphiquement toutes les branches, HEAD et plus encore.

Je suppose que la première chose à faire serait d'exécuter git fsck sur votre référentiel local pour vous assurer que tout est en ordre.

Je n'ai jamais vu ce problème auparavant et je ne vois pas ce qui pourrait ne pas être correct.

Je n'ai pas la réputation de commenter directement la réponse précédente de CesarB, mais gitk --all ne fonctionne pas dans ce cas car il ne répertorie que les branches connues.

gitk HEAD montre ce problème, mais ce n'est pas tout à fait clair. Le problème est que master apparaît dans l’arbre de validation plutôt que lors de la dernière validation.

Donc, il s'avère que les deux: le hachage de commit dans .git / refs / heads / master était correct et les informations dans .git / logs / refs / heads / master étaient incomplètes; en ce sens que je veux dire que cela n'a été intégré que dans le hachage de validation spécifié dans .git / refs / heads / master.

Une fois que j'ai corrigé ces fichiers (à la main) et que j'ai été renvoyé à Github, tout était redevenu saucisse. Je n’ai toujours aucune idée de ce qui est arrivé pour que les choses se passent dans cet état, mais je suis content d’avoir au moins trouvé la solution.

Au cas où quelqu'un se demanderait: pour réparer .git / refs / heads / master, je viens de remplacer le contenu de ce fichier par le dernier hachage de validation (HEAD), et de corriger .git / logs / refs / heads / master , J'ai simplement copié le contenu de .git / logs / HEAD dans .git / logs / refs / heads / master. Facile comme bonjour ... PAS.

J'ai eu le même problème deux fois et j'ai finalement compris ce que je faisais qui le causait. En train de modifier un ancien commit avec git rebase -i , au lieu d'appeler git commit --amend , j'appelais git commit -a par habitude, immédiatement suivi de git rebase --continue , bien sûr. Quelqu'un d’autre pourrait peut-être expliquer ce qui se passe dans les coulisses, mais il semble que le résultat soit le problème isolé de HEAD.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top