如何推"git replace --graft"

Rae*_*ald 13 git git-push

我曾经git replace --graft记录过一个版本实际上是两个版本之间的(手动执行)合并:

 git replace --graft <merged-version> <predecessor-version> <version-merged-from>
Run Code Online (Sandbox Code Playgroud)

这改变了我的(本地,私有)存储库.

我现在想通过将其"推送"到我们的共享存储库(在Github上,这样就可以)将该更改提供给我的团队的其他成员.我怎么做?简单git push似乎没有效果.

tor*_*rek 12

移植物存在于refs/replace/层次结构内.(或者,可能更好的说法是"将它们存在于"这样的引用.)要将它们从一个存储库传输到另一个存储库,那么,您必须推送或获取此类引用.

例如:

git push origin refs/replace/5c714d7798d1dc9c18d194fa6448680515c0ccdb
Run Code Online (Sandbox Code Playgroud)

当commit 5c714d7798d1dc9c18d194fa6448680515c0ccdb有一个替换时(在我的情况下,替换是新的提交对象ceba978ce6dad3b52d12134f4ef2720c5f3a9002,即,Git通常不会"看到" 5c714d7,ceba978而是寻找替换对象).

推动所有替换:

git push origin 'refs/replace/*:refs/replace/*'
Run Code Online (Sandbox Code Playgroud)

(引号有时需要保持外壳从重整的星号;什么时候,哪些类型的引号使用的,有些壳依赖性,虽然单引号和双引号在所有的Unix-Y弹工作).

获取替换的注意事项

如果某些远程R有替换,并且您想将所有远程R都带入您的存储库,请使用(或者如果您希望他们的替换替换您已经拥有的任何替换,则使用相同的前缀).您可以为任何给定的存储库和远程自动执行此操作.例如,如果您运行,您会发现现有的遥控器有几个如下所示的设置:git fetch R 'refs/replace/*:refs/replace/*'+git config --editorigin

[remote "origin"]
    url = ...
    fetch = +refs/heads/*:refs/remotes/origin/*
Run Code Online (Sandbox Code Playgroud)

只需添加以下行:

    fetch = refs/replace/*:refs/replace/*
Run Code Online (Sandbox Code Playgroud)

要么:

    fetch = +refs/replace/*:refs/replace/*
Run Code Online (Sandbox Code Playgroud)

让你的Git带来他们的Git's refs/replace/*.(注意:此处不需要引号,因为shell不会处理此行.)前导加号与通常具有相同的含义:1没有它,如果您已经有一些引用,则保留您的并忽略它们.使用前导加号,您可以丢弃它并使用它们.与标签一样,如果您的参考文献和参考文献已经匹配,那么您是保留自己的名称还是将其替换为他们的名称并不重要; 这只有在您对某个引用应该命名的对象有不同的想法时才有意义.


1实际上,前导加号的"通常含义"取决于引用是否应该移动,这样的分支名称,或者应该移动,例如标记名称.加号标记设置强制标志,即"始终采用建议的新设置",但是对于分支名称 - 预期"向前移动" - 当且仅当它是"前进"时,允许更新而不用力(或"快进")移动.Git最初也将此规则应用于其他引用,例如标签,但Git人员在Git 1.8.2中修复了它.我不清楚Git适用于refs/replace/引用的哪些规则,这些规则不应该移动,但不会特别注意标记的方式.


Ich*_*hyo 6

为了完整起见: git 替换是“虚拟的”,而不是永久的。被操纵的提交的原始版本仍然存在\xe2\x80\x94,它只是被替换提交遮盖了。接受的答案描述了如何将这些“虚拟替换”也发布到共享存储库中,以及如何安排在获取时获取此类替换。通常这是正确的做法。

\n

然而,有时我们想让这样的历史修复永久化。对于 Git,做到这一点的唯一方法就是综合新的历史记录。git filter-branch这可以通过(脆弱、低级)或 Github 上非常好的工具git-filter-repo(Git 项目官方推荐)来完成。

\n

但请注意,无法强制共享存储库的其他用户使用重写的历史记录。您需要要求他们进行切换,例如通过重置其主分支或切换到另一个新分支。因此,在公共设置中,永久重写历史是不可行的;然而,对于封闭的用户组,例如在商业设置中,这是一个非常有效的选项(并且可能确实有必要删除一些敏感内容,例如凭证)

\n