如何连接两个git历史? [英] How to concatenate two git histories?
问题描述
我有两个切线相关的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.
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 agit reset --hard HEAD
to actually check the files out after youfast-import
.
这篇关于如何连接两个git历史?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!