Fondamentalement, mon problème est que je ne peux pas faire comprendre à git que ~/main-project/submodule
est un sous-module.
J'ai une bonne expérience des sous-modules git:
dans mon référentiel de fichiers dot J'ai créé le fichier .gitmodules dans ~/dotfiles-repo
et y ai ajouté des chemins et des URL. Depuis lors, si je modifie les fichiers des sous-modules et exécute git status
, j'obtiens un résultat du type: .vim/bundle/auto-complete (new commits) # in red
.
J'ai créé le fichier .gitmodules
dans ~/main-project
mais:
~/main-project/submodule
et même pousse les modifications, je ne reçois pas une réponse similaire à celle de <submodule> (new commits) # in red
lors de l'exécution de git status
dans ~/main-project
Je viens de connaître les modifications apportées à ces répertoiresLorsque je clique sur les liens des dossiers à github
pour ces répertoires, cela ne me dirige pas vers les référentiels eux-mêmes, mais je reste dans le même référentiel.
~/main-project/submodule
à l'index?J'ai lu cette question qui m'a amené à cette réponse Mais je ne suis pas sûr d'avoir besoin de git-subtree
. Je ne veux pas faire des choses qui pourraient faire des changements difficiles à revenir.
Edit: Cette solution de doublon suggérée n’a pas fonctionné non plus, j’ai reçu une erreur qui
Updates were rejected because the remote contains work that you do not have locally
. Il semble que @GabLeRoux m'a pratiquement dit de transmettre<repo-A>
à l'URL de<repo-B>
.
La solution est assez simple. Il a été extrait de ici .
git rm submodule-dir
submodule-dir
rm -rf submoduledir
submodule-dir
car git les aurait ignorés.git commit
submodul-dir
. Il est maintenant temps de le faire:git submodule add <remote-path-to-submodule>
.gitmodules
et de voir si les sous-modules ont été ajoutés avec succès. Dans mon cas, j'avais déjà un fichier .gitmodules
et je devais le modifier.Depuis v2.12.0-rc0 , et après ce commit , Nous avons reçu git submodule absorbgitdirs
et c’est exactement ce dont j'avais besoin au moment de poser cette question.
C’est ce que fait la docs state cette commande:
Si un répertoire git d'un sous-module est à l'intérieur du sous-module, déplacez le répertoire git du sous-module dans ses superprojets
$GIT_DIR/modules
chemin puis connectez le répertoire git et son répertoire de travail en définissant lecore.worktree
et en ajoutant un fichier .git pointant vers le répertoire git incorporé dans le fichier superprojects répertoire git.
Donc, au lieu de tout recommencer, comme suggéré dans les réponses précédentes par @DomQ et moi-même, on peut simplement ajouter exécuter ce qui suit:
.gitmodules
et à .git/config
avecgit submodule add <url> <path>
$GIT_DIR
du sous-module (.git
dans les référentiels classiques) vers .git/modules/<path>
avecgit submodule absorbgitdirs <path>
Il n’existe fondamentalement pas de meilleur moyen que de prétendre recommencer:
git submodule add
depuis le sous-référentiel distantcd mysubmodule
git fetch ../wherever/you/stashed/the/sub-repository/in/step-1
git merge FETCH_HEAD
Pour expliquer pourquoi, il me semble qu’une compréhension plus approfondie des sous-modules are est nécessaire, que ce que l’on peut extraire de la page de manuel git-submodule(1)
(ou même du pertinent)). chapitre du livre Git ). J'ai trouvé quelques explications plus détaillées sur cet article , mais comme cet article est un peu long, je prends la liberté de les résumer ici.
À un niveau bas, un sous-module git comprend les éléments suivants,
.git/modules
pour héberger les objets Git du sous-module,.gitmodules
.L'objet commit est contenu (ou plus précisément, référencé par SHA1) dans l'objet arbre parent. Ceci est inhabituel, car les choses (généralement } _ se produisent dans l'autre sens, mais cela explique pourquoi vous voyez un répertoire apparaître dans le git status
du référentiel principal après que vous ayez effectué une validation dans le sous-module. Vous pouvez également créer quelques expériences avec git ls-tree
pour observer cet objet commit plus en détail.
Le sous-répertoire dans .git/modules
correspond à un sous-répertoire .git
dans le sous-module; et en fait, il y a un .git
fichier dans le sous-module qui pointe vers l'ancien en utilisant une ligne gitdir:
. C'est le comportement par défaut depuis la version 1.7.8 de Git . Vous ne savez pas pourquoi tout ne fonctionnerait pas si vous gardiez un répertoire .git
séparé, sauf indication contraire dans les notes de mise à jour, vous rencontrerez probablement des problèmes lors du passage d'une branche contenant le sous-module à une autre.
Le fichier .gitmodules
fournit l'URL que git submodule update --remote
et ses amis doivent extraire; qui est évidemment distinct de l'ensemble des télécommandes du référentiel principal. Notez également que .gitmodules
est partiellement copié dans .git/config
par la commande git submodule sync
et les autres commandes l’appelant en arrière-plan.
Bien qu'il soit assez facile de faire les modifications nécessaires manuellement pour .gitmodules
+ .git/config
, et aussi pour .git/modules
+ mysubmodule/.git
(et en fait, il existe même git submodule absorbgitdirs
pour ce dernier), il n'y a pas vraiment de porcelaine pour créer uniquement le objet de validation in-tree. D'où la solution proposée en déplaçant + refaisant les modifications présentées ci-dessus.
Pour répondre à vos questions dans l'ordre:
git rm --cached submodule-name/
. Créez ensuite une validation intermédiaire, suivie de l'ajout du dossier en tant que référentiel: git add submodule-name
(notez qu'il y a no slash final après le nom du sous-module dans le cas des sous-modules).La réponse que vous avez mentionnée peut également corriger l’historique de vos commits:
Ce dossier sera traité comme un sous-module dans l'ensemble de votre historique de validation, pas seulement dans tous les futurs commits. Cela évite toute complication si vous passez à une version précédente dans laquelle elle était traitée comme un dossier. Ceci est une complication, car lorsque vous revenez au sommet de votre branche, vous devrez peut-être également entrer votre sous-module et vérifier le dernier commit pour restaurer tous les fichiers (qui peuvent être supprimés de votre répertoire de travail). Cela pourrait être évité en effectuant une sorte de vérification récursive de votre dernier commit.
Si l'historique de validation est modifié, tous les autres contributeurs devront également re-cloner le projet, car ils auront des conflits de fusion ou une situation pire. réintroduire le problème engage à nouveau dans le projet.