J'ai commencé un projet il y a quelques mois et tout stocké dans un répertoire principal. Dans mon répertoire principal "Project", il y a plusieurs sous-répertoires contenant différentes choses: Project / paper contient un document écrit en LaTeX Project / sourcecode / RailsApp contient mon application rails.
"Project" est GITified et il y a eu beaucoup de commits dans les répertoires "paper" et "RailsApp". Maintenant, comme j'aimerais utiliser cruisecontrol.rb pour mon "RailsApp", je me demande s'il existe un moyen de créer un sous-module à partir de "RailsApp" sans perdre l'historique.
git
git-submodules
Cœur
la source
la source
Réponses:
De nos jours, il existe un moyen beaucoup plus simple de le faire que d'utiliser manuellement git filter-branch: git subtree
Installation
NOTE
git-subtree
fait maintenant partie degit
(si vous installez contrib) à partir de 1.7.11, donc vous l'avez peut-être déjà installé. Vous pouvez vérifier en exécutantgit subtree
.Pour installer git-subtree à partir des sources (pour les anciennes versions de git):
Ou si vous voulez les pages de manuel et tout
Usage
Divisez un plus grand en petits morceaux:
Pour une documentation détaillée (page de manuel), veuillez lire
git-subtree.txt
.la source
git rm -rf ./foo
supprimefoo
deHEAD
mais ne filtre pas l'my-project
historique de. Ensuite,git submodule add [email protected]:my-user/new-project.git foo
ne créefoo
un sous-module qu'à partir deHEAD
. À cet égard, le scriptfilter-branch
est supérieur car il permet de réaliser "faire comme si subdir était un sous-module depuis le tout début"Checkout git filter-branch .
La
Examples
section de la page de manuel montre comment extraire un sous-répertoire dans son propre projet tout en conservant toute son histoire et en supprimant l'historique des autres fichiers / répertoires (exactement ce que vous recherchez).la source
Une façon de faire est l'inverse: supprimez tout sauf le fichier que vous souhaitez conserver.
En gros, faites une copie du référentiel, puis utilisez
git filter-branch
pour supprimer tout sauf le fichier / les dossiers que vous souhaitez conserver.Par exemple, j'ai un projet dont je souhaite extraire le fichier
tvnamer.py
vers un nouveau référentiel:Cela permet
git filter-branch --tree-filter
de parcourir chaque commit, d'exécuter la commande et de réitérer le contenu des répertoires résultant. Ceci est extrêmement destructeur (vous ne devriez donc le faire que sur une copie de votre référentiel!), Et peut prendre un certain temps (environ 1 minute sur un référentiel avec 300 commits et environ 20 fichiers)La commande ci-dessus exécute simplement le script shell suivant sur chaque révision, que vous devrez bien sûr modifier (pour le faire exclure votre sous-répertoire au lieu de
tvnamer.py
):Le plus gros problème évident est qu'il laisse tous les messages de validation, même s'ils ne sont pas liés au fichier restant. Le script git-remove-empty-commits corrige ce problème.
Vous devez utiliser l'
-f
argument force run àfilter-branch
nouveau avec tout ce qui se trouve dansrefs/original/
(qui essentiellement une sauvegarde)Bien sûr, ce ne sera jamais parfait, par exemple si vos messages de commit mentionnent d'autres fichiers, mais c'est à peu près aussi proche qu'un git current le permet (pour autant que je sache de toute façon).
Encore une fois, ne l'exécutez que sur une copie de votre référentiel! - mais en résumé, pour supprimer tous les fichiers sauf "thisismyfilename.txt":
la source
git filter-branch
a (de nos jours?) une option intégrée pour supprimer les commits vides, à savoir--prune-empty
. Un meilleur guide pour segit filter-branch
trouve dans les réponses à cette question: stackoverflow.com/questions/359424/…Les réponses CoolAJ86 et apenwarr sont très similaires. J'ai fait des allers-retours entre les deux en essayant de comprendre les éléments qui manquaient à l'un ou l'autre. Voici une combinaison d'entre eux.
Naviguez d'abord dans Git Bash jusqu'à la racine du dépôt git à fractionner. Dans mon exemple ici, c'est
~/Documents/OriginalRepo (master)
Vous trouverez ci-dessous une copie de ce qui précède avec les noms personnalisables remplacés et utilisant plutôt https. Le dossier racine est maintenant
~/Documents/_Shawn/UnityProjects/SoProject (master)
la source
Si vous souhaitez transférer un sous-ensemble de fichiers vers un nouveau référentiel mais conserver l'historique, vous allez essentiellement vous retrouver avec un historique complètement nouveau. La façon dont cela fonctionnerait est essentiellement la suivante:
Il devrait être assez simple d'automatiser cela si cela ne vous dérange pas d'écrire un petit script mais poilu. Simple, oui, mais aussi douloureux. Les gens ont réécrit l'histoire dans Git dans le passé, vous pouvez faire une recherche pour cela.
Alternativement: clonez le référentiel et supprimez le papier dans le clone, supprimez l'application dans l'original. Cela prendrait une minute, il est garanti de fonctionner, et vous pouvez revenir à des choses plus importantes que d'essayer de purifier votre histoire git. Et ne vous inquiétez pas de l'espace disque occupé par les copies redondantes de l'historique.
la source