.git/info/grafts 有什么用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/161928/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 16:04:40  来源:igfitidea点击:

What are .git/info/grafts for?

gitversion-control

提问by Alexander Artemenko

I am trying to figure out what is the 'grafts' in the Git.

我试图弄清楚 Git 中的“移植”是什么。

For example, in one of the latest comments here, Tobu suppose to use git-filter-branchand .git/info/graftsto join two repositories.

例如,在此处的最新评论之一中,Tobu 假设使用git-filter-branch.git/info/grafts来加入两个存储库。

But I don't understand why I need these grafts? It seems, that all work without last two commands.

但我不明白为什么我需要这些移植物?似乎,没有最后两个命令,所有的工作。

回答by Oli

From Git Wiki:

来自Git 维基

Graft points or grafts enable two otherwise different lines of development to be joined together. It works by letting users record fake ancestry information for commits. This way you can make git pretend the set of parents a commit has is different from what was recorded when the commit was created.

Reasons for Using Grafts

Grafts can be useful when moving development to git, since it allows you to make cloning of the old history imported from another SCM optional. This keeps the initial clone for users who just wants to follow the latest version down while developers can have the full development history available.

When Linus started using git for maintaining his kernel tree there didn't exist any tools to convert the old kernel history. Later, when the old kernel history was imported into git from the bkcvs gateway, grafts was created as a method for making it possible to tie the two different repositories together.

移植点或移植物能够将两个不同的发育线连接在一起。它的工作原理是让用户记录提交的虚假祖先信息。通过这种方式,您可以让 git 假装提交的父项集与创建提交时记录的不同。

使用移植物的原因

在将开发转移到 git 时,Grafts 很有用,因为它允许您克隆从另一个 SCM 导入的旧历史是可选的。这为只想关注最新版本的用户保留了初始克隆,而开发人员可以获得完整的开发历史。

当 Linus 开始使用 git 来维护他的内核树时,不存在任何工具来转换旧的内核历史。后来,当旧的内核历史从 bkcvs 网关导入 git 时,创建了嫁接作为一种方法,可以将两个不同的存储库联系在一起。

回答by VonC

The grafts approach mentionedby Chris Johnsenfor joining two repositories is no longer fullyvalid (with grafts alone).
With Git 2.18 (Q2 2018), the functionality of "$GIT_DIR/info/grafts" has been superseded by the "refs/replace/" mechanism (for some time now).
The internal code had support for it in many places, which has been cleaned up in order to drop support of the "grafts" mechanism.

Chris Johnsen提到的用于加入两个存储库的移植方法不再完全有效(仅使用移植)。 在 Git 2.18(2018 年第二季度)中,“ ”的功能已被“ ”机制取代(一段时间以来)。 内部代码在很多地方都支持它,为了放弃对“嫁接”机制的支持,已经清理了它 。
$GIT_DIR/info/graftsrefs/replace/

See commit a3694d9, commit f42fa47, commit 8d0d81a, commit e2d65c1, commit f9f99b3, commit 0115e03, commit fb40429, commit 041c98e, commit e24e871(28 Apr 2018), and commit d398f2e, commit fef461e, commit c5aa6db(25 Apr 2018) by Johannes Schindelin (dscho).
(Merged by Junio C Hamano -- gitster--in commit 352cf6c, 23 May 2018)

提交a3694d9提交f42fa47提交8d0d81a提交e2d65c1提交f9f99b3提交0115e03提交fb40429提交041c98e提交e24e871(2018年4月28日),以及提交d398f2e提交fef461e提交c5aa6db由(2018年4月25日)约翰Schindelin ( dscho)
(由Junio C gitsterHamano合并-- --提交 352cf6c 中,2018 年 5 月 23 日)

So instead of

所以代替

echo "$commit-id $graft-id" >> .git/info/grafts

You now do:

你现在做:

git replace --graft $commit-id $graft-id
git filter-branch $graft-id..HEAD

Deprecate support for .git/info/grafts

The grafts feature was a convenient way to "stitch together" ancient history to the fresh start of linux.git.

Its implementation is, however, not up to Git's standards, as there are too many ways where it can lead to surprising and unwelcome behavior.

For example, when pushing from a repository with active grafts, it is possible to miss commits that have been "grafted out", resulting in a broken state on the other side.

Also, the grafts feature is limited to "rewriting" commits' list of parents, it cannot replace anything else.

The much younger feature implemented as git replaceset out to remedy those limitations and dangerous bugs.

Seeing as git replaceis pretty mature by now (since 4228e8b(replace: add --graftoption, 2014-07-19, Git 2.1.0) it can perform the graft file's duties), it is time to deprecate support for the graft file, and to retire it eventually.

弃用支持 .git/info/grafts

嫁接功能是将古代历史“缝合”到新起点的便捷方式linux.git

然而,它的实现并不符合 Git 的标准,因为它可以通过太多方式导致令人惊讶和不受欢迎的行为。

例如,当从具有活动移植的存储库推送时,可能会错过已“移植”的提交,从而导致另一侧的状态损坏。

此外,移植功能仅限于“重写”提交的父母列表,它不能替代任何其他内容。

git replace为解决这些限制和危险的错误而实施的更年轻的功能。

眼见为git replace是相当现在的成熟(因为4228e8b(更换:添加--graft选项,2014年7月19日,Git的2.1.0),它可以进行移植文件的职责),是时候为移植文件弃用的支持,以及退休它最终。

Now (again, Git 2.18, Q2 2018), you have:

现在(再次,Git 2.18,2018 年第二季度),你有:

replace: add --graftoption

The usage string for this option is:

git replace [-f] --graft <commit> [<parent>...]

First we create a new commit that is the same as <commit>except that its parents are [<parents>...]

Then we create a replace ref that replace with the commit we just created.

With this new option, it should be straightforward to convert grafts to replace refs.

replace: 添加--graft选项

此选项的用法字符串是:

git replace [-f] --graft <commit> [<parent>...]

首先我们创建一个新的提交,<commit>除了它的父母是[<parents>...]

然后我们创建一个替换引用来替换我们刚刚创建的提交。

使用这个新选项,将移植物转换为替换参考应该很简单。



And before Git 2.20 (Q4 2018), the recently introduced commit-graph auxiliary data is incompatible with mechanisms such as replace & grafts that "breaks" immutable nature of the object reference relationship.
Disable optimizations based on its use (and updating existing commit-graph) when these incompatible features are in use in the repository.

而在 Git 2.20(2018 年第四季度)之前,最近引入的提交图辅助数据与诸如替换和移植等机制不兼容,这些机制“打破”了对象引用关系的不可变性质。
当存储库中正在使用这些不兼容的功能时,根据其使用禁用优化(并更新现有的提交图)。

See commit 829a321, commit 5cef295, commit 20fd6d5, commit d653824, commit b775896, commit 950c62b(20 Aug 2018) by Derrick Stolee (derrickstolee).
See commit 212e0f7, commit 4a6067c(20 Aug 2018) by Stefan Beller (stefanbeller).
(Merged by Junio C Hamano -- gitster--in commit 6d8f8eb, 16 Oct 2018)

请参阅Derrick Stolee ( ) 的commit 829a321commit 5cef295commit 20fd6d5commit d653824commit b775896commit 950c62b(2018 年 8 月 20 日。 请参阅Stefan Beller ( ) 的commit 212e0f7commit 4a6067c(2018 年 8 月 20 日(由Junio C Hamano合并-- --提交 6d8f8eb,2018 年 10 月 16 日)derrickstolee
stefanbeller
gitster



With Git 2.24 (Q4 2019), the "upload-pack" (the counterpart of "git fetch"), which needs to disable commit-graph when responding to a shallow clone/fetch request, does not panic anymore.

在 Git 2.24(2019 年第四季度)中,在响应浅克隆/获取请求时需要禁用提交图的“ upload-pack”(“ ”的对应物git fetch)不再恐慌。

See commit 6abada1, commit fbab552(12 Sep 2019) by Jeff King (peff).
(Merged by Junio C Hamano -- gitster--in commit 098e8c6, 07 Oct 2019)

请参阅Jeff King ( ) 的commit 6abada1commit fbab552(2019 年 9 月 12 日(由Junio C Hamano合并-- --098e8c6 提交中,2019 年 10 月 7 日)peff
gitster

## upload-pack: disable commit graph more gently for shallow traversal

When the client has asked for certain shallow options like "deepen-since", we do a custom rev-list walk that pretends to be shallow.
Before doing so, we have to disable the commit-graph, since it is not compatible with the shallow view of the repository. That's handled by 829a321(commit-graph: close_commit_graph before shallow walk, 2018-08-20, Git v2.19.2).
That commit literally closes and frees our repo->objects->commit_graph struct.

That creates an interesting problem for commits that have alreadybeen parsed using the commit graph.
Their commit->object.parsedflag is set, their commit->graph_posis set, but their commit->maybe_treemay still be NULL.
When somebody later calls repo_get_commit_tree(), we see that we haven't loaded the tree oid yet and try to get it from the commit graph.
But since it has been freed, we segfault!

So the root of the issue is a data dependency between the commit's lazy-load of the tree oid and the fact that the commit graph can go away mid-process.

## upload-pack: 更温和地禁用提交图以进行浅层遍历

当客户要求某些浅层选项(例如“deepen-since”)时,我们会执行一个假装浅层的自定义 rev-list walk。
在这样做之前,我们必须禁用提交图,因为它与存储库的浅视图不兼容。这由829a321处理(commit-graph浅步前的 close_commit_graph,2018-08-20,Git v2.19.2)。
该提交实际上关闭并释放了我们的repo->objects->commit_graph struct.

对于已经使用提交图解析的提交,这会产生一个有趣的问题。
他们的commit->object.parsed标志已经设置,他们的commit->graph_pos已经设置,但他们commit->maybe_tree可能仍然是NULL
当有人稍后调用 时repo_get_commit_tree(),我们看到我们还没有加载树 oid 并尝试从提交图中获取它。
但是既然它被释放了,我们就出现了段错误!

因此,问题的根源在于提交对树 oid 的延迟加载与提交图可以在过程中消失的事实之间的数据依赖性。

回答by Martin Gross

When working with git-svn:

使用 git-svn 时:

git grafts are very useful to import a Git tree into a Subversion repository.

git 移植对于将 Git 树导入到 Subversion 存储库非常有用。

E.g. I created a local Git repository as a start. After working on it several days, creating lots of commits, I had to publish it into the central Subversion repository and I didn't want to lose the history.

例如,我首先创建了一个本地 Git 存储库。经过几天的工作,创建了大量提交,我不得不将它发布到中央 Subversion 存储库中,我不想丢失历史记录。

I found the following How-to article: http://eikke.com/importing-a-git-tree-into-a-subversion-repository/

我找到了以下操作方法文章:http: //eikke.com/importing-a-git-tree-into-a-subversion-repository/