Can pus:用于指定远程跟踪分支的git语法与gitpull push checkout等的语法

git pull 命令的语法是 git pull [remote] [branch](注意远程名称和分支名称之间的空格)。

git pull origin v0

但是,对于另一个命令,语法是 [remote] / [branch](这次是 '/',而不是分隔 [remote] 和 [branch] 的空格):

git branch --set-upstream v0 origin/v0

这让我感到困惑,因为“origin / v0”也是我本地机器上的“远程跟踪分支”的名称。例如列出远程跟踪分支的命令:

git branch -r
  origin/master
* origin/v0

然而,令我更加困惑的是,列出所有本地跟踪分支和远程跟踪分支的命令使用 [branch](对于本地分支)和 remotes / [remote] / [branch] 的语法进行远程跟踪分支。例如:

git branch -a 
  master
* v0
  remotes/origin/master
  remotes/origin/vo

我的主要问题是我正确理解这些看似模棱两可的语法约定?

第二个问题和评论是:为什么对引用远程跟踪分支的不同方式有歧义,例如源 / 主与远程 / 源 / 主的情况?

为什么不只是有 'git branch-a' 而不是 prepend 'remotes /'?例如:

 git branch -a 
      master
    * v0
     origin/master
    * origin/v0

对于像这样的功能:

git branch --set-upstream v0 origin/v0

制作它:

git branch --set-upstream v0 origin v0

以便知道命令参数引用名为“origin”的远程的分支“v0”,而不是“远程跟踪分支”。

甚至使用详细的命名参数语法:

git branch --set-upstream OfLocalBranch:v0 ToRemoteAndBranch::origin v0

或上述命名的 param 方法的一些变化。

0

首先,在git pull remote branch中,branch不对应于remote分支,而是对应于local分支。使用该命令将从远程remotebranch的远程跟踪分支中提取更改(尽管该行为取决于您的设置)。

至于远程跟踪分支,remotes/<remote>/<branch>是这些分支的真正的名称。因此,当列出所有分支时,它只是列出全名以避免歧义,并清楚地表明一个分支是一个远程分支。然而,当使用git branch -r时,你明确地请求远程分支,所以你知道你将看到的所有分支都是

当指定<refname>时,Git 将try the following refs until it finds one

如果$GIT_DIR/<refname>存在,那就是您的意思(这通常仅对HEADFETCH_HEADORIG_HEADMERGE_HEADCHERRY_PICK_HEAD有用);

否则,refs/<refname>,如果它存在;

否则,refs/tags/<refname>,如果它存在;

否则,refs/heads/<refname>,如果它存在;

否则,refs/remotes/<refname>,如果它存在;

否则,refs/remotes/<refname>/HEAD,如果它存在。

该列表已经显示了引用的实际全名:

refs/tags/<name>for tags

refs/heads/<name>表示分支

refs/remotes/<name>用于远程分支

因此,您所做的一切,例如仅指定master只是 Git 允许您执行的快捷方式,因此您不必将其指定为heads/master(您仍然可以)。对于远程设备,通常情况下,非远程分支不会使用origin/之类的前缀,因此指定origin/branch通常是您在谈论远程分支的安全保证。

用一个例子明确地回答你的一个问题:*“为什么不只git branch -aprependremotes/?”*

有一个存储库,git branch -a返回以下输出,其中只有最后一个是实际的远程分支:

$ git branch -a
* master
  origin/master
  remotes/origin/master

至于指定远程跟踪分支,使用git branch --set-upstream,您需要知道您是不是指定某个远程的分支。您确实正在设置一个远程跟踪分支,这就是为什么您需要在那里引用该远程跟踪分支。

实际上没有什么-除了约定-需要远程跟踪分支被称为remotes/<remote>/<branch>。绝对有可能将它们命名为foo/bar/baz/<branch>,而它们仍将使用git fetch进行更新。因为重要的是存储在存储库的配置文件中的远程配置。通常,这样的部分看起来像这样:

[remote "origin"]
    url = git@github.com:poke/myproject.git
    fetch = +refs/heads/*:refs/remotes/origin/*

这基本上告诉 Git 在remotes/origin/*为远程的本地分支列表中找到的每个分支更新远程分支

0

我看到这已经回答了,但我要尝试一些不同的东西。

这里的基本问题是git pull是一个非常古老的命令,它是在远程跟踪分支的整个想法完整且常见之前编写的。

Background

使用 git(或任何现代的分布式版本控制系统)首先要记住的是,您的存储库是您的。您的存储库中实际上没有任何“远程分支”,只有本地分支。称为“remote”的存储库-或稍好一点的名称“remote-tracking”-存储在您的存储库中的本地存储;它们只是更新了什么

也就是说,您的remotes/origin/master是“我,您的 git 的副本,也是上次我在master上看到的东西,并询问他的 git 在master中的内容。”因此,这是您上次检查时在那里(或曾经)的最新副本。再次检查,您只需运行

(从 1.8.2 开始使用 git,确实是这种情况;在较早的版本中,一些git fetch调用无法更新您的副本。令人讨厌的是,它是特别是git pull脚本运行的调用。但是,如果您的 git 比这更新,那么这个小皱纹就消失了,并且远程跟踪分支真的消失了

History

有了这些,让我们回到git pull,以及它背后的历史。具体来说,有一个时间点根本没有“远程”。如果你是 Linus Torvalds,或者和他一起工作,你运行了git fetch git://some.host.name/some/path develop合并命令,因为你知道谁在做什么,他们的主机名是什么,以及他们使用的是什么分支。

事实证明,这真的很常见,所以有人写了pull脚本来执行提取,然后进行合并。而且仍然没有“远程”,所以您只是命名了您知道 Bob 正在用于开发的分支:您的 git 调用他的分支,通过您刚刚键入的分支名称询问他的分支,然后您的 git 合并了他的东西,从FETCH_HEAD文件到当前的

结果,作为git pull的参数给出的分支名称实际上根本不是本地分支名称,这严重违反了几乎所有其他关于 git 分支名称的规则。这些名称被传递给git fetch,后者又将它们传递给调用的 git,并通过 Internet-phone(或其他任何传输 ID)将其填充到

Evolution

一旦“遥控器”被发明,“远程跟踪分支”的想法存储在您的本地仓库中,所有的旧东西都应该立即被扔掉,当然人们已经习惯了它,并且正在使用它并依赖于这种行为。所以git pull origin master仍然以它多年来的方式工作,并且仍然违反规则。

幸运的是,git pull只需找出上游远程是什么,以及该远程上的分支是什么,因此在没有额外参数的情况下运行它会使用跟踪信息,并且会自动执行正确的操作。您将 URL 存储在适当的远程名称下一次-通常 git 会在初始克隆上为您执行此操作-从那时起,您无需重新键入长 URL。

问题

您仍然可以使用额外的参数运行git pull,因为向后兼容性实际上很重要。las,git pull origin master develop并不意味着大多数人期望它的意思:pull脚本告诉fetch将遥控器的masterdevelop都放入

参考规格

值得在这里补充的是,在某些情况下,您do需要指定本地分支名称和远程分支名称。具体来说,如果您(本地)命名了一个分支fix-bug-123,这是一个很好的明智的做法,当您在develop分支上修复 bug # 123 时,您可能希望将您的修复直接推送到develop

简而言之,refspec 是1只是一对分支名称。要将您的fix-bug-123推送到其develop,请执行以下操作:

$ git push them fix-bug-123:develop

您的本地分支名称位于左侧,其远程分支名称位于右侧。

您可以在获取时执行相同的操作(请记住,push的反面是fetch不是pull-pull是执行fetch-then-merge的历史脚本!),但是这里的名称是相反的。

$ git fetch git://mrjones.com/path/to/repo.git feature:jones-feature
[fetch stuff happens here]
$ git log jones-feature

它可能是明智的创建一个实际的远程,并获取一切:“不太明智的”方法只是为了说明。这里他的分支名称在左边,你的在右边,因为它总是“源:目的地”。

“更明智”的方式让你得到一个remotes/mrjones/feature

$ git remote add mrjones git://mrjones.com/path/to/repo.git
$ git fetch mrjones
$ git log remotes/mrjones/feature

当您这样做时,git 仍然使用 fetch ref-specs,但它将它们隐藏在您的.git/config文件中,在remote条目下mrjones。您可以使用git config get-all查看它们:

$ git config get-all remote.mrjones.fetch

get-all变体是在您设置多个fetch行的情况下;默认情况下,git 只创建一个提取行,但我想我应该在这里说明最复杂的情况。)

1稍微太短:例如,这掩盖了标记如何工作的细节。根据需要匹配不合格的 ref-specs,或将其创建为分支。例如,要强制某些内容成为标签,请将其拼出:refs/tags/sometag。用refs/拼出的任何内容都会使 git 在该名称空间内工作。

本站系公益性非盈利分享网址,本文来自用户投稿,不代表边看边学立场,如若转载,请注明出处

(862)
Boy time:GameBoyGPU和任天堂徽标
上一篇
熟悉linux系统:面试问题:你熟悉 linux吗(linux interview questions)
下一篇

相关推荐

发表评论

登录 后才能评论

评论列表(44条)