我开始玩Git,遇到过“上游”和“下游”这两个术语。我以前看过这些,但从未完全了解它们。这些术语在SCM(软件配置管理工具)和源代码的上下文中是什么意思?
我开始玩Git,遇到过“上游”和“下游”这两个术语。我以前看过这些,但从未完全了解它们。这些术语在SCM(软件配置管理工具)和源代码的上下文中是什么意思?
Answers:
在源代码管理方面,从存储库复制(克隆,签出等)时,您处于“ 下游 ”状态。信息流向您的下游。
进行更改时,通常希望将它们发送回“ 上游 ”,以便它们将其发送到该存储库中,以便从同一源提取信息的每个人都可以进行所有相同的更改。这主要是每个人如何协调工作的社会问题,而不是源代码控制的技术要求。您希望将更改纳入主项目,以免跟踪不同的开发路线。
有时,您会读到有关将更改提交到“上游”的程序包或发行经理(人员,而不是工具)的信息。这通常意味着他们必须调整原始来源,以便可以为其系统创建一个程序包。他们不想继续进行这些更改,因此,如果将它们“上游”发送到原始来源,则他们不必在下一发行版中处理相同的问题。
-u
一样git push --set-upstream origin master
,如果它不是一个技术要求?我们可以push -u origin
或不可以push origin
,所以这是一项技术要求。但是有什么区别呢?
当您在git tag
手册页中阅读时:
git的一个重要方面是它是分布式的,并且很大程度上是分布式的,这意味着系统中没有固有的“上游”或“下游”。
,仅表示没有绝对上游回购或下游回购。
这些概念始终是两个仓库之间的相对关系,并取决于数据流的方式:
如果“ yourRepo”已声明“ otherRepo”为远程数据库,则:
注意“ from”和“ for”:您不仅是“下游”,而且是“ from / for ”的下游,因此是相对方面。
DVCS(分布式版本控制系统)的缺点是:您不知道下游到底是什么,除了您自己的仓库(相对于已声明的远程仓库)之外。
基本上:
在“ 数据流 ”方面,您的存储库位于来自上游存储库(“从...拉出”)并返回(相同或其他)上游存储库(“推送至”)的流的底部(“下游”) )。
您可以在git-rebase
手册页中看到带有“从UPSTREAM REBASE进行恢复”段落的插图:
这意味着您要从发生了基础更改的“上游”存储库中拉出,并且您(“下游”存储库)被结果卡住了(很多重复的提交,因为分支基于上游的分支重新创建了与您相同的分支的提交)本地)。
这很不好,因为对于一个“上游”存储库,可能有许多下游存储库(即,从具有上游存储库的存储库,通过重新定位的分支),所有这些存储库都可能处理重复的提交。
再次,与“数据流”类比,在DVCS中,一个错误的命令“上游”可能对下游产生“ 波纹效应 ”。
注意:这不限于数据。
它也适用于参数,因为git命令(例如“瓷器”命令)经常在内部调用其他git命令(“管道”命令)。参见rev-parse
手册页:
许多git命令混合使用标志(即以破折号'
-
' 开头的参数)和表示git rev-list
内部使用的基本命令的参数,以及用于下游的其他命令的标志和参数的混合git rev-list
。此命令用于区分它们。
对于GIT工具套件,上游一词也具有明确的含义,尤其是相对于跟踪
例如 :
$git rev-list --count --left-right "@{upstream}"...HEAD >4 12
相对于该本地分支当前正在跟踪的远程分支(如果有),将打印(当前的分支的后面(左侧)和前面(右侧))提交的数量(最后缓存的值)。否则将显示错误消息:
>error: No upstream branch found for ''
origin
您的分叉存储库github)和upstream
(您从中派生的github上的仓库)。这些只是可互换的名称,只有“ git @ ...” URL可以标识它们。您的
.git/config
读物:[remote "origin"] fetch = +refs/heads/*:refs/remotes/origin/* url = git@github.com:myusername/reponame.git [remote "upstream"] fetch = +refs/heads/*:refs/remotes/upstream/* url = git@github.com:authorname/reponame.git
它是“ 所述远程”上的“ 分支”(如果有),它正在跟踪“本地存储库”上的“当前分支”。
这是每当您发出无参数的
git fetch
/ 时从中获取/拉取的分支git pull
。
假设要将远程分支的原始/主节点设置为已签出的本地主分支的跟踪分支。只是问题:
$ git branch --set-upstream master origin/master > Branch master set up to track remote branch master from origin.
这会在中添加2个参数
.git/config
:[branch "master"] remote = origin merge = refs/heads/master
现在尝试(提供的“上游”遥控器具有“ dev”分支)
$ git branch --set-upstream master upstream/dev > Branch master set up to track remote branch dev from upstream.
.git/config
现在显示:[branch "master"] remote = upstream merge = refs/heads/dev
-u --set-upstream
对于每个最新的或成功推送的分支,添加上游(跟踪)引用,该引用由无参数git-pull(1)和其他命令使用。有关更多信息,请参见
branch.<name>.merge
git-config(1)。branch.<name>.merge
与一起定义给定分支
branch.<name>.remote
的上游分支。它告诉git fetch / git pull / git rebase合并哪个分支,并且还可能影响git push(请参阅push.default)。\(...)branch.<name>.remote
在分支<名称>中时,它告诉git fetch和git push从哪个远程获取/推送到。如果未配置任何远程服务器,则默认为源。如果您不在任何分支上,也将使用origin。
git config --global push.default upstream git config --global push.default tracking (deprecated)
这是为了防止意外推送到您尚未准备好推送的分支。
git branch --help
截至2018年的节选:As this option had confusing syntax, it is no longer supported. Please use --track or --set-upstream-to instead.
a,还有“上游”的另一种用法,这里的其他答案都没有得到,即是指回购中提交的父子关系。Pro Git书中的 Scott Chacon 尤其容易出现这种情况,结果很不幸。不要模仿这种说话方式。
例如,他说合并导致快速前进,这是因为
您合并到的分支所指向的提交位于您所在的提交的直接上游
他想说提交B是提交A的唯一子项中...的唯一子项的唯一子项,因此要将B合并到A中,只需将引用A指向提交B即可。应该将其称为“上游”而不是“下游”,或者为什么应该在“直接上游”描述这种纯直线图的几何形状,这是完全不清楚的,并且可能是任意的。(的手册页git-merge
在解释这种关系时做得更好,当它说“当前分支头是指定提交的祖先。”这就是Chacon应该说的那种话。)
的确,当Chacon谈到重写已删除的提交的所有子提交时,他自己似乎后来使用“下游”一词是完全相同的:
您必须重写6df76下游的所有提交,才能从Git历史记录中完全删除此文件
基本上,当谈到一段时间内的提交历史时,他似乎并不清楚其对“上游”和“下游”的含义。因此,这种使用是非正式的,不应鼓励,因为这很令人困惑。
完全清楚的是,每一项承诺(除一项承诺外)都至少有一位父母,因此父母的父母就是祖先;在另一个方向上,提交有孩子和后代。这是公认的术语,并且明确描述了图的方向性,因此,当您要描述回购的图几何中的提交如何相互关联时,这就是一种交谈的方式。在这种情况下,请勿宽松地使用“上游”或“下游”。
[附加说明:我一直在思考我在上面引用的第一个Chacon句子与git-merge
手册页之间的关系,在我看来,前者可能是基于对后者的误解。手册页上继续描述了使用“上游”是合理的情况:当“您正在跟踪上游存储库,您尚未提交任何本地更改,现在您想更新到较新的版本时,通常会发生快速转发”上游修订。” 所以也许Chacon使用了“上游”,因为他在手册页中看到了它。但是在手册页中有一个远程存储库。Chacon引用的快速转发示例中没有远程存储库,只有几个本地创建的分支。
<branch>
。
git-rebase
文档中来到这里是因为我完全困惑为什么在这里将提交引用称为“上游”(实际上,我对此感到怀疑,因为我之前从未见过该术语)。感谢@outis和@matt整理了一切!