web-dev-qa-db-fra.com

Fusionner plusieurs référentiels git en un seul, en conservant l'historique des branches

J'ai quatre projets distincts. Ils ont leur propre dépôt git. et le même nom de succursales pour tous les projets.

 /project/
 /project/projA/
 /project/projA/.git/
 /project/projB/
 /project/projB/.git/
 /project/projC/
 /project/projC/.git/
 /project/projD/
 /project/projD/.git/

Tous les dépôts git ont le même nom de branches, et bien sûr leur propre branche master.

Question

Je voudrais fusionner tous les projets en un seul comme ceci:

  /Project/.git/
  /project/projA/
  /project/projB/
  /project/projC/
  /project/projD/

Mais

je veux garder l'histoire de toutes les branches.

ps -> j'ai le même nom de branches pour tous les repo. par exemple: un nom de branche utilisé pour les quatre projets: V6-004

Détails

J'ai essayé sous-module et sous-arbre mais les deux ne résolvent pas le problème.

J'ai aussi essayé ça.

  $ mkdir new_parent_project
  $ cd new_parent_project
  $ git init
  # Now we need to create the initial commit. This is essential.
  $ touch README.md
  $ git add README.md
  $ git commit -am "initial commit"

après

  # merge project ProjA into subdirectory ProjA
  $ git remote add -f ProjA http://GitUrl
  $ git merge -s ours --no-commit ProjA/V6-006
  $ git read-tree --prefix=ProjA/ -u ProjA/V6-006
  $ git commit -m "merging ProjA into subdir: ProjA"

après

  # merge project ProjB into subdirectory ProjB 
  $ git remote add -f ProjB http://GitUrl
  $ git merge -s ours --no-commit ProjB/V6-006
  $ git read-tree --prefix=ProjB/ -u ProjB/V6-006
  $ git commit -m "merging ProjB into subdir: ProjB"

mais

les projets sont fusionnés mais je n'ai que l'historique de V6-006. mais je n'ai pas d'histoire pour les autres branches.

23
Anas ZAHOURI

Cette solution n'est pas si loin de ce que vous avez essayé. Cela ne fonctionne que si vos différents projets n'ont pas de fichiers communs (sinon il peut être difficile de résoudre les conflits)

# create a new repo:
git init all_projects
cd all_project
# to make it more easy to understand, let's create a new branch
git checkout -b main

# import 1st project
git remote add projectA http://projectA
git fetch --all --tags
git checkout masterA projectA/master
git rebase masterA main
# move the main branch to the current state
git branch main -f
# Now your branch main is at the same state as your A project

# import 2st project
git remote add projectB http://projectB
git fetch --all --tags
git checkout masterB projectB/master
git rebase masterB main
# move the main branch to the current state
git branch main -f
# Now your branch main contains all commits from projectA and projectB

# etc..

Le résultat sera un référentiel avec tout d'abord toutes les validations du projet A, puis toutes les validations du projet B, même si le projet B a des validations datées avant la dernière validation du projet A, mais cela ne devrait pas être un problème (et l'arborescence historique sera plus facile à lire)

EDIT: Désolé, je remarque que cela ne résout pas votre problème pour obtenir toutes les branches distantes. Peut-être que vous pouvez trouver une solution basée sur cette question , avec quelque chose comme ceci:

for i in $(git branch -r |grep projectA|awk -F'/' '{print $2}'); do
  git checkout $i projectA/$i
  git rebase $i main
done

mais cela rendrait votre arbre plus complexe car toutes les branches commenceront à partir de la validation main.

12
Asenar