合并两个 Git 存储库并保留历史记录 [英] Merge two Git repos and keep the history

查看:29
本文介绍了合并两个 Git 存储库并保留历史记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想扩展我遇到的另一个问题:

这是rebase后的结果.顶级 repo 的时间是 rebase-time.原来的日期丢失了!

  • 我是这样做的:

    # 假设当前目录是我们想要创建新仓库的地方# 创建新的存储库混帐初始化# 在我们进行合并之前,我们必须有一个初始提交,所以我们将进行一个虚拟提交目录 >读.mdgit 添加.git commit -m "初始提交"# 添加远程并获取旧的 RepoAgit remote add -f RepoA https://github.com/DimitriDewaele/RepoA# 对 RepoB 做同样的事情git remote add -f RepoB https://github.com/DimitriDewaele/RepoB# 在 repoB 之上重新建立工作分支(master)git rebase RepoB/master# 在顶部 op repoA 上重新建立工作分支(带有 RepoB 的 master)git rebase RepoA/master

    有可能有这样的东西吗?(绘制的解决方案!!!)

    我想保留原始时间+合并历史.

    更新 - 答案

    最适合我的答案是使用嫁接点.但是其他答案在其他用例中也非常有用.我把我的结果加到了github上,大家可以评价一下.

    答案 1:对我来说最好的工作移植"确实为我揭示了正确的工作答案.

    答案 2LeGEC"中的替换"选项也为某些用例提供了良好的结果.一个异常为我留下:

    答案 3:值得添加 来自VonC"的答案.在我的情况下,我无法获得--preserve-merges working"选项.这可能适用于其他场景,但我没有测试这个 furtner.

    解决方案

    正如您所发现的,rebase 不是您想用来将历史拼接在一起的命令(因为它实际上重写了历史).早期的 Git 有一个特性(hack)是专门为你想要做的事情设计的:graft points.更好的是,从 1.6.5 开始,您可以使用 git replace--graft 代替:

    git checkout mastergit replace --graft $(git log RepoB/master --format=%H | tail -1) HEADgit replace --graft $(git log RepoA/master --format=%H | tail -1) RepoB/mastergit reset --hard RepoA/master

    (git log RepoA/master --format=%H | tail -1RepoA 返回初始提交)

    从技术上讲,如果您在 master 中实际上还没有任何有价值的东西,您可以跳过第一个 replace,只生成 RepoB + RepoA 的历史.

    这些命令在 refs/replace/* 中创建条目,可以推送和拉取这些条目以与他人共享您的修订历史记录.或者,如果您不关心保留 RepoA/RepoB 的 SHA,您可以通过运行 git filter-branch --all 来使替换 永久 生成一个"real" 所需世系的提交集.

    I want to extend on another question I had: Merge two Git repositories and keep the master history

    I have succeeded in merging 2 different repo's into one repo. I needed a rebase to do this successfully. The master is correct, but I also want to keep the merge history. Is this possible?

    I have 2 repositories:

    This is the result after rebasing. The times of the top repo are the rebase-time. The original date is lost!

    This is how I did it:

    # 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
    dir > Read.md
    git add .
    git commit -m "initial commit"
    
    # Add a remote for and fetch the old RepoA
    git remote add -f RepoA https://github.com/DimitriDewaele/RepoA
    
    # Do the same thing for RepoB
    git remote add -f RepoB https://github.com/DimitriDewaele/RepoB
    
    # Rebase the working branch (master) on top of repoB
    git rebase RepoB/master
    
    # Rebase the working branch (master with RepoB) on top op repoA
    git rebase RepoA/master
    

    Is it possible to have something like this? (painted solution!!!)

    I would like to keep the original time + the merge history.

    UPDATE - ANSWER

    The answer that worked best for me, was working with graft points. But other answers are also very usable in other use cases. I have added my results on github, so everybody can evaluate.

    Answer 1: Best working in my case The 'graft' did reveal the correct working answer for me.

    GitHub: RepoGraft

    Answer 2 the "replace" option from "LeGEC" also gives good results for some use cases. One anomaly stayed for me:

    GitHub: RepoHistory

    Answer 3: Worth adding The answer from 'VonC'. I could not get the option '--preserve-merges working' in my case. This might work in other scenario's, but I did not test this furtner.

    解决方案

    As you've discovered, rebase isn't the command you want to use to stitch histories together (because it actually rewrites history). Early Git had a feature (hack) designed specifically for what you're trying to do: graft points. Even better, since 1.6.5 you can use git replace --graft instead:

    git checkout master
    git replace --graft $(git log RepoB/master --format=%H | tail -1) HEAD
    git replace --graft $(git log RepoA/master --format=%H | tail -1) RepoB/master
    git reset --hard RepoA/master
    

    (git log RepoA/master --format=%H | tail -1 returns the initial commit from RepoA)

    Technically you could skip the first replace if you don't actually have anything of value yet in master, yielding just history with RepoB + RepoA.

    These commands create entries in refs/replace/* that can be pushed and pulled to share your revised history with others. Or, if you don't care about preserving the SHAs of RepoA/RepoB, you can make the replacements permanent by running git filter-branch --all to produce a "real" set of commits of the desired lineage.

    这篇关于合并两个 Git 存储库并保留历史记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆