Au départ, nos dépôts Git étaient des parties d'un seul dépôt SVN monstre où les projets individuels avaient chacun leur propre arbre, comme suit :
project1/branches
/tags
/trunk
project2/branches
/tags
/trunk
Évidemment, il était assez facile de déplacer des fichiers de l'un à l'autre avec svn mv
. Mais dans Git, chaque projet est dans son propre dépôt, et aujourd'hui on m'a demandé de déplacer un sous-répertoire de project2
à project1
. J'ai fait quelque chose comme ça :
$ git clone project2
$ cd project2
$ git filter-branch --subdirectory-filter deeply/buried/java/source/directory/A -- --all
$ git remote rm origin # so I don't accidentally overwrite the repo ;-)
$ mkdir -p deeply/buried/different/java/source/directory/B
$ for f in *.java; do
> git mv $f deeply/buried/different/java/source/directory/B
> done
$ git commit -m "moved files to new subdirectory"
$ cd ..
$
$ git clone project1
$ cd project1
$ git remote add p2 ../project2
$ git fetch p2
$ git branch p2 remotes/p2/master
$ git merge p2 # --allow-unrelated-histories for git 2.9+
$ git remote rm p2
$ git push
Mais ça semble assez alambiqué. Existe-t-il une meilleure façon de faire ce genre de choses en général ? Ou ai-je adopté la bonne approche ?
Notez que cela implique de fusionner l'historique dans un référentiel existant, plutôt que de simplement créer un nouveau référentiel autonome à partir d'une partie d'un autre référentiel ( comme dans une question précédente ).
1 votes
Cela me semble être une approche raisonnable ; je ne vois pas de moyen évident d'améliorer significativement votre méthode. C'est bien que Git rende cela facile (je ne voudrais pas essayer de déplacer un répertoire de fichiers entre différents référentiels dans Subversion, par exemple).
0 votes
Je ne voudrais pas non plus essayer de déplacer un répertoire entre deux dépôts svn différents ! (J'imagine un cauchemar impliquant svnadmin dump et svn dumpfilter, bleah).
1 votes
@ebneter - J'ai fait cela (déplacer l'historique d'un repo svn à un autre) manuellement, en utilisant des scripts shell. En gros, j'ai rejoué l'historique (diffs, messages de commit logs) de fichiers/dossiers particuliers dans un second dépôt.
1 votes
Je me demande pourquoi vous ne faites pas
git fetch p2 && git merge p2
au lieu degit fetch p2 && git branch .. && git merge p2
? Edit : alright, il semble que vous vouliez obtenir les changements dans une nouvelle branche nommée p2, et non dans la branche actuelle.0 votes
Pour ne reprendre que les commits de l'autre repo qui concerne le répertoire que vous déplacez, vous devez ajouter
--prune-empty
à lagit filter-branch
0 votes
J'ai aussi trouvé ce fil de discussion au cas où les fichiers que vous avez déplacés du projet2 avaient beaucoup d'historique et que vous vouliez effacer définitivement toutes les traces de ces fichiers, puisque vous avez l'historique dans un second projet : dalibornasevic.com/posts/
1 votes
N'y a-t-il aucun moyen d'empêcher --filter-branch de détruire la structure des répertoires ? Cette étape "git mv" résulte en un commit massif rempli de suppressions et de créations de fichiers.
1 votes
Notez que depuis git 2.9, la fusion d'historiques non liés est interdite par défaut. Pour que cela fonctionne, ajoutez
--allow-unrelated-histories
jusqu'au derniergit merge
pour que ça marche.0 votes
Duplicata possible de Détacher (déplacer) le sous-répertoire dans un dépôt Git distinct
0 votes
@Liam, ce n'est pas vraiment un doublon, car il s'agit de fusionner des choses dans l'historique d'un repo existant.
1 votes
Hé, le "overwrite" dans le commentaire "pour ne pas accidenter le repo" a été intentionnellement omis ! Je suppose que ce mème a été oublié :-)
9 votes
git filter-repo
est l'outil approprié pour faire cela en 2021, plutôt quefilter-branch
.