协慌网

登录 贡献 社区

“下游”和 “上游” 的定义

我已经开始玩 Git 并遇到过 “上游” 和 “下游” 这两个词。我之前见过这些,但从未完全理解它们。这些术语在 SCM( 软件配置管理工具)和源代码的上下文中意味着什么?

答案

在源代码控制方面,当您从存储库复制(克隆,签出等)时,您处于 “ 下游 ”。信息流向 “下游” 给您。

当您进行更改时,您通常希望将它们发送回 “ 上游 ”,以便它们进入该存储库,以便从同一来源拉出的每个人都在处理所有相同的更改。这主要是每个人如何协调工作而不是源控制技术要求的社会问题。您希望将更改纳入主项目,这样您就无法跟踪不同的开发线。

有时您会阅读有关提交 “上游” 更改的包或发布经理(人员,而不是工具)。这通常意味着他们必须调整原始来源,以便他们可以为他们的系统创建一个包。他们不想继续进行这些更改,因此如果他们将它们 “上游” 发送到原始源,他们就不必在下一个版本中处理相同的问题。

当您在git tag手册页中阅读时:

git 的一个重要方面是它是分布式的,并且分布很大意味着系统中没有固有的 “上游” 或 “下游”。

,这仅仅意味着没有绝对的上游回购或下游回购。
这些概念在两个回购之间总是相对的,取决于数据的流动方式:

如果 “yourRepo” 已将 “otherRepo” 声明为远程,则

  • 要从上游 “otherRepo” (“otherRepo” 是 “上游你”,你是 “ otherRepo 下游”)。
  • 你正推向上游 (“otherRepo” 仍然是 “上游”,现在信息可以回到上游)。

注意 “从” 和 “为”:你不仅仅是 “下游”,你是 “下游/ 为 ”,因此相对方面。


DVCS(分布式版本控制系统)扭曲是:你不知道下游实际上是什么,除了你自己的 repo 相对于你声明的远程仓库。

  • 你知道上游是什么(你正在拉动或推动的回购)
  • 你不知道下游是由什么组成的(另一个回购拉动或推动你的回购 )。

基本上:

在 “ 数据流 ” 方面,您的仓库位于来自上游回购(“拉出”)并返回(相同或其他)上游回购(“推送到”)的流的底部(“下游”) )。


您可以在git-rebase手册页中看到一个插图,其中包含 “从上游重新恢复” 的段落:

这意味着你正在从一个发生 rebase 的 “上游” 仓库中撤出 ,而你(“下游” 仓库)仍然存在后果(许多重复提交,因为上游的分支重新创建了同一分支的提交你在当地)。

这是不好的,因为对于一个 “上游” 回购,可能有许多下游回购(即从上游回收利用重新分支的回购),所有这些都有可能处理重复提交。

同样,对于 “数据流” 类比,在 DVCS 中,一个坏命令 “上游” 可以在下游具有 “ 波纹效应 ”。


注意:这不仅限于数据。
它也适用于参数 ,因为 git 命令(如 “瓷器” 命令)经常在内部调用其他 git 命令(“plumbing” 命令)。请参阅rev-parse手册页

许多 git ceramicish 命令混合使用标志(即以短划线 ' - ' 开头的参数)和用于内部使用的底层git rev-list命令的参数,以及用于git rev-list下游的其他命令的标志和参数 。此命令用于区分它们。

上游(与之相关)跟踪

对于 GIT 工具套件而言, 上游一词也具有一些明确的含义,特别是与跟踪相关

例如 :

$git rev-list --count --left-right "@{upstream}"...HEAD
   >4   12

将打印(最后一个缓存的值)当前工作分支后面(左)和前面(右)的提交数,相对于当前跟踪此本地分支的远程分支如果有 )。否则将打印错误消息:

>error: No upstream branch found for ''
  • 正如已经说过的,你可能有一个本地存储库的任意数量的遥控器,例如,如果你从 github 分叉存储库,然后发出一个 '拉取请求',你肯定至少有两个: origin (你的分叉回购)在 github 上)和upstream (你分叉的 github upstream的 repo)。这些只是可互换的名称,只有'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
  • 另一方面, @ {upstream}对 GIT 的意义是唯一的:

它是 所说的遥控器”上的 分支” (如果有的话),它跟踪“本地存储库”上的“当前分支

它是你在没有参数的情况下发出普通git fetch / git pull时获取 / 拉出的分支。

假设想要将远程分支 origin / master 设置为您已检出的本地主分支的跟踪分支。刚发出:

$ git branch --set-upstream  master origin/master
   > Branch master set up to track remote branch master from origin.

这在.git/config添加了 2 个参数:

[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

git-push(1)手册页

-u
   --set-upstream

对于每个最新或成功推送的分支,添加上游(跟踪)引用,由无参数 git-pull(1)和其他命令使用。有关更多信息,请参阅 git-config(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。如果您不在任何分支上,也会使用原点。

上游和推送(Gotcha)

看看git-config(1)手册页

git config --global push.default upstream
   git config --global push.default tracking  (deprecated)

这是为了防止意外推送到你尚未准备推进的树枝上。