首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在不破坏文件历史的情况下合并两个Git存储库

在不破坏文件历史的情况下合并两个Git存储库
EN

Stack Overflow用户
提问于 2012-10-24 07:41:43
回答 6查看 108.8K关注 0票数 253

我需要将两个Git存储库合并成一个全新的第三个存储库。我发现了许多关于如何使用子树合并(例如How do you merge two Git repositories?上的Jakub Narębski's answer )来完成此操作的描述,并且遵循这些说明基本上是有效的,除了当我提交子树合并时,旧存储库中的所有文件都被记录为新添加的文件。当我执行git log时,我可以看到旧存储库的提交历史记录,但是如果我执行git log <file>,它只显示该文件的一个提交-子树合并。从上面答案的评论来看,我并不是唯一一个看到这个问题的人,但我还没有找到任何已发表的解决方案。

有没有办法合并存储库并保留单个文件的历史记录?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2013-01-23 07:57:18

事实证明,如果您只是试图将两个存储库粘合在一起,并让它看起来一直都是这样,而不是管理外部依赖,那么答案就简单多了。您只需向旧的存储库添加远程,将它们合并到新的主存储库中,将文件和文件夹移动到子目录中,提交移动,然后对所有其他存储库重复上述操作。子模块、子树合并和花哨的rebase旨在解决一个稍有不同的问题,并不适合我想要做的事情。

以下是将两个存储库粘合在一起的示例Powershell脚本:

代码语言:javascript
复制
# Assume the current directory is where we want the new repository to be created
# Create the new repository
git init

# Before we do a merge, we have to have an initial commit, so we'll make a dummy commit
git commit --allow-empty -m "Initial dummy commit"

# Add a remote for and fetch the old repo
# (the '--fetch' (or '-f') option will make git immediately fetch commits to the local repo after adding the remote)
git remote add --fetch old_a <OldA repo URL>

# Merge the files from old_a/master into new/master
git merge old_a/master --allow-unrelated-histories

# Move the old_a repo files and folders into a subdirectory so they don't collide with the other repo coming later
mkdir old_a
dir -exclude old_a | %{git mv $_.Name old_a}

# Commit the move
git commit -m "Move old_a files into subdir"

# Do the same thing for old_b
git remote add -f old_b <OldB repo URL>
git merge old_b/master --allow-unrelated-histories
mkdir old_b
dir –exclude old_a,old_b | %{git mv $_.Name old_b}
git commit -m "Move old_b files into subdir"

显然,如果您更愿意这样做,可以将old_b合并到old_a中(这将成为新的组合存储库)-修改脚本以适合您的需要。

如果您还想引入正在进行的功能分支,请使用以下命令:

代码语言:javascript
复制
# Bring over a feature branch from one of the old repos
git checkout -b feature-in-progress
git merge -s recursive -Xsubtree=old_a old_a/feature-in-progress

这是这个过程中唯一不明显的部分--这不是一个子树合并,而是一个常规递归合并的参数,它告诉Git我们重命名了目标,这有助于Git正确地排列所有内容。

我写了一个稍微详细的解释here

票数 298
EN

Stack Overflow用户

发布于 2020-05-30 09:05:27

假设您想要将存储库a合并到b中(我假设它们位于彼此的旁边):

代码语言:javascript
复制
cd b
git remote add a ../a
git fetch a
git merge --allow-unrelated-histories a/master
git remote remove a

如果您希望将a放入子目录,请在执行上述命令之前执行以下操作:

代码语言:javascript
复制
cd a
git filter-repo --to-subdirectory-filter a
cd ..

为此,您需要安装git-filter-repo (filter-branchdiscouraged)。

合并两个大型存储库的示例,将其中一个放入子目录:https://gist.github.com/x-yuri/9890ab1079cf4357d6f269d073fd9731

更多关于它的here

票数 16
EN

Stack Overflow用户

发布于 2012-10-24 09:56:23

请看一下如何使用

代码语言:javascript
复制
git rebase --root --preserve-merges --onto

将他们生命早期的两段历史联系起来。

如果有重叠的路径,请使用以下命令进行修复

代码语言:javascript
复制
git filter-branch --index-filter

当你使用log时,确保你“更难找到副本”,用

代码语言:javascript
复制
git log -CC

这样,您就可以找到路径中文件的任何移动。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13040958

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档