Très souvent, vous écrivez un projet quelconque, et après un certain temps, il devient clair qu'un composant du projet est en fait utile en tant que composant autonome (une bibliothèque, peut-être). Si vous avez eu cette idée dès le début, il y a de fortes chances que la plupart de ce code se trouve dans son propre dossier.
Existe-t-il un moyen de convertir l'un des sous-répertoires d'un projet Git en sous-module?
Idéalement, cela se produirait de telle sorte que tout le code de ce répertoire soit supprimé du projet parent et que le projet de sous-module soit ajouté à sa place, avec tout l'historique approprié, et de sorte que tous les validations du projet parent pointent vers le sous-module correct. .
git
git-submodules
rien101
la source
la source
Réponses:
Pour isoler un sous-répertoire dans son propre référentiel, utilisez
filter-branch
sur un clone du référentiel d'origine:Ce n'est alors rien de plus que de supprimer votre répertoire d'origine et d'ajouter le sous-module à votre projet parent.
la source
git remote rm <name>
après la branche de filtre, puis peut-être ajouter une nouvelle télécommande. De plus, s'il y a des fichiers ignorés, ungit clean -xd -f
peut être utile-- --all
peut être remplacé par le nom d'une branche si le sous-module ne doit être extrait que de cette branche.git clone <your_project> <your_submodule>
Télécharge- t-il uniquement des fichiers pour votre_submodule?git clone source destination
indique simplement à Git l'emplacement où placer vos fichiers clonés. La magie réelle pour filtrer les fichiers de votre sous-module se produit alors dans l'filter-branch
étape.filter-branch
est obsolète de nos jours. Vous pouvez utilisergit clone --filter
, mais votre serveur Git doit être configuré pour autoriser le filtrage, sinon vous obtiendrezwarning: filtering not recognized by server, ignoring
.Commencez par changer dir en dossier qui sera un sous-module. Ensuite:
la source
Je sais que c'est un vieux fil, mais les réponses ici écrasent tous les commits liés dans d'autres branches.
Un moyen simple de cloner et de conserver toutes ces branches et commits supplémentaires:
1 - Assurez-vous d'avoir cet alias git
2 - Clonez la télécommande, tirez toutes les branches, changez la télécommande, filtrez votre répertoire, poussez
la source
Cela peut être fait, mais ce n'est pas simple. Si vous recherchez
git filter-branch
,subdirectory
etsubmodule
, il y a des comptes rendus décents sur le processus. Cela implique essentiellement la création de deux clones de votre projet, en utilisantgit filter-branch
pour supprimer tout sauf un sous-répertoire dans l'un, et en supprimant uniquement ce sous-répertoire dans l'autre. Ensuite, vous pouvez établir le deuxième référentiel en tant que sous-module du premier.la source
Status Quo
Supposons que nous ayons un référentiel appelé
repo-old
qui contient un sous- répertoiresub
que nous aimerions convertir en un sous- module avec son propre dépôtrepo-sub
.Il est en outre prévu que le dépôt d'origine
repo-old
soit converti en un dépôt modifiérepo-new
où tous les commits touchant le soussub
- répertoire existant précédemment pointeront maintenant vers les commits correspondants de notre repo de sous-module extraitrepo-sub
.Changeons
Il est possible d'y parvenir à l'aide d'
git filter-branch
un processus en deux étapes:repo-old
versrepo-sub
(déjà mentionné dans la réponse acceptée )repo-old
àrepo-new
(avec un mappage de validation approprié)Remarque : je sais que cette question est ancienne et qu'il a déjà été mentionné qu'elle
git filter-branch
est un peu obsolète et pourrait être dangereuse. Mais d'un autre côté, cela pourrait aider les autres avec des référentiels personnels faciles à valider après la conversion. Alors soyez prévenu ! Et s'il vous plaît laissez-moi savoir s'il existe un autre outil qui fait la même chose sans être obsolète et est sûr à utiliser!Je vais vous expliquer comment j'ai réalisé les deux étapes sous linux avec la version 2.26.2 de git ci-dessous. Les versions plus anciennes peuvent fonctionner dans une certaine mesure, mais cela doit être testé.
Par souci de simplicité, je me limiterai au cas où il y a juste une
master
branche et uneorigin
télécommande dans le repo d'originerepo-old
. Sachez également que je compte sur des balises git temporaires avec le préfixetemp_
qui seront supprimées dans le processus. Donc, s'il y a déjà des balises nommées de manière similaire, vous voudrez peut-être ajuster le préfixe ci-dessous. Et enfin, sachez que je n'ai pas testé cela de manière approfondie et qu'il peut y avoir des cas secondaires où la recette échoue. Veuillez donc tout sauvegarder avant de continuer !Les extraits de code bash suivants peuvent être concaténés en un seul gros script qui doit ensuite être exécuté dans le même dossier où se trouve le dépôt
repo-org
. Il n'est pas recommandé de tout copier et coller directement dans une fenêtre de commande (même si j'ai testé cela avec succès)!0. Préparation
Variables
Script de filtrage
1. Extraction de sous-répertoires
2. Remplacement de sous-répertoire
Remarque: si le référentiel nouvellement créé se
repo-new
bloque pendant,git submodule update --init
essayez de re-cloner le référentiel de manière récursive une fois à la place:la source
Cela fait la conversion sur place, vous pouvez la sauvegarder comme vous le feriez pour n'importe quelle branche de filtre (j'utilise
git fetch . +refs/original/*:*
).J'ai un projet avec une
utils
bibliothèque qui a commencé à être utile dans d'autres projets, et je voulais diviser son histoire en sous-modules. Je n'ai pas pensé à regarder SO d'abord, alors j'ai écrit le mien, il construit l'historique localement donc c'est un peu plus rapide, après quoi si vous le souhaitez, vous pouvez configurer le.gitmodules
fichier de la commande d'assistance et autres, et pousser les historiques des sous-modules eux-mêmes n'importe où tu veux.La commande dépouillée elle-même est ici, la documentation dans les commentaires, dans la commande non rayée qui suit. Exécutez-le comme sa propre commande, avec
subdir
set, commesubdir=utils git split-submodule
si vous divisez leutils
répertoire. C'est hacky parce que c'est un one-off, mais je l'ai testé sur le sous-répertoire Documentation de l'historique Git.la source