Eri*_*Lee 209 git git-subtree
我需要将两个Git存储库合并到一个全新的第三个存储库中.我已经找到了很多关于如何使用子树合并进行此操作的描述(例如JakubNarębski关于如何合并两个Git存储库的答案?)并遵循这些说明大多数工作,除了当我提交子树合并所有文件从旧存储库记录为新添加的文件.我可以在旧的存储库中看到提交历史记录git log,但如果我这样做git log <file>,则只显示该文件的一次提交 - 子树合并.从对上述答案的评论来看,我并不是唯一一个看到这个问题的人,但我发现没有公开的解决方案.
有没有办法合并存储库并保持个别文件历史记录完整?
Eri*_*Lee 255
事实证明,如果您只是尝试将两个存储库粘合在一起并使其看起来像是一直这样,而不是管理外部依赖,那么答案会更简单.您只需将遥控器添加到旧的存储库,将它们合并到新的主存储器,将文件和文件夹移动到子目录,提交移动,然后重复所有其他存储库.子模块,子树合并和花哨的rebase旨在解决稍微不同的问题,并不适合我试图做的事情.
这是一个将两个存储库粘合在一起的Powershell脚本示例:
# 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
git remote add -f 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"
Run Code Online (Sandbox Code Playgroud)
显然你可以将old_b合并到old_a(它成为新的组合repo),如果你更愿意这样做 - 修改脚本以适应.
如果您还要引入正在进行的功能分支,请使用以下命令:
# 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
Run Code Online (Sandbox Code Playgroud)
这是该过程中唯一不明显的部分 - 这不是子树合并,而是普通递归合并的参数,告诉Git我们重命名了目标,这有助于Git正确排列所有内容.
我在这里写了一个稍微详细的解释.
Fli*_*imm 140
这是一种不会重写任何历史记录的方法,因此所有提交ID都将保持有效.最终结果是第二个repo的文件最终会出现在子目录中.
将第二个repo添加为远程:
cd firstgitrepo/
git remote add secondrepo username@servername:andsoon
Run Code Online (Sandbox Code Playgroud)确保您已经下载了所有secondrepo的提交:
git fetch secondrepo
Run Code Online (Sandbox Code Playgroud)从第二个repo的分支创建一个本地分支:
git branch branchfromsecondrepo secondrepo/master
Run Code Online (Sandbox Code Playgroud)将其所有文件移动到子目录中:
git checkout branchfromsecondrepo
mkdir subdir/
git ls-tree -z --name-only HEAD | xargs -0 -I {} git mv {} subdir/
git commit -m "Moved files to subdir/"
Run Code Online (Sandbox Code Playgroud)将第二个分支合并到第一个repo的主分支中:
git checkout master
git merge --allow-unrelated-histories branchfromsecondrepo
Run Code Online (Sandbox Code Playgroud)您的存储库将有多个root提交,但这不会造成问题.
x-y*_*uri 15
假设您想将存储库合并a到b(我假设它们并排放置):
cd b
git remote add a ../a
git fetch a
git merge --allow-unrelated-histories a/master
git remote remove a
Run Code Online (Sandbox Code Playgroud)
如果您想放入a子目录,请在执行上述命令之前执行以下操作:
cd a
git filter-repo --to-subdirectory-filter a
cd ..
Run Code Online (Sandbox Code Playgroud)
为此,您需要git-filter-repo安装(filter-branch被劝阻)。
合并 2 个大型存储库,将其中一个放入子目录的示例:https : //gist.github.com/x-yuri/9890ab1079cf4357d6f269d073fd9731
更多关于它在这里。
aba*_*sta 14
几年过去了,有一些基于良好投票的解决方案,但我想分享我的解决方案,因为它有点不同,因为我想将 2 个远程存储库合并到一个新的存储库中,而不删除以前存储库的历史记录。
在 Github 中创建一个新的存储库。
下载新创建的 repo 并添加旧的远程存储库。
git clone https://github.com/alexbr9007/Test.git
cd Test
git remote add OldRepo https://github.com/alexbr9007/Django-React.git
git remote -v
Run Code Online (Sandbox Code Playgroud)从旧 repo 中获取所有文件,以便创建一个新分支。
git fetch OldRepo
git branch -a
Run Code Online (Sandbox Code Playgroud)
在 master 分支中,进行合并以将旧 repo 与新创建的 repo 合并。
git merge remotes/OldRepo/master --allow-unrelated-histories
Run Code Online (Sandbox Code Playgroud)
创建一个新文件夹来存储从 OldRepo 添加的所有新创建的内容,并将其文件移动到这个新文件夹中。
最后,您可以从合并的存储库上传文件并从 GitHub 安全地删除 OldRepo。
希望这对处理合并远程存储库的任何人都有用。
请看看使用情况
git rebase --root --preserve-merges --onto
Run Code Online (Sandbox Code Playgroud)
在他们生命的早期联系两个历史.
如果您有重叠的路径,请使用它们进行修复
git filter-branch --index-filter
Run Code Online (Sandbox Code Playgroud)
当您使用日志时,请确保"更难找到副本"
git log -CC
Run Code Online (Sandbox Code Playgroud)
这样你就可以在路径中找到任何文件移动.
我将解决方案从@Flimm改为git alias像这样(添加到我的~/.gitconfig):
[alias]
mergeRepo = "!mergeRepo() { \
[ $# -ne 3 ] && echo \"Three parameters required, <remote URI> <new branch> <new dir>\" && exit 1; \
git remote add newRepo $1; \
git fetch newRepo; \
git branch \"$2\" newRepo/master; \
git checkout \"$2\"; \
mkdir -vp \"${GIT_PREFIX}$3\"; \
git ls-tree -z --name-only HEAD | xargs -0 -I {} git mv {} \"${GIT_PREFIX}$3\"/; \
git commit -m \"Moved files to '${GIT_PREFIX}$3'\"; \
git checkout master; git merge --allow-unrelated-histories --no-edit -s recursive -X no-renames \"$2\"; \
git branch -D \"$2\"; git remote remove newRepo; \
}; \
mergeRepo"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
85787 次 |
| 最近记录: |