Nan*_*ana 5 git github git-branch
我有两个遥控器和两个本地分支机构:
这是在我的 .git/config 文件中:
...
[remote "origin"]
url = http://my.gitlab.com/nandoquintana/repo.git
fetch = +refs/heads/*:refs/remotes/origin/*
[remote "github"]
url = https://github.com/nandoquintana/repo.git
fetch = +refs/heads/*:refs/remotes/github/*
[branch "master"]
remote = origin
merge = refs/heads/master
[branch "mirror"]
remote = github
merge = refs/heads/master
[push]
default = tracking
Run Code Online (Sandbox Code Playgroud)
这是“git Remote show origin”的输出:
$ git remote show origin
* remote origin
Fetch URL: http://my.gitlab.com/nandoquintana/repo.git
Push URL: http://my.gitlab.com/nandoquintana/repo.git
HEAD branch: master
Remote branch:
master tracked
Local branch configured for 'git pull':
master merges with remote master
Local ref configured for 'git push':
master pushes to master (up to date)
$ git remote show github
* remote github
Fetch URL: https://github.com/nandoquintana/repo.git
Push URL: https://github.com/nandoquintana/repo.git
HEAD branch: master
Remote branch:
master tracked
Local branch configured for 'git pull':
mirror merges with remote master
Local ref configured for 'git push':
master pushes to master (local out of date)
Run Code Online (Sandbox Code Playgroud)
“推”和“拉”命令都可以正常工作:
那么,为什么“为‘git Push’配置的本地引用”是“主站推送到主站”?为什么不“镜子推主”?“本地过时”是什么意思?
@torek 回答后更新:
这里我们有一些参考:
$ git ls-remote github
455063a9db09977535ac808af5729181b153f4c7 HEAD
455063a9db09977535ac808af5729181b153f4c7 refs/heads/master
$ cat .git/refs/heads/master
ca9e4399058a4998bd7c993f86d6740cfaec820b
$ cat .git/refs/heads/mirror
455063a9db09977535ac808af5729181b153f4c7
$ cat .git/refs/remotes/github/master
455063a9db09977535ac808af5729181b153f4c7
Run Code Online (Sandbox Code Playgroud)
确切地说,“refs/remotes/github/master”和“refs/heads/master”不相等。这就是为什么出现“本地已过期”消息的原因:
master pushes to master (local out of date)
Run Code Online (Sandbox Code Playgroud)
这对我来说不是问题,我确信“remotes/github/master”中的代码和本地“master”中的代码是不同的。
尽管如此,“remotes/github/master”和本地“mirror”中的代码是相同的。事实上,refs“refs/remotes/github/master”和“refs/heads/mirror”是相等的。
这是让我安心的消息:
mirror pushes to master (up to date)
Run Code Online (Sandbox Code Playgroud)
我如何配置remote/github...或push.default...来获得此输出?
[给我自己和 OP 的一些提醒:远程origin= GitLab,远程github= GitHub。从根本上来说,使用的主要问题git remote show是它做出假设。这些假设是关于您将来如何运行其他 Git 命令\xe2\x80\x94git fetch和git push\xe2\x80\x94,以及将来如何布局每个 Git 命令涉及的第二个 Git 存储库。显然,按照一句古老的丹麦谚语:很难做出预测,尤其是对未来的预测。]
让我在这里解决顶部编辑过的问题:
\n\n\n\n\n这是让我安心的消息:
\n\nRun Code Online (Sandbox Code Playgroud)\n\nmirror pushes to master (up to date)\n我如何配置remote/github...或push.default...来获得此输出?
\n
有一件事情值得一试:一个push.default设置upstream告诉 Git 默认情况下git push应该执行此操作。如果它有效并且达到了您想要的效果,那么您就一切就绪了。但请注意,无论 Git 在这里说什么,它都是谎言。
根本问题是mirror 不推动master. 在您输入git push命令之前,它根本不会推送任何内容;一旦您输入该命令,您就可以控制该命令的执行位置,这可以完全覆盖任何声明git pushgit remote show。
您git push当时的选择是:
不提供额外的参数。
\n\n在这种情况下,您的 Git从当前上游选择远程。如果上游设置为origin/...远程则为origin。如果上游设置为github/...远程则为github。它看起来像一个简单的字符串替换(通常确实如此,尽管由于历史原因,它实际上是一个非常复杂的字符串替换,通常结果很简单:取斜杠之前的部分)。
此时,您的 Git 将继续处理此处列出的第二种情况。
提供一个附加参数。该参数指定要连接的其他 Git。它通常是一个远程(origin或github),但此时您可以提供一个 URL,例如。
提供两个或多个附加参数。其中第一个名称为远程(或者是 URL)。其余的是refspecs,定义如下。
此时,您的 Git 连接到该远程服务器,并且实际上运行git ls-remote以查看它们有哪些分支。此列表很重要,因为它与您提供的或未能提供的 refspec 一起使用,具体取决于您的push.default设置,并且事实上,当您提供 refspec 时,您只能提供一半的refspec。
“半个参考规范”的情况尤其有问题。无论你做什么或设置什么,如果你git push github mirror在打开时实际运行mirror,你的 Git 都会要求远程的 Gitgithub进行设置……好吧,这取决于你是否有上游设置,如果没有,您的push.default设置。详细信息位于文档git push中,采用 Git 通常的神秘形式。不过,默认值是“half refspec”,该名称的mirror意思是mirror:mirror.
如果您提供完整的 refspec,例如git push github mirror:asdf, refspec 的后半部分将确定您的 Git 要求其 Git 设置哪个分支名称。如果您给出一半的参考规范,则您给出的一半通常会成为两个名称。使用默认值push.default = simple,您不能意外地将您的推mirror到其他任何人的master,您必须使用显式的完整引用规范(然后由您决定是否正确)。
如果你没有给出refspec,你的 Git 就会依赖push.default,并且只有 5 个设置。默认的simple,让 Git 将您的分支集与他们的分支集(来自git ls-remote)进行比较。如果您的分支(例如mirror)没有任何相应的分支,您的 Git 不会要求其 Git 设置任何分支分支。
假设您位于分支mirror,其上游设置为github/master,并且您已配置push.default为upstream(使用git config push.default upstream):
如果您git push在不带参数或git push github不带其他参数的情况下运行,则遥控器将为github.
如果您不提供 refspec,则push.default应用该设置:Git 将构建的 refspec 将是mirror:master。
但是,如果您提供一半的 refspec,即使在多次重新阅读文档之后,我也不确定 Git 将构建什么完整的refspec。我认为这将是mirror:mirror,这不是你想要的。
您还可以配置remote.github.push提供默认参考规范的变量。这也可能让你得到你想要的东西,尽管push.default = upstream看起来更简单。
我们现在回到原来的答案。:-)
\n\n\n\n\n那么,为什么“为‘git push’配置的本地引用”是“主站推送到主站”?
\n
这意味着:
\n\nmaster(即您已经运行git checkout master)git push github(不是 git push github more-command-words)master送到https://github.com/nandoquintana/repo.git\'smaster这可能会成功,也可能不会成功,具体取决于 GitHub 上的 Git 服务器如何处理礼貌请求来设置其 masterGit 通过此推送请求发送的任何哈希 ID。
master(如果您再次运行并没有任何其他参数,情况也是如此git push origin,除了名称origin指的是 GitLab 上的 Git 之外,情况也是如此。)
另一方面,假设您当前的分支名为mirror:
git checkout mirrorgit push github出现这种情况的原因很可能是您已push.default配置或默认为simple. 当push.default设置为 时simple,git push不带refspec参数的分支会尝试推送当前分支,但前提是其他 Git 具有同名分支。github因此,如果位于(即 at )的 Githttps://github.com/...仍然没有名为的分支mirror,您的 Git 将会对自己说:嗯。没有命名的分支mirror。最好不要推动任何东西。
(如果明天 GitHub 上的另一个 Git确实有一个名为 的分支mirror,那么你的 Git 就会对自己说:啊哈!有一个名为 的分支mirror!好的,我会要求另一个 Git 更新它的mirror。)
\n\n\n为什么不“镜子推主”?
\n
因为它没有。即使您重新配置您的push.default,也没有默认设置意味着“如果我无法提供git push参考规范,请创建一个不匹配的参考规范”。
所有这一切都取决于refspec的概念。在 Git 中, refspec 本质上是一对引用。
\n\n引用是“分支或标签名称”的花哨词。(它可以不仅仅是这两个,但它们是主要的两个。)像这样的分支名称master是其完整拼写的简写refs/heads/master。这个引用名称refs/heads/master,是 Git 表达“不仅仅是master分支” master的方式。像这样的短标签名称v1.2是参考名称的简写refs/tags/v1.2。如果您省略了refs/heads/或refs/tags/部分,Git 通常会通过查看您现在拥有的分支和标签来确定您指的是哪一个。
不管怎样,refspec大多只是其中的两个:,中间有一个冒号:
refs/heads/master:refs/heads/master\nRun Code Online (Sandbox Code Playgroud)\n\n例如。您需要其中两个,因为您正在使用两个 Git:一个在您的系统上,您要求它做某事,另一个在某个远程上,例如gitlab或github。您让您的 Git 通过网络电话呼叫另一个 Git。然后你的 Git 和他们的 Git 互相对话,之后你的 Git 将获取或推送东西。
获取和推送步骤需要每个 Git 的一个引用,因此这意味着您需要两个引用:一个 refspec。
\n\nrefspec 的两部分是源和目标。如果您正在运行git fetch,则源是另一个Git,目标是您自己的 Git。如果你在奔跑git push,你就是源头;另一个 Git 成为目的地。但无论哪种情况,源都会向目标提供一些提交,然后源的名称\xe2\x80\x94 refspec\xe2\x80\x94 的左半部分用于更改目标名称中的某些内容\xe2\x80\x94 参考规范的右半部分。
对于git fetch,两边有不同的名称是完全正常的。我们从他们的中获取refs/heads/master并写入我们自己的refs/remotes/origin/master。我们从他们的中获取refs/heads/master并写入我们自己的refs/remotes/mirror/master。这让我们可以从许多不同的地方获取数据,但又保持它们完整。
不过,对于来说,两边使用相同的git push名称更为正常。我们从他们的那里获取,进入我们的。然后我们工作一段时间,确保我们的内容是在他们的基础上进行的更新,例如通过合并或变基。然后我们再次打电话给他们,交付我们的新提交,并要求他们将\xe2\x80\x94不是他们的,他们甚至没有,而是他们的\xe2\x80\x94 到这个基于他们的最新提交以前的提交。masterrefs/remotes/.../master mastermastermasternando/mastermaster
我们确保它建立在他们的基础上,先获取,然后工作,然后推送。如果我们输掉了与 Sofia\xe2\x80\x94 的“比赛”,我们都会在同一时间获取数据,但她工作得更快,然后她在我们之前推动\xe2\x80\x94,我们得到“远程拒绝”“不快进”错误; 我们必须再次获取,从 GitHub 或其他地方获取 Sofia 的工作,并使我们的工作构建在她的工作之上,然后再次尝试推送。
\n\n\n\n\n“本地过时”是什么意思?
\n
当你通过网络电话git remote show特别调用远程\xe2\x80\x94 github,即\xe2\x80\x94时,另一个Git说:https://github.com/nandoquintana/repo.git
I have these references:\n refs/heads/master <some big ugly hash ID>\nRun Code Online (Sandbox Code Playgroud)\n\n(尝试运行git ls-remote github看看他们有什么,你会得到完整的列表)。
您自己的 Git 有一个名为 的分支,但是您的Git 为您的\xe2\x80\x94your分支\xe2\x80\x94提供的master又大又难看的哈希 ID是不同的。 refs/heads/mastermaster
由于两者不同,你的 Git 假设你要么“领先”\xe2\x80\x94,你有一些他们没有的提交\xe2\x80\x94,要么“落后”(他们有一些你没有的提交),或者也许两者兼而有之。如果你落后的话,你的 Git 无法告诉你落后了多远,但它可以通过查看你的所有提交来告诉你“领先”多远。如果您129bca4f...的提交的父级是e033fc12...,并且它们位于 commit e033fc12...,那么您仅领先一次提交。
master如果你的 Git 可以在你的分支历史记录中找到他们的 Git 提交哈希 ID ,那么你就“领先”了,你git push现在可能可以向他们发送你的新提交,要求他们将其设置master为129bca4f...,他们可能会进行提交并更新它们的master.
但是如果他们有提交930ab988...,而你根本没有提交,那么你的 Git 只知道他们有一些你没有的提交。你一定是“落后”的。您可以git fetch从他们那里获取他们拥有而您没有的所有提交,并使用refs/remotes/github/master. 然后,您可以尽一切努力将这些提交添加到您自己的 中master,这样您就可以与它们\xe2\x80\x94 保持一致,既不领先也不落后\xe2\x80\x94,并执行所需的任何其他工作,以便您现在领先于他们。
由您决定这是否是个好主意,如果是,是否要这样做。所要做的就是通过网络电话git remote show使用 给他们打电话,并将他们的参考资料与您的参考资料进行比较,根据这些结果猜测要做什么和会做什么。(如果您使用,则仅意味着运行,然后运行。该命令也会尝试猜测这会做什么。)git ls-remotegit fetchgit pushgit pullgit fetchgit mergegit remote show
| 归档时间: |
|
| 查看次数: |
3015 次 |
| 最近记录: |