Disons que j'ai une configuration qui ressemble à quelque chose
phd/code/
phd/figures/
phd/thesis/
Pour des raisons historiques, ils ont tous leurs propres référentiels git. Mais j'aimerais les combiner en un seul pour simplifier un peu les choses. Par exemple, en ce moment, je pourrais faire deux séries de changements et devoir faire quelque chose comme
cd phd/code
git commit
cd ../figures
git commit
Ce serait (maintenant) agréable de simplement jouer
cd phd
git commit
Il semble y avoir deux façons de le faire en utilisant des sous-modules ou en tirant de mes sous-répertoires, mais c'est un peu plus complexe que je ne le recherche. À tout le moins, je serais heureux
cd phd
git init
git add [[everything that's already in my other repositories]]
mais cela ne semble pas être une ligne. Y a-t-il quelque chose git
qui puisse m'aider?
Réponses:
Voici une solution que j'ai donnée ici :
Faites d'abord une sauvegarde complète de votre répertoire phd: je ne veux pas être tenu responsable de vos années de travail acharnées! ;-)
Déplacez le contenu de
phd/code
versphd/code/code
et corrigez l'historique afin qu'il ressemble à ce qu'il a toujours été là (cela utilise la commande filter-branch de git ):Idem pour le contenu de
phd/figures
etphd/thesis
(remplacez simplementcode
parfigures
etthesis
).Maintenant, la structure de votre répertoire devrait ressembler à ceci:
Créez ensuite un référentiel git dans le répertoire racine, tirez tout dedans et supprimez les anciens référentiels:
Enfin, vous devriez maintenant avoir ce que vous vouliez:
Un bon côté de cette procédure est qu'elle laissera les fichiers et répertoires non versionnés en place.
J'espère que cela t'aides.
Juste un mot d'avertissement cependant: si votre
code
répertoire a déjà uncode
sous - répertoire ou un fichier, les choses peuvent mal tourner (même chosefigures
etthesis
bien sûr). Si c'est le cas, renommez simplement ce répertoire ou fichier avant de passer par toute cette procédure:Et lorsque la procédure est terminée, ajoutez cette dernière étape:
Bien sûr, si le
code
sous - répertoire ou le fichier n'est pas versionné, utilisez simplement à lamv
place degit mv
, et oubliez legit commit
s.la source
mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD
et ensuite cela a très bien fonctionné!la source
Peut-être, simplement (de manière similaire à la réponse précédente, mais en utilisant des commandes plus simples) faire dans chacun des anciens référentiels séparés une validation qui déplace le contenu dans un sous-répertoire convenablement nommé, par exemple:
puis en fusionnant les trois dépôts séparés en un nouveau, en faisant smth comme:
Ensuite, vous sauvegarderez vos historiques, mais vous continuerez avec un seul dépôt.
la source
Vous pouvez essayer la stratégie de fusion des sous-arbres . Il vous permettra de fusionner le repo B dans le repo A. L'avantage
git-filter-branch
est qu'il ne vous oblige pas à réécrire votre historique du repo A (briser les sommes SHA1).la source
La solution git-filter-branch fonctionne bien, mais notez que si votre dépôt git provient d'une importation SVN, il peut échouer avec un message comme:
Dans ce cas, vous devez exclure la révision initiale de la branche de filtre - c'est-à-dire changer le
HEAD
à la fin en[SHA of 2nd revision]..HEAD
- voir:http://www.git.code-experiments.com/blog/2010/03/merging-git-repositories.html
la source
La solution @MiniQuark m'a beaucoup aidé, mais malheureusement, elle ne prend pas en compte les balises qui se trouvent dans les référentiels sources (au moins dans mon cas). Voici mon amélioration de la réponse @MiniQuark.
Créez d'abord un répertoire qui contiendra le référentiel composé et les repos fusionnés, créez un répertoire pour chaque fusionné.
Faites une extraction de chaque référentiel et récupérez toutes les balises. (Présentation des instructions uniquement pour le
code
sous-répertoire)(Il s'agit d'une amélioration au point 2 de la réponse MiniQuark) Déplacez le contenu de
new_phd/code
tonew_phd/code/code
et ajoutez uncode_
préfixe avant chaque baliseAprès cela, il y aura deux fois plus de balises qu'avant la branche de filtrage. Les anciennes balises restent dans le référentiel et de nouvelles balises avec
code_
préfixe sont ajoutées.Supprimez les anciennes balises manuellement:
Répétez le point 2,3,4 pour les autres sous-répertoires
Maintenant, nous avons la structure des répertoires comme au point de réponse @MiniQuark 3.
Faites comme au point 4 de la réponse de MiniQuark, mais après avoir fait un pull et avant de supprimer
.git
dir, récupérez les balises:Continuer..
Ceci est juste une autre solution. J'espère que cela aide quelqu'un, cela m'a aidé :)
la source
git-stitch-repo d' Aristotle Pagaltzis 'réponse ne fonctionne que pour les référentiels avec une histoire simple et linéaire.
La réponse de MiniQuark fonctionne pour tous les référentiels, mais elle ne gère pas les balises et les branches.
J'ai créé un programme qui fonctionne de la même manière que décrit MiniQuark, mais il utilise un commit de fusion (avec N parents) et recrée également toutes les balises et branches pour pointer vers ces commits de fusion.
Voir le référentiel git-merge-repos pour des exemples d'utilisation.
la source
J'ai créé un outil qui fait cette tâche. La méthode utilisée est similaire (faire en interne certaines choses comme --filter-branch) mais est plus conviviale. Est GPL 2.0
http://github.com/geppo12/GitCombineRepo
la source
En fait, git-stitch-repo prend désormais en charge les branches et les balises, y compris les balises annotées (j'ai trouvé un bogue que j'ai signalé et il a été corrigé). Ce que j'ai trouvé utile, c'est avec des balises. Comme les balises sont attachées aux validations, et certaines des solutions (comme l'approche d'Eric Lee) ne parviennent pas à gérer les balises. Vous essayez de créer une branche à partir d'une balise importée, et cela annulera toutes les fusions / mouvements de git et vous renverra comme le référentiel consolidé étant presque identique au référentiel d'où provient la balise. En outre, il existe des problèmes si vous utilisez la même balise dans plusieurs référentiels que vous avez «fusionné / consolidé». Par exemple, si vous disposez de l'annonce A du référentiel B, les deux ayant la balise rel_1.0. Vous fusionnez le référentiel A et le référentiel B dans le référentiel AB. Comme les balises rel_1.0 sont sur deux validations différentes (une pour A et une pour B), quelle balise sera visible dans AB? Soit l'étiquette du référentiel importé A, soit du référentiel importé B, mais pas les deux.
git-stitch-repo aide à résoudre ce problème en créant des balises rel_1.0-A et rel_1.0-B. Vous ne pourrez peut-être pas extraire la balise rel_1.0 et vous attendre aux deux, mais au moins vous pouvez voir les deux, et théoriquement, vous pouvez les fusionner dans une branche locale commune, puis créer une balise rel_1.0 sur cette branche fusionnée (en supposant que vous venez de fusionner et ne pas changer le code source). Il est préférable de travailler avec des succursales, car vous pouvez fusionner comme des succursales de chaque dépôt en succursales locales. (dev-a et dev-b peuvent être fusionnés en une branche de développement locale qui peut ensuite être poussée à l'origine).
la source
La séquence que vous avez suggérée
fonctionnera, mais vous perdrez votre historique de validation.
la source
Pour fusionner un secondProject au sein d'un mainProject:
A) Dans le deuxième projet
B) Dans le projet principal:
Dans cette branche, effectuez toutes les transformations lourdes que vous devez effectuer et validez-les.
C) Puis revenons au master et une fusion classique entre les deux branches:
la source
Je jetterai ma solution ici aussi. C'est essentiellement un wrapper de script bash assez simple
git filter-branch
. Comme d'autres solutions, il migre uniquement les branches principales et ne migre pas les balises. Mais les historiques de validation complets sont migrés et il s'agit d'un bref script bash, il devrait donc être relativement facile pour les utilisateurs de le réviser ou de le modifier.https://github.com/Oakleon/git-join-repos
la source
Ce script bash contourne le problème des caractères de l'onglet sed (sur MacOS par exemple) et le problème des fichiers manquants.
Ceci est une combinaison de miniquark , marius-Butuc et ryan messages de. Bravo à eux!
la source