代码之家  ›  专栏  ›  技术社区  ›  SilentGhost

如何连接两个git历史?

  •  12
  • SilentGhost  · 技术社区  · 14 年前

    我有两个完全相关的Git存储库。也就是说,一方的内容是另一方的前身。我想以某种方式将存管A的完整历史提前交给存管B,这样,A的提示将是存储库B的第一个变更集的父级?两者的历史都是线性的。

    这有可能吗?

    1 回复  |  直到 7 年前
        1
  •  10
  •   Community Egal    7 年前

    您可以尝试使用嫁接文件( .git/info/grafts ),其中可以覆盖提交的父级(如 projectb having for parent the latest of projecta )。

    另请参见“ What are.git/info/grafts for?“and” how to prepend the past to a git repository?”“了解更多有关此操作的信息。


    skalee comments about the article” git:marchriving repositories “(from so user ben straub )for a concrete example.

    < Buff行情>

    现在,我们要做的是更改__ nuevo中的第一个提交 _157; repo(_ new commit 1 _),使其父级是__old__repo(__old 3_)中的最后一个提交。伏都教时间:

    < /块引用>
    git fetch../old master:古代历史
    < /代码> 
    
    < Buff行情>
    

    Git允许您从任何其他Git存储库中提取,无论此回购是否与之相关!精彩!这给我们留下了:

    < /块引用>

    < Buff行情>

    请注意我们如何将旧的主分支更名为古史。如果我们没有t,Git会尝试合并这两个,可能会厌恶地放弃。

    现在我们仍然有问题。
    这两棵树是不相连的,事实上,一个git-pull根本就无法得到古代的历史分支。我们需要一种在两者之间建立联系的方法。

    Git有一个称为嫁接的设施,它基本上是在两个提交之间伪造父链接。
    要制作一个,只需在.git/info/grafts中插入一行file in this format:。

    < /块引用>
    [ref][parent]
    < /代码> 
    
    < Buff行情>
    

    这两个都需要成为所讨论的提交的完整散列值。所以让我们找到它们:

    < /块引用>
    $git rev list master tail-n 1
    D7737BFFDAD86DC05BBADE271A9C16F8F912D3C6
    
    $git rev解析古代历史
    463D0401A3F34BD381C456C6166E514564289ab2
    
    $echo D7737BFFDAD86DC05BBADE271A9C16F8F912D3C6\
    463D0401A3F34BD381C456C6166E514564289ab2\
    >.git/info/嫁接
    < /代码> 
    
    

    (在一行中,as建议的byssokolow)

    echo$(git rev list master tail-n 1)$(git rev parse antiginal_history)>.git/info/grafts
    < /代码> 
    
    在那里。现在我们的历史是这样的:

    < Buff行情>

    克隆此repo会导致:

    < /块引用>

    < Buff行情> 哎哟!结果表明,嫁接仅对本地存储库有效。我们可以使用明智的应用程序修复此问题

    < /块引用>
    $git fast export--all>../export
    
    $mkdir../nuevo完成
    
    $cd../nuevo完成
    
    $it init
    
    $git快速导入<../export
    Git快速导入统计信息:[…]
    < /代码> 
    
    

    (在一行中,as建议的byssokolow)

    git filter branch$(git rev parse antiginate_history)..head
    < /代码> 
    
    < Buff行情>
    

    这有效地将我们的“假”历史链接转换为真实链接。
    所有工程师都必须从这个新的存储库中重新克隆,因为散列值都是不同的,但这对于不停机和完整的历史记录来说是一个很小的代价。

    < /块引用>

    作为qixcomments以下::

    < Buff行情>

    fast import似乎只导入git信息,但不签出任何内容。
    git init最初将您放在master上,因此您需要一个git reset--hard head以在您fast import之后实际检查文件。

    < /块引用> 可以覆盖承诺的父级(如projectB最新的projectA)

    也见“What are .git/info/grafts for?“和”How to prepend the past to a git repository?“更多关于这种操纵的信息。


    skaleecomments关于文章”Git: Grafting repositories“(来自SO用户)Ben Straub)举个具体的例子。

    现在我们要做的是更改__中的第一个提交nuevo_157;回购(__New commit #1_157;),使其父级是__old_157;repo(_156;old_3_157;)中的最后一个提交。伏都教时间:

    git fetch ../old master:ancient_history
    

    Git允许您从任何其他Git存储库中提取,无论此回购是否与之相关!精彩!这给我们留下了:

    enter image description here

    请注意我们如何将旧的主分支更名为古史。如果我们没有t,Git会试图合并这两个公司,可能会因为厌恶而放弃。

    现在我们仍然有问题。
    这两棵树是不相连的,事实上,一个git-pull根本就无法得到古代的历史分支。我们需要一种方法把两者联系起来。

    Git有一个称为贪污的设施,它基本上是伪造两个提交之间的父链接。
    要制作一个,只需在.git/info/移植物此格式的文件:

    [ref] [parent]
    

    这两个都需要成为所讨论的提交的完整散列值。所以让我们找到它们:

    $ git rev-list master | tail -n 1
    d7737bffdad86dc05bbade271a9c16f8f912d3c6
    
    $ git rev-parse ancient_history
    463d0401a3f34bd381c456c6166e514564289ab2
    
    $ echo d7737bffdad86dc05bbade271a9c16f8f912d3c6 \
           463d0401a3f34bd381c456c6166e514564289ab2 \
           > .git/info/grafts
    

    (一行,如suggested通过ssokolow)

    echo $(git rev-list master | tail -n 1) $(git rev-parse ancient_history) > .git/info/grafts 
    

    那里。现在我们的历史是这样的:

    enter image description here

    克隆此repo会导致:

    enter image description here

    胡扯。结果表明,嫁接仅对本地存储库有效。我们可以明智地运用git fast-import:

    $ git fast-export --all > ../export
    
    $ mkdir ../nuevo-complete
    
    $ cd ../nuevo-complete
    
    $ git init
    
    $ git fast-import < ../export
    git-fast-import statistics: [...]
    

    (一行,如suggested通过索科洛)

    git filter-branch $(git rev-parse ancient_history)..HEAD 
    

    这有效地将我们的“假”历史链接转换为真实的历史链接。
    所有的工程师都必须从这个新的存储库中重新克隆,因为散列将是不同的,但是这对于不需要停机和完整的历史来说是一个很小的代价。

    enter image description here

    ASQix评论below:

    fast-import似乎只是导入git信息,但不签出任何内容。
    git init原来你是大师,所以你需要一个git reset --hard HEAD在你离开后实际检查文件快速导入.