如何连接两个git历史? [英] How to concatenate two git histories?

查看:105
本文介绍了如何连接两个git历史?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个切线相关的git存储库。也就是说,一个人的内容是另一个的前身。我想以某种方式将存管处A的完整历史记录存储到存储处B,以便小费A将是存储处B的第一个变更集的父项。两者的历史都非常线性。



这可能吗?

解决方案

文件( .git / info / grafts ),您可以覆盖提交的父级(例如 projectB 为父母提供最新的 projectA



另请参阅通过 :




  $ git fast-export --all> ../export 

$ mkdir ../nuevo-complete

$ cd ../nuevo-complete

$ git init

$ git fast-import< ../export
git-fast-import statistics:[...]

(在一行中,如:


fast-import 似乎只是导入了git信息,但并没有检查任何东西。本来
git init 原本把你放在master上,所以你需要一个 git reset --hard HEAD 来实际检查出 fast-import code>



I have two git repositories that are tangentially related. Namely, content of one was a predecessor of the other. I would like to somehow prepend the full history of depository A to the depository B, so that tip of A would be a parent of the very first changeset of repository B? Histories in both are pretty linear.

Is this possible?

解决方案

You could try using the graft file (.git/info/grafts) where you could overwrite the parenthood of a commit (like the first of projectB having for parent the latest of projectA)

See also "What are .git/info/grafts for?" and "How to prepend the past to a git repository?" for more on this manipulation.


skalee comments about the article "Git: Grafting repositories" (from SO user Ben Straub) for a concrete example.

Now what we want to do is change the first commit in the "nuevo" repo ("New commit #1") so that its parent is the last commit in the "old" repo ("Old #3"). Time for some voodoo:

git fetch ../old master:ancient_history

Git lets you fetch from any other git repository, whether this repo is related to it or not! Brilliant! This leaves us with this:

Note how we renamed the old master branch to ancient_history. If we hadn’t, git would have tried to merge the two, and probably given up in disgust.

Now we still have a problem.
The two trees aren’t connected, and in fact a git pull won’t even get the ancient_history branch at all. We need a way to make a connection between the two.

Git has a facility called a graft, which basically fakes up a parent link between two commits.
To make one, just insert a line into the .git/info/grafts file in this format:

[ref] [parent]

Both of these need to be the full hash of the commits in question. So let’s find them:

$ git rev-list master | tail -n 1
d7737bffdad86dc05bbade271a9c16f8f912d3c6

$ git rev-parse ancient_history
463d0401a3f34bd381c456c6166e514564289ab2

$ echo d7737bffdad86dc05bbade271a9c16f8f912d3c6 \
       463d0401a3f34bd381c456c6166e514564289ab2 \
       > .git/info/grafts

(in one line, as suggested by ssokolow)

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

There. Now our history looks like this:

Cloning this repo results in this:

Woops. It turns out that grafts only take effect for the local repository. We can fix this with judicious application of git fast-import:

$ git fast-export --all > ../export

$ mkdir ../nuevo-complete

$ cd ../nuevo-complete

$ git init

$ git fast-import < ../export
git-fast-import statistics: [...]

(in one line, as suggested by ssokolow)

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

This effectively converts our "fake" history link into a real one.
All the engineers will have to re-clone from this new repository, since the hashes will all be different, but that’s a small price to pay for no downtime and a complete history.

As Qix comments below:

fast-import appears to just import the git information, but doesn't check anything out.
git init originally puts you on master, so you need a git reset --hard HEAD to actually check the files out after you fast-import.

这篇关于如何连接两个git历史?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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