1530 votes

Git: Comment puis-je concilier détaché de la TÊTE, maître/origine?

Je suis nouveau à la ramification de la complexité de Git. Je travaille toujours sur une seule branche et de valider les modifications et ensuite périodiquement pousser à ma télécommande d'origine.

Quelque part récemment, j'ai fait une remise à zéro de certains fichiers pour les faire sortir de commettre mise en scène, et plus tard a fait un rebase -i pour se débarrasser d'un couple de récentes modifications locales. Maintenant, je suis dans un état, je ne comprends pas très bien.

Dans ma zone de travail, git log montre exactement ce que je m'attendrais-je suis sur le bon train avec les commits je ne voulais pas disparu, et de nouveaux sont là, etc.

Mais j'ai juste poussé vers le dépôt distant, et ce qu'il y a de différent, un couple de tous les commits que j'ai tué dans le rebase a été repoussée, et les nouveaux engagés localement ne sont pas là.

Je pense que "maître/origine" est détaché de la TÊTE, mais je ne suis pas 100% clair sur ce que cela signifie, comment le visualiser avec les outils en ligne de commande, et comment le résoudre.

Votre point de vue/les pointeurs sont appréciés. Merci.

2484voto

Chris Johnsen Points 50064

Tout d'abord, nous allons clarifier ce que la TÊTE est et ce qu'il veut dire quand il est détaché.

La TÊTE est le nom symbolique pour la sorti de la validation. Lorsque la TÊTE n'est pas détachée à la "normale"1 situation: vous avez une branche vérifié), TÊTE de souligne en fait à une branche de la "ref" et les points de branchement à la livraison. La TÊTE est donc "attaché" à une branche. Lorsque vous effectuez un nouveau commit, la direction générale que la TÊTE est mise à jour pour pointer vers le nouveau commit. La TÊTE suit automatiquement depuis juste des points pour la branche.

  • git symbolic-ref HEAD rendements en refs/heads/master
    La branche nommée "maître" est cochée.
  • git rev-parse refs/heads/master rendement 17a02998078923f2d62811326d130de991d1a95a
    Que la validation est que la pointe de courant ou de "tête" de la branche master.
  • git rev-parse HEAD également yeilds 17a02998078923f2d62811326d130de991d1a95a
    C'est ce que signifie être un "symbolique ref". Il pointe vers un objet par une autre référence.
    (Symbolique refs ont été initialement mis en œuvre que les liens symboliques, mais plus tard changé à la plaine de fichiers avec l'interprétation supplémentaire afin qu'ils puissent être utilisés sur les plates-formes qui n'ont pas de liens symboliques.)

Nous avons HEADrefs/heads/master17a02998078923f2d62811326d130de991d1a95a

Lorsque la TÊTE est détachée, il pointe directement vers un commit-au lieu de faire indirectement de pointage à l'aide d'une branche. Vous pouvez penser à un décollement de la TÊTE comme sur un sans nom de la branche.

  • git symbolic-ref HEAD d'échec avec fatal: ref HEAD is not a symbolic ref
  • git rev-parse HEAD rendements en 17a02998078923f2d62811326d130de991d1a95a
    Car il n'est pas symbolique, ref, il doit pointer directement à le commettre lui-même.

Nous avons HEAD17a02998078923f2d62811326d130de991d1a95a

La chose importante à retenir avec un décollement de la TÊTE, c'est que si le commit c'est le contraire non référencées (aucun autre ref peut l'atteindre), puis il deviendra "pend" quand vous commander quelques autres de commettre. Enfin, ces balançant les validations seront taillés à travers le processus de nettoyage (par défaut, ils sont conservés pendant au moins 2 semaines et peuvent être conservés plus longtemps en étant référencé par le CHEF de l'reflog).

1 Il est parfaitement bien de faire de travail "normale" avec un décollement de la TÊTE, vous avez juste à garder une trace de ce que vous faites pour éviter d'avoir à poissons a chuté de l'histoire de la reflog.


Les étapes intermédiaires d'un rebase interactif sont fait avec un décollement de la TÊTE (en partie pour éviter de polluer l'actif de la direction générale de reflog). Si vous finissez le plein de rebase opération, elle sera mise à jour de l'original de votre branche avec le résultat cumulé de la rebase fonctionnement et remettre en place la TÊTE à l'origine de la branche. Ma conjecture est que vous n'avez jamais complètement achevé le processus de rebase; ce qui vous laisse avec un décollement de la TÊTE pointant vers le commit qui a été plus récemment traitées par le rebase opération.

Récupérer à partir de votre situation, vous devez créer une branche qui pointe vers le commit actuellement pointée par votre détaché de la TÊTE:

git branch temp
git checkout temp

(ces deux commandes peuvent être abrégé en git checkout -b temp)

Cela permettra de rattacher votre TÊTE vers le nouveau temp de la branche.

Ensuite, vous devez comparer l'état actuel de commettre (et son histoire) avec la normale de la branche sur laquelle vous vous attendiez à être à travailler:

git log --graph --decorate --pretty=oneline --abbrev-commit master origin/master temp
git diff master temp
git diff origin/master temp

(Vous aurez probablement envie d'expérimenter avec le journal des options: ajouter -p, laisser tomber --pretty=… voir tout le message de log, etc.)

Si votre nouveau - temp de la branche semble bon, vous souhaitez mettre à jour (par exemple,) master de point de:

git branch -f master temp
git checkout master

(ces deux commandes peuvent être abrégé en git checkout -B master temp)

Vous pouvez ensuite supprimer le temporaire de la branche:

git branch -d temp

Enfin, vous aurez probablement envie de pousser les rétabli l'histoire:

git push origin master

Vous avez beaucoup ont besoin d'utiliser --force pour pousser si la branche à distance ne peut pas être "avance rapide" pour le nouveau commit (c'est à dire que vous avez laissé tomber, ou réécrit certains commettent, ou autrement réécriture de certains bits de l'histoire).

Si vous avez été dans le milieu d'un rebase opération, vous devriez probablement le nettoyer. Vous pouvez vérifier si un rebase a été dans le processus de recherche le répertoire .git/rebase-merge/. Vous pouvez nettoyer manuellement en cours de rebase tout simplement en supprimant le répertoire (par exemple, si vous ne vous souvenez plus du but et du contexte de l'actif rebase opération). Habituellement, vous devez utiliser git rebase --abort, mais qui fait partie supplémentaire de réinitialisation que vous voulez probablement à éviter (il bouge la TÊTE en arrière à l'original de la direction générale et le remet à zéro à l'origine de commettre, qui permet d'annuler une partie du travail que nous avons fait ci-dessus).

618voto

Daniel Alexiuc Points 2304

Faites simplement ceci:

git checkout master

Si cela n'est pas fixe, ce sera:

git checkout -b temp
git branch -f master temp
git checkout master

123voto

dimadima Points 2803

Je viens de tomber sur ce problème et dès que j'ai lu

La TÊTE est le nom symbolique pour la sorti de la validation.

dans le haut-voté réponse, j'ai pensé: "Ah-ha! Je vais juste rebase!" J'ai voulu apporter les commits derrière et y compris le détachement HEAD qui n'étaient pas encore en master en master, et git rebase vous permet de le faire:

git rebase HEAD master

Pour moi, cela dit:

Prendre le parent s'engage de la TÊTE vers le point où les histoires de la TÊTE et du maître divergé, et de lire ces s'engage sur le dessus de maître. Ensuite, vérifier maître.

Concilier plus loin avec origin/master est alors une question de concilier la nouvelle-relocalisée master avec origin/master. Pour cela, vous pouvez ls-remote ou fetch origin/master et de comparer les journaux.

Les autres réponses sur ce fil sont très agréable, et certainement la peine de lire attentivement, mais mon approche semble très bien si vous êtes dans une situation simple.

81voto

manojlds Points 96599

Regardez ici pour l'explication de base de décollement de la tête:

http://git-scm.com/docs/git-checkout

Ligne de commande pour le visualiser:

git branch

ou

git branch -a

vous obtenez un résultat comme ci-dessous:

* (no branch)
master
branch1

L' * (no branch) montre que vous êtes dans décollement de la tête.

Vous aurait pu arriver à cet état en faisant un git checkout somecommit etc. et il vous aura prévenu par le suivant:

Vous êtes dans " détaché de la TÊTE de l'état. Vous pouvez regarder autour, expérimentaux les changements et de les valider, et vous pouvez jetez tous les commits que vous faites dans ce état sans impact sur les branches en effectuant une autre caisse.

Si vous souhaitez créer une nouvelle branche à conserver engage que vous créez, vous pouvez le faire (maintenant ou plus tard) à l'aide de b avec l' la caisse commande de nouveau. Exemple:

git checkout -b new_branch_name

Maintenant, pour obtenir sur master:

Faire un git reflog ou même juste git log et notez vos commits. Maintenant, git checkout master et git merge le commet.

git merge HEAD@{1}

Edit:

Pour ajouter, utilisez git rebase -i non seulement pour la suppression et la mise à mort s'engage à ce que vous n'avez pas besoin, mais aussi pour les modifier. Il suffit de mentionner "modifier" dans la validation de la liste et vous serez en mesure de modifier votre livraison et un numéro d' git rebase --continue d'aller de l'avant. Cela aurait assuré que vous n'avez jamais eu dans un décollement de la TÊTE.

35voto

Rose Perrone Points 14478

Obtenez votre détachée commettre sur sa propre branche

Exécutez simplement git checkout -b mynewbranch.

Ensuite, exécutez git log, et vous verrez que la validation est maintenant HEAD sur cette nouvelle branche.

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