-->

合并两个Git仓库没有打破历史文件(Merge two Git repositories witho

2019-06-18 14:46发布

我需要将两个Git仓库合并成一个全新的,第三收纳库。 我发现了如何做到这一点使用的子树合并(例如许多描述的JakubNarębski的回答对你如何合并两个Git仓库? ),并遵循着这些指导主要工作,除了当我犯的子树合并的所有文件从旧仓库被记录为新添加的文件。 我可以看到老库的提交历史,当我做git log ,但如果我做git log <file> ,仅显示一个提交该文件-子树合并。 从上述答案的评论来看,我不是一个人在看到这个问题,但我发现它没有公布方案。

有什么办法不合并存储库,并留下个人文件历史记录是否完​​整?

Answer 1:

事实证明,答案是简单得多,如果你只是想粘上两个储存在一起,使它看起来就像是这样一直而非管理的外部依赖。 您只需将遥控器的文件和文件夹添加到您的旧档案库,把它们合并到你的新主人,移动到一个子目录,提交移动,并重复所有附加回购。 子模块,子树合并,和花哨的底垫是为了解决一个稍微不同的问题,不适合什么,我要怎样做。

下面是一个例子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"

很明显,你可以改为合并old_b到old_a(成为新合并回购),如果你宁愿做 - 修改以适应脚本。

如果你想带过来正在进行的功能分支为好,这样使用:

# 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帮助行一切。

我写了一个稍微更详细的解释在这里 。



Answer 2:

下面是一个不重写任何历史的一种方式,因此所有提交的ID将仍然有效。 最终的结果是,第二回购的文件将在子目录中结束。

  1. 添加第二个回购为远程:

     cd firstgitrepo/ git remote add secondrepo username@servername:andsoon 
  2. 请确保您已经下载了全部secondrepo的提交内容:

     git fetch secondrepo 
  3. 创建一个从第二回购的分支本地分支:

     git branch branchfromsecondrepo secondrepo/master 
  4. 将所有的文件放到一个子目录:

     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/" 
  5. 合并第二支进入第一回购的主分支:

     git checkout master git merge --allow-unrelated-histories branchfromsecondrepo 

您的仓库将有超过一个根犯,但这不应该成为问题。



Answer 3:

请看看使用

git rebase --root --preserve-merges --onto

早在他们的生活连接两个历史。

如果您有重叠的路径,解决这些问题了

git filter-branch --index-filter

当您使用日志,保证你“找到副本难度”与

git log -CC

这样你会发现在路径文件中的任何动作。



Answer 4:

我把解决方案从@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"


Answer 5:

此功能将克隆远程回购到本地回购目录:

function git-add-repo
{
    repo="$1"
    dir="$(echo "$2" | sed 's/\/$//')"
    path="$(pwd)"

    tmp="$(mktemp -d)"
    remote="$(echo "$tmp" | sed 's/\///g'| sed 's/\./_/g')"

    git clone "$repo" "$tmp"
    cd "$tmp"

    git filter-branch --index-filter '
        git ls-files -s |
        sed "s,\t,&'"$dir"'/," |
        GIT_INDEX_FILE="$GIT_INDEX_FILE.new" git update-index --index-info &&
        mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"
    ' HEAD

    cd "$path"
    git remote add -f "$remote" "file://$tmp/.git"
    git pull "$remote/master"
    git merge --allow-unrelated-histories -m "Merge repo $repo into master" --edit "$remote/master"
    git remote remove "$remote"
    rm -rf "$tmp"
}

如何使用:

cd current/package
git-add-repo https://github.com/example/example dir/to/save

利润!



Answer 6:

几年过去了,有良好的基础上投票解决方案,但我想分享我的,因为这是一个有点不同,因为我想合并2个远程仓库成一个,而从以前的资料库中删除历史记录。

  1. 创建新仓库。

  2. 下载新创建的回购和增加老远程仓库。

     git clone https://github.com/alexbr9007/Test.git cd Test git remote add OldRepo https://github.com/alexbr9007/Django-React.git git remote -v 
  3. 所以一个新的分支被创建获取从旧回购的所有文件。

     git fetch OldRepo git branch -a 

  4. 在主分支,做一个合并的老回购与新创建的一个结合。

     git merge remotes/OldRepo/master --allow-unrelated-histories 

  5. 创建一个新的文件夹来存储所有从OldRepo添加新创建的内容和移动的文件到这个新文件夹。

  6. 最后,您可以从合并回购上传的文件,并安全地从GitHub删除OldRepo。

希望这可以为任何人处理合并远程仓库有用。



Answer 7:

按照以下步骤嵌入一个回购协议到另一个回购,通过合并这两个混帐历史有一个单一的git的历史。

  1. 克隆既要合并的回购。

混帐克隆git@github.com:用户/父repo.git

混帐克隆git@github.com:用户/儿童repo.git

  1. 转到孩子回购

CD儿童回购/

  1. 运行以下命令,替换路径my/new/subdir ,你想有孩子回购与目录结构(3个出现次数)。

git的过滤分支--prune空--tree过滤器“如果[! -e我的/新/子目录] 随后的mkdir -p我的/新/子目录git的LS-树--name仅$ GIT_COMMIT | xargs的-I文件MV文件我的/新/子目录科幻”

  1. 转到母公司回购

CD ../parent-repo/

  1. 添加远程母公司回购,指向路径孩子回购

远程Git添加子远程../child-repo/

  1. 取孩子回购

混帐取儿童遥控

  1. 合并的历史

混帐合并--allow无关,历史儿童遥控/主

如果您现在检查git的日志在父回购,它应该有孩子回购的提交合并。 您还可以看到从提交源指示标记。

下面的文章帮我在嵌入一个回购到另一个回购,通过合并这两个混帐历史有一个单一的git的历史。

http://ericlathrop.com/2014/01/combining-git-repositories/

希望这可以帮助。 编码快乐!



文章来源: Merge two Git repositories without breaking file history