我已经使用:
将github remote添加到我的git存储库中git remote add --mirror=push github repository_path.git
我正在尝试使用以下方式从远程获取:
git fetch github
其中,github
是我在上一步中添加的远程。
我尝试git fetch两个存储库,在第一次存储的情况下,它能够获取远程存在的更改。但是在第二次回购的情况下,git fetch无法获取远程中存在的更改。
两个存储库之间的区别在于,fetch工作的存储库是由我创建的,而fetch不工作的存储库是由其他用户创建的,但我有权在该存储库中执行pull和push
有人可以帮我解决这个问题吗?
答案 0 :(得分:1)
--mirror=push
击败了你你可能不想要那个选项。它根本不清楚 想要的选项(如果有的话)。
首先(虽然这里不那么重要),git fetch
提取提交,而不是更改。 提交和"更改"之间的(特定于Git)差异是一个提交是一个快照:一个工作树的完整副本(或者更准确地说,是在提交时在索引中的工作树的部分)。要将快照变为更改,您必须将(即git diff
)与其他快照进行比较。 (事实上,这也不太准确:git fetch
提取对象,其中包括提交,但也包括带注释的标签,树和blob。但一般来说,我们&#39 ;主要关注提交。)
这里最重要的部分是:{{1>}提取的提交(以及其他对象)由 refspecs 控制。 refspec,以其第二种最简单的形式看起来像这样:
git fetch
这些是名为master:origin/master
refs/heads/*:refs/remotes/foo/*
或origin
的远程的典型fetch refspec。你的名字为foo
,所以你可能想要,例如:
github
作为您的默认refspec。这告诉你的 Git,当其他 Git - 您通过互联网电话呼叫的外国Git时,在您之前指定的URL上提供{{1} },refs/heads/*:refs/remotes/github/*
和refs/heads/master
,您的 Git应该在其refs/heads/branch
和refs/notes/commits
分支上进行处理,并忽略{{1} } notes。
每个以冒号分隔的对的左侧是您希望Git匹配的名称。您无法控制他们的Git 提供的内容,但您可以完全控制采取的内容(即匹配)。
右侧是您希望Git在您的存储库中使用的名称。正如您在此处所看到的,您不必使用与其他Git使用的名称相同的名称。您可以使用相同的名称,如果这是您想要的名称,但您没有,并且通常您不想要到。通常,您希望将他们的分支名称(例如他们的master
和重命名)作为您的远程跟踪分支名称:branch
,例如。
我在上面提到过,这是第二种最简单的refspec形式。最简单的是没有冒号的那个,例如commits
。 如果您使用这种无冒号的refspec形式,master
不会为获取的对象提供存储库中的任何名称。这就是您所看到的。
(这再次不是100%准确:任何 origin/master
写入master
。但是,git fetch
是一个非常临时的名称。具体而言,下一个git fetch
覆盖它,因为任何 FETCH_HEAD
写入FETCH_HEAD
。所以它可能也是"没有名称":它&# 39;只有在下一次获取之前才有用。这就是原始git fetch
脚本所需要的全部内容,当git fetch
仅用于面向用户的FETCH_HEAD
脚本时, "遥控器"是首先发明的。但是,当我们希望我们的远程跟踪分支更新时,它现在并不好。)
git pull
需要一些默认的refspecs 如果您运行git fetch
,则使用 no refspec参数运行它。在这种情况下,pull
会在Git配置中查找默认 refspecs。通常情况下,git fetch
会为您设置这些内容:
git fetch remote
使用两个配置项创建git fetch
:
git remote add
(我们应该始终使用$ git remote add foo ssh://host.dom.ain/path/to/repo.git
,以防有多条已配置的remote "foo"
行,但事实上$ git config --get remote.foo.url
ssh://host.dom.ain/path/to/repo.git
$ git config --get-all remote.foo.fetch
refs/heads/*:refs/remotes/foo/*
只会设置一行。)
您使用了--get-all
,更改了 fetch
为新远程设置的内容。它不会将git remote add
设置为git remote add --mirror=push
,而是将git remote add
设置为remote.foo.fetch
:
refs/heads/*:refs/remotes/foo/*
特别是,没有remote.foo.mirror
个条目。
(这个true
让我们检查$ git config --get-regexp '^remote\.foo\.'
remote.foo.url ssh://host.dom.ain/path/to/repo.git
remote.foo.mirror true
部分下的所有内容。它是remote.foo.fetch
的替代,接受任意正则表达式,我们给它一个匹配{{1}使用左锚--get-regexp
并引用两个点字符以确保它们匹配文字点而不是任何单个字符。请注意,正则表达式与shell样式globs不同,并且功能更强大:{{ 1}} refspecs是shell样式的globs,而不是正则表达式。这些都不是你需要知道的东西,它只是有用的辅助信息。)
[remote "foo"]
就会陷入困境没有命令行refspec:
--get-all
或默认remote.foo.
,^
依赖于弱且脆弱的内置默认值。它询问其他 Git:"你最重要的分支是什么?具体来说,你的fetch
承诺是什么?"然后它会根据需要提取该提交(及其历史记录),并在您的存储库中调用git fetch
:
git fetch github 'refs/heads/*:refs/remotes/github/*'
现在,您现在有时间到下一个remote.github.fetch
使用git fetch
执行某些操作。
HEAD
的原因,然后提出你真正想要的选项将FETCH_HEAD
设置为From <url>
* branch HEAD -> FETCH_HEAD
与在命令行上指定git fetch
具有相同的效果:它强制将所有本地引用推送到在遥控器上使用相同的名称,就好像您使用了FETCH_HEAD
。 1 但是如果远程是与本地存储库相比的推送镜像,您可能根本不想从中获取它。 (换句话说,这个组合 - 推镜,但是可以使用 - 没有任何意义。)
1 请注意,push refspecs与fetch refspecs有所不同。两者都使用相同的语法:可选的强制标志,源引用名称或单星号glob模式,冒号和目标引用名称或类似的glob模式。但是,源和目标是相反的:对于获取,源是远程存储库/其他Git,而对于推送,源是本地存储库/我们的Git。丢失目标的含义也不同:对于提取,缺少目标意味着仅使用--mirror=push
,但对于推送,缺少目标意味着使用相同名称,例如,remote.remote.mirror
表示将(我们的)主人推送到(他们的)主人。最后,fetch不允许空源,但是push会执行:这意味着要求远程Git完全删除引用。