web-dev-qa-db-ja.com

複数のgitリポジトリを1つにマージし、ブランチの履歴を保持する

4つの別々のプロジェクトがあります。彼らは独自のgitリポジトリを持っています。すべてのプロジェクトで同じ名前のブランチ。

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

すべてのgitリポジトリには同じ名前のブランチがあり、もちろん独自のマスターブランチがあります。

質問

すべてのプロジェクトを次のように1つにマージしたいと思います。

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

だが

すべてのブランチの履歴を保持したい。

pS->私はすべてのリポジトリのブランチの同じ名前を持っています。例:4つのプロジェクトすべてに使用されるブランチ名:V6-004

細部

私はsubmodulesubtreeしかし、どちらも問題を解決しません。

これも試しました。

  $ 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の履歴しか持っていません。しかし、他のブランチの履歴はありません。

23
Anas ZAHOURI

その解決策は、あなたが試したことからそれほど遠くない。これは、異なるプロジェクトに共通ファイルがない場合にのみ機能します(そうしないと、競合を解決するのが難しい場合があります)

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

結果は、プロジェクト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から始まるため、これによりツリーがより複雑になります。

12
Asenar