git - 将多个 git 仓库 merge 为一个,保留分支历史

标签 git github merge git-branch git-subtree

我有四个独立的项目。他们有自己的 git 仓库。所有项目的分支名称相同。

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

所有的git仓库都有同名的分支,当然还有自己的master分支。

问题

我想像这样将所有项目 merge 为一个:

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

但是

我想保留所有分支的历史记录。

ps -> 我对所有 repo 都有相同的分支名称。 例如:用于所有四个项目的分支名称: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"

但是

项目已 merge ,但我只有 V6-006 的历史记录。但我没有其他分支机构的历史记录。

最佳答案

该解决方案与您所尝试的相差无几。 这仅在您的不同项目没有公共(public)文件时才有效(否则可能难以解决冲突)

# 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 的最后一次提交,但这应该不是问题(并且历史树将更容易阅读)

编辑: 抱歉,我只是注意到这并不能解决您获取所有远程分支的问题。也许你可以找到基于 that question 的解决方案,像这样:

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

但这会使您的树更加复杂,因为所有分支将从 main 提交开始..

关于git - 将多个 git 仓库 merge 为一个,保留分支历史,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26502970/

相关文章:

Python:组合两个排序列表(并保持它们排序)而不使用内置排序

android - Git repo 同步 - 连接丢失

PHP Github Pull脚本错误 'permission denied (publickey)'

git - 带有 Laravel Sail 和版本控制的 Laravel 8 开发项目

git - 如何处理审查 pull 请求、修改代码和 merge ?

git - 如果我是一名开发人员,如何使用 git 分支?

reactjs - React-scripts 无法在 azure 部署上运行 npm run build

Git:如何在反向 merge 后提交本地更改

git - 我如何在 Mercurial 上执行 git reset --hard HEAD?

git - 撤消 IntelliJ 智能 checkout