web-dev-qa-db-fra.com

La référence de la tête de sous-module Git n'est pas un arbre

J'ai un projet avec un sous-module qui pointe vers une validation non valide: la validation du sous-module est restée locale et lorsque je tente de l'extraire d'un autre référentiel, je reçois:

$ git submodule update
fatal: reference is not a tree: 2d7cfbd09fc96c04c4c41148d44ed7778add6b43
Unable to checkout '2d7cfbd09fc96c04c4c41148d44ed7778add6b43' in submodule path 'mysubmodule'

Je sais ce que devrait être le sous-module HEAD. Existe-t-il un moyen de modifier cela localement, sans indiquer à partir du référentiel que est-ce que a commit 2d7cfbd09fc96c04c4c41148d44ed7778add6b43?

Je ne sais pas si je suis clair ... voici une situation similaire j'ai trouvé.

289
Mauricio Scheffer

En supposant que le référentiel du sous-module contienne une validation que vous souhaitez utiliser (contrairement à la validation référencée à partir de l'état actuel du super-projet), il existe deux façons de le faire.

La première nécessite que vous connaissiez déjà le commit du sous-module que vous voulez utiliser. Cela fonctionne de l'intérieur vers l'extérieur en ajustant directement le sous-module, puis en mettant à jour le super-projet. La seconde fonctionne à partir de “l'extérieur, dans” en recherchant le commit du super-projet qui a modifié le sous-module, puis en réinitialisant son index pour faire référence à un commit différent du sous-module.

À l'envers

Si vous savez déjà quel commit vous voulez que le sous-module utilise, cd au sous-module, extrayez le commit que vous voulez, puis git add et git commit dans le super-projet.

Exemple:

$ git submodule update
fatal: reference is not a tree: e47c0a16d5909d8cb3db47c81896b8b885ae1556
Unable to checkout 'e47c0a16d5909d8cb3db47c81896b8b885ae1556' in submodule path 'sub'

Oups, quelqu'un a créé un super-commit qui fait référence à un commit non publié dans le sous-module sub. D'une manière ou d'une autre, nous savons déjà que nous voulons que le sous-module soit à commit 5d5a3ee314476701a20f2c6ec4a53f88d651df6c. Allez-y et vérifiez-le directement.

Commander dans le sous-module

$ cd sub
$ git checkout 5d5a3ee314476701a20f2c6ec4a53f88d651df6c
Note: moving to '5d5a3ee314476701a20f2c6ec4a53f88d651df6c' which isn't a local branch
If you want to create a new branch from this checkout, you may do so
(now or later) by using -b with the checkout command again. Example:
  git checkout -b <new_branch_name>
HEAD is now at 5d5a3ee... quux
$ cd ..

Comme nous vérifions un commit, cela produit un HEAD détaché dans le sous-module. Si vous voulez vous assurer que le sous-module utilise une branche, utilisez git checkout -b newbranch <commit> pour créer et extraire une branche lors de la validation ou extrayez la branche souhaitée (par exemple, une avec la validation souhaitée à la pointe).

Mettre à jour le super projet

Une extraction dans le sous-module est reflétée dans le super-projet en tant que modification de l'arborescence de travail. Nous devons donc organiser le changement dans l'index du super-projet et vérifier les résultats.

$ git add sub

Vérifier les résultats

$ git submodule update
$ git diff
$ git diff --cached
diff --git c/sub i/sub
index e47c0a1..5d5a3ee 160000
--- c/sub
+++ i/sub
@@ -1 +1 @@
-Subproject commit e47c0a16d5909d8cb3db47c81896b8b885ae1556
+Subproject commit 5d5a3ee314476701a20f2c6ec4a53f88d651df6c

La mise à jour du sous-module était silencieuse car il est déjà à la validation spécifiée. Le premier diff montre que l'index et l'arbre de travail sont identiques. La troisième diff montre que le seul changement mis en scène est de déplacer le sous-module sub vers un commit différent.

Commettre

git commit

Ceci valide l’entrée de sous-module corrigée.


Dehors dans

Si vous ne savez pas quel commit utiliser dans le sous-module, vous pouvez consulter l'historique du superprojet pour vous guider. Vous pouvez également gérer la réinitialisation directement à partir du super-projet.

$ git submodule update
fatal: reference is not a tree: e47c0a16d5909d8cb3db47c81896b8b885ae1556
Unable to checkout 'e47c0a16d5909d8cb3db47c81896b8b885ae1556' in submodule path 'sub'

C'est la même situation que ci-dessus. Mais cette fois, nous allons nous concentrer sur la résolution du super-projet au lieu de plonger dans le sous-module.

Trouvez le Errant Commit du super-projet

$ git log --oneline -p -- sub
ce5d37c local change in sub
diff --git a/sub b/sub
index 5d5a3ee..e47c0a1 160000
--- a/sub
+++ b/sub
@@ -1 +1 @@
-Subproject commit 5d5a3ee314476701a20f2c6ec4a53f88d651df6c
+Subproject commit e47c0a16d5909d8cb3db47c81896b8b885ae1556
bca4663 added sub
diff --git a/sub b/sub
new file mode 160000
index 0000000..5d5a3ee
--- /dev/null
+++ b/sub
@@ -0,0 +1 @@
+Subproject commit 5d5a3ee314476701a20f2c6ec4a53f88d651df6c

OK, il semblerait que tout se soit mal passé dans ce5d37c. Nous allons donc restaurer le sous-module à partir de son parent (ce5d37c~).

Vous pouvez également prendre la validation du sous-module dans le texte du correctif (5d5a3ee314476701a20f2c6ec4a53f88d651df6c) et utiliser plutôt le processus ci-dessus «inside, out».

Commander dans le Super-projet

$ git checkout ce5d37c~ -- sub

Ceci réinitialise l'entrée du sous-module pour sub à ce qu'elle était à commit ce5d37c~ dans le super-projet.

Mettre à jour le sous-module

$ git submodule update
Submodule path 'sub': checked out '5d5a3ee314476701a20f2c6ec4a53f88d651df6c'

La mise à jour du sous-module s'est bien passée (elle indique un HEAD détaché).

Vérifier les résultats

$ git diff ce5d37c~ -- sub
$ git diff
$ git diff --cached
diff --git c/sub i/sub
index e47c0a1..5d5a3ee 160000
--- c/sub
+++ i/sub
@@ -1 +1 @@
-Subproject commit e47c0a16d5909d8cb3db47c81896b8b885ae1556
+Subproject commit 5d5a3ee314476701a20f2c6ec4a53f88d651df6c

Le premier diff montre que sub est maintenant identique à ce5d37c~. La deuxième diff montre que l'index et l'arbre de travail sont identiques. La troisième diff indique que le seul changement mis en scène déplace le sous-module sub vers un commit différent.

Commettre

git commit

Ceci valide l’entrée de sous-module corrigée.

368
Chris Johnsen

essaye ça:

git submodule sync
git submodule update
183
Lonre Wang

Cette erreur peut signifier qu'une validation est manquante dans le sous-module. C'est-à-dire que le référentiel (A) a un sous-module (B). A veut charger B de telle sorte qu'il pointe vers un certain commit (en B). Si cette validation est manquante, vous obtiendrez cette erreur. Une des causes possibles: la référence au commit a été insérée dans A, mais le commit n’a pas été poussé de B. Je commencerais par là.

Moins probable, il y a un problème d'autorisations, et le commit ne peut pas être tiré (possible si vous utilisez git + ssh).

Assurez-vous que les chemins de sous-modules sont corrects dans les fichiers .git/config et .gitmodules.

Une dernière chose à essayer - dans le répertoire du sous-module: git reset HEAD --hard

15
Daniel Tsadok

Cause possible

Cela peut arriver quand: 

  1. Les sous-modules ont été édités sur place
  2. Sous-module (s) validé (s), qui met à jour le hachage du sous-module désigné
  3. Sous-module non poussé .

par exemple. quelque chose comme ceci est arrivé:

$ cd submodule
$ emacs my_source_file  # edit some file(s)
$ git commit -am "Making some changes but will forget to Push!"

Le sous-module devrait être poussé à ce stade.

$ cd .. # back to parent repository
$ git commit -am "updates to parent repository"
$ git Push Origin master

En conséquence, les commits manquants n'ont pas pu être trouvés par l'utilisateur distant car ils sont toujours sur le disque local.

Solution

Informa la personne qui a modifié le sous-module en Push, c.-à-d.

$ cd submodule
$ git Push
9
chriskelly

J'ai eu cette erreur quand j'ai fait:

$ git submodule update --init --depth 1

mais le commit dans le projet parent pointait vers un commit précédent.
Suppression du dossier de sous-module et exécution

$ git submodule update --init

n'a pas résolu le problème. J'ai supprimé le repo et essayé à nouveau sans l'indicateur de profondeur et cela a fonctionné.

4
Plato

Cela peut également se produire lorsque vous avez un sous-module qui pointe vers un référentiel qui a été rebasé et que le commit donné est "parti". Bien que la validation puisse toujours figurer dans le référentiel distant, elle ne se trouve pas dans une branche. Si vous ne pouvez pas créer de nouvelle branche (pas votre référentiel, par exemple), vous êtes obligé de mettre à jour le super projet pour qu'il pointe vers un nouveau commit. Vous pouvez également utiliser l'une de vos copies des sous-modules ailleurs, puis mettre à jour le super-projet pour qu'il pointe vers ce référentiel.

4
pasamio

Cette réponse s'adresse aux utilisateurs de SourceTree ayant une expérience limitée de terminal git. 

Ouvrez le sous-module problématique à partir du projet Git (super-projet).

Récupérez et assurez-vous que «Récupérer toutes les balises» est coché.

Rebase tire ton projet Git.

Cela résoudra le problème «la référence n'est pas un arbre» ​​neuf fois sur dix. Ce n'est pas le cas, est un correctif terminal tel que décrit par la réponse du haut.

1
ericTbear

Pour synchroniser le dépôt git avec la tête du sous-module, au cas où ce soit vraiment ce que vous voulez, j'ai constaté que le fait de supprimer le sous-module puis de le lire en évitant de bricoler l'historique. Malheureusement, supprimer un sous-module nécessite un piratage plutôt qu'une simple commande git, mais c'est faisable.

Les étapes que j'ai suivies pour supprimer le sous-module, inspirées par https://Gist.github.com/kyleturner/1563153 :

  1. Exécuter git rm --cached 
  2. Supprimez les lignes pertinentes du fichier .gitmodules.
  3. Supprimez la section appropriée de .git/config.
  4. Supprimez les fichiers de sous-module maintenant non suivis.
  5. Supprimer le répertoire .git/modules /

Là encore, cela peut être utile si tout ce que vous voulez, c'est de pointer à nouveau la tête du sous-module, et vous n'avez pas compliqué les choses en conservant la copie locale du sous-module intacte. Il suppose que vous avez le sous-module "right" en tant que référentiel, quelle que soit son origine, et vous souhaitez simplement revenir à l'inclure correctement en tant que sous-module. 

Remarque: faites toujours une copie complète de votre projet avant de vous engager dans ce type de manipulation ou dans toute commande git au-delà de la simple validation ou de la diffusion. Je le conseillerais également pour toutes les autres réponses et en tant que directive générale de git.

0
matanster

L’historique de vos sous-modules est conservé en toute sécurité dans le sous-module git.

Alors, pourquoi ne pas simplement supprimer le sous-module et l'ajouter à nouveau?

Sinon, avez-vous essayé de modifier manuellement la HEAD ou le refs/master/head dans le sous-module .git

0
Lakshman Prasad

Dans mon cas, aucune des réponses ci-dessus ne résout le problème, même si ce sont de bonnes réponses. Je poste donc ma solution (dans mon cas, il y a deux clients Git, les clients A et B):

  1. aller au répertoire du sous-module:

    cd sub
    
  2. passer à maîtriser:

    git checkout master
    
  3. se rebase à un code de validation que les deux clients peuvent voir

  4. retournez dans le répertoire du parent:

  5. s'engager à maîtriser

  6. passez à l'autre client , faites à nouveau rebase.

  7. enfin ça marche bien maintenant! Peut-être perdre quelques commits mais cela fonctionne.

  8. Pour votre information, n'essayez pas de supprimer votre sous-module, il y restera .git/modules et ne pourra pas le relire à nouveau, sauf en cas de réactif local.

0
kimimaro

Je suis tombé par hasard sur ce problème et aucune de ces solutions n’a fonctionné pour moi. Ce qui s’est avéré être la solution à mon problème est en réalité beaucoup plus simple: mettez à niveau Git. Le mien était 1.7.1, et après l'avoir mis à jour à 2.16.1 (le dernier), le problème est parti sans laisser de trace! Je suppose que je le laisse ici, j'espère que cela aidera quelqu'un.

0
An Phan

Votre agence n’est peut-être pas à jour, solution simple, mais essayez git fetch

0
kittycatbytes

Juste pour être sûr, essayez de mettre à jour vos binaires git.

GitHub pour Windows a la version git version 1.8.4.msysgit.0 qui était dans mon cas le problème. La mise à jour l'a résolu.

0
Gman