Объединение нескольких хранилищ git в один, сохранение истории веток

У меня есть четыре отдельных проекта. У них есть собственный репозиторий git. и одно и то же имя ветвей для всех проектов.

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

Все хранилища git имеют одно и то же имя ветвей и, конечно же, собственную ветку хозяина.

Вопрос

Я хотел бы объединить все проекты в один, например:

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

Но

Я хочу сохранить историю всех ветвей.

ps → я имеет одно и то же имя ветвей для всех репо. например: название ветки, используемое для всех четырех проектов: V6-004

Подробнее

Я пробовал подмодуль и поддерева, но оба они не решают проблему.

Я попробовал и это.

  $ 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"

после

  # 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"

после

  # 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"

, но

проекты объединяются, но у меня есть только история V6-006. но у меня нет истории для других ветвей.

Ответ 1

Это решение не так далеко от того, что вы пробовали. Это работает только в том случае, если в ваших разных проектах нет общих файлов (иначе это может быть трудно разрешить конфликты)

# create a new repo:
git init all_projects
cd all_project
# to make it more easy to understand, let 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..

Результатом будет репозиторий с 1-м, все коммиты из проекта A, затем все будут совершены из проекта B, даже если проект B имеет некоторые фиксации, датированные до последнего фиксации проекта A, но это не должно быть проблемой (и дерево истории будет легче читать)

EDIT: Извините, я просто заметил, что это не решит вашу проблему, чтобы получить все удаленные ветки. Возможно, вы можете найти решение на основе этого вопроса, с чем-то вроде этого:

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

но это сделает ваше дерево более сложным, потому что все ветки начнутся с main commit..