如何推送"git replace --graft" [英] How to push a "git replace --graft"

查看:109
本文介绍了如何推送"git replace --graft"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 git replace --graft <merged-version> <predecessor-version> <version-merged-from>

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

现在,我想通过将更改"推送"到我们的共享存储库(在Github上,这种情况发生),使更改可供我团队的其他成员使用.我怎么做?一个简单的git push似乎无效.

解决方案

refs/replace/层次结构中存在嫁接. (或者,也许最好说归功于"此类引用.)要将它们从一个存储库转移到另一个存储库,则必须推送或获取此类引用.

例如:

git push origin refs/replace/5c714d7798d1dc9c18d194fa6448680515c0ccdb

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

要推送所有替换项:

git push origin 'refs/replace/*:refs/replace/*'

(有时需要使用引号来防止外壳混淆星号;确切地说,何时使用哪种引号以及哪种 引号取决于外壳,尽管单引号和双引号都可以使用所有Unix-y shell).

获取替换物品的注意事项

如果某些远程 R 具有替换项,并且您希望将所有替换项都放入存储库中,请使用git fetch R 'refs/replace/*:refs/replace/*'(如果希望替换项带有前缀+,请使用相同的前缀覆盖您已经拥有的任何内容).您可以针对任何给定的存储库和远程库自动执行此操作.例如,如果您运行git config --edit,您会发现现有的origin遥控器具有以下几种设置:

[remote "origin"]
    url = ...
    fetch = +refs/heads/*:refs/remotes/origin/*

只需添加以下行:

    fetch = refs/replace/*:refs/replace/*

或:

    fetch = +refs/replace/*:refs/replace/*

使您的Git带来他们的Git的refs/replace/*. (注意:这里不需要引号,因为shell不会处理此行.)前导加号的含义与通常的含义相同: 1 如果没有已经有一些参考,您保留您的内容,而忽略他们的内容.使用前导加号,您丢弃您的,而改用他们的.与标签一样,如果您的参考文献和他们的参考文献已经匹配,则保留还是保留它们或用它们替换它们都没有关系.仅当您对某些引用应命名的对象有不同的想法时,这才重要.


1 实际上,前导加号的通常含义"取决于引用是应该移动(例如分支名称)还是 not 应该会移动,例如标签名称.加号设置强制标记,即始终采用建议的新设置",但是对于分支名称(预计将向前移动"),如果且仅当,则允许不加强制地进行更新这是前进"(或快进")动作. Git最初也将此规则应用于标签等其他引用,但Git员工在Git 1.8.2中对其进行了修复.对我来说,尚不清楚Git对refs/replace/引用适用哪些规则,这些规则不应该移动,但是不能像标签那样被特别对待.

I've used git replace --graft to record that a version was actually a (manually performed) merge between two versions:

 git replace --graft <merged-version> <predecessor-version> <version-merged-from>

That made a change to my (local, private) repository.

I now want to make that change available to other members of my team, by "pushing" it to our shared repository (on Github, it so happens). How do I do that? A simple git push seems to have no effect.

解决方案

Grafts exist inside the refs/replace/ hierarchy. (Or, it might be better to say, "owe their existence to" such references.) To transfer them from one repository to another, then, you must push or fetch such references.

For instance:

git push origin refs/replace/5c714d7798d1dc9c18d194fa6448680515c0ccdb

when commit 5c714d7798d1dc9c18d194fa6448680515c0ccdb has a replacement (in my case the replacement was new commit object ceba978ce6dad3b52d12134f4ef2720c5f3a9002, i.e., Git normally doesn't "see" 5c714d7, looking to replacement object ceba978 instead).

To push all replacements:

git push origin 'refs/replace/*:refs/replace/*'

(the quotes are sometimes needed to keep the shell from mangling the asterisks; exactly when, and which kind of quotes to use, is somewhat shell-dependent, though both single and double quotes work on all Unix-y shells).

Notes on fetching replacements

If some remote R has replacements, and you want to bring all of theirs in to your repository, use git fetch R 'refs/replace/*:refs/replace/*' (or the same with a prefix + if you want their replacements to override any you have already). You can automate this for any given repository and remote. For instance, if you run git config --edit, you will find that your existing origin remote has several settings that look like this:

[remote "origin"]
    url = ...
    fetch = +refs/heads/*:refs/remotes/origin/*

Simply add the line:

    fetch = refs/replace/*:refs/replace/*

or:

    fetch = +refs/replace/*:refs/replace/*

to make your Git bring over their Git's refs/replace/*. (Note: no quotes are needed here as the shell is not going to process this line.) The leading plus sign has the same meaning as usual:1 without it, if you already have some reference, you keep yours and ignore theirs. With the leading plus sign, you discard yours and use theirs instead. As with tags, if your reference and their reference already match, it does not matter whether you keep yours or replace yours with theirs; this only matters when you have different ideas about what object some reference should name.


1In fact, the "usual meaning" for leading plus sign depends on whether the reference is supposed to move, such a branch names, or not supposed to move, such as a tag name. The plus mark sets the force flag, i.e., "always take the proposed new setting", but for branch names—which are expected to "move forward"—an update is allowed without force if and only if it is a "forward" (or "fast forward") move. Git originally applied this rule to other references like tags as well, but the Git folks fixed it in Git 1.8.2. It's not clear to me which rules Git applies to refs/replace/ references, which are not supposed to move, but are not treated extra-specially the way tags are.

这篇关于如何推送"git replace --graft"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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