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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2739376/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 08:19:41  来源:igfitidea点击:

Definition of "downstream" and "upstream"

gitversion-controlversioningterminologydefinition

提问by brendan

I've started playing with Git and have come across the terms "upstream" and "downstream". I've seen these before but never understood them fully. What do these terms mean in the context of SCMs (Software Configuration Managementtools) and source code?

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

采纳答案by brian d foy

In terms of source control, you're "downstream" when you copy (clone, checkout, etc) from a repository. Information flowed "downstream" to you.

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

When you make changes, you usually want to send them back "upstream" so they make it into that repository so that everyone pulling from the same source is working with all the same changes. This is mostly a social issue of how everyone can coordinate their work rather than a technical requirement of source control. You want to get your changes into the main project so you're not tracking divergent lines of development.

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

Sometimes you'll read about package or release managers (the people, not the tool) talking about submitting changes to "upstream". That usually means they had to adjust the original sources so they could create a package for their system. They don't want to keep making those changes, so if they send them "upstream" to the original source, they shouldn't have to deal with the same issue in the next release.

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

回答by VonC

When you read in git tagman page:

当您阅读git tag手册页时

One important aspect of git is it is distributed, and being distributed largely means there is no inherent "upstream" or "downstream" in the system.

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

, that simply means there is no absoluteupstream repo or downstream repo.
Those notions are always relative between two repos and depends on the way data flows:

,这只是意味着没有绝对的上游回购或下游回购。
这些概念在两个存储库之间始终是相对的,并且取决于数据流动的方式:

If "yourRepo" has declared "otherRepo" as a remote one, then:

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

  • you are pulling from upstream"otherRepo" ("otherRepo" is "upstream fromyou", and you are "downstream forotherRepo").
  • you are pushing to upstream("otherRepo" is still "upstream", where the information now goes back to).
  • 您正在从上游拉“otherRepo”(“otherRepo”是“上游你”,你是“下游用于otherRepo”)。
  • 您正在推动上游(“otherRepo”仍然是“上游”,信息现在可以返回到那里)。

Note the "from" and "for": you are not just "downstream", you are "downstream from/for", hence the relative aspect.

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



The DVCS (Distributed Version Control System) twist is: you have no idea what downstream actually is, beside your own repo relative to the remote repos you have declared.

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

  • you know what upstream is (the repos you are pulling from or pushing to)
  • you don't know what downstream is made of (the other repos pulling from or pushing to your repo).
  • 你知道上游是什么(你正在拉取或推送到的回购)
  • 您不知道下游是由什么组成的(其他回购从您的回购中拉出或推向您的回购)。

Basically:

基本上:

In term of "flow of data", your repo is at the bottom ("downstream") of a flow coming from upstream repos ("pull from") and going back to (the same or other) upstream repos ("push to").

就“数据流”而言,您的回购位于来自上游回购(“拉出”)并返回(相同或其他)上游回购(“推到”)的流的底部(“下游”) )。



You can see an illustration in the git-rebaseman pagewith the paragraph "RECOVERING FROM UPSTREAM REBASE":

您可以在git-rebase手册页中看到带有“从上游重新数据库恢复”段落的插图:

It means you are pulling from an "upstream" repo where a rebase took place, and you (the "downstream" repo) is stuck with the consequence (lots of duplicate commits, because the branch rebased upstream recreated the commits of the same branch you have locally).

这意味着您正在从发生变基的“上游”存储库中提取,并且您(“下游”存储库)被结果困住了(大量重复提交,因为上游变基的分支重新创建了与您相同的分支的提交)本地有)。

That is bad because for one "upstream" repo, there can be manydownstream repos (i.e. repos pulling from the upstream one, with the rebased branch), all of them having potentially to deal with the duplicate commits.

这很糟糕,因为对于一个“上游”存储库,可能有许多下游存储库(即从上游拉出的存储库,具有重新定位的分支),所有这些存储库都有可能处理重复提交。

Again, with the "flow of data" analogy, in a DVCS, one bad command "upstream" can have a "ripple effect" downstream.

同样,以“数据流”类比,在 DVCS 中,“上游”的一个错误命令可能会在下游产生“连锁反应”。



Note: this is not limited to data.
It also applies to parameters, as git commands (like the "porcelain" ones) often call internally other git commands (the "plumbing" ones). See rev-parseman page:

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

Many git porcelainish commands take mixture of flags (i.e. parameters that begin with a dash '-') and parameters meant for the underlying git rev-listcommand they use internally and flags and parameters for the other commands they use downstream of git rev-list. This command is used to distinguish between them.

许多 git 瓷器命令混合使用标志(即以破折号 ' -'开头的参数)和用于git rev-list它们内部使用的底层命令的参数以及它们在git rev-list.下游使用的其他命令的标志和参数。该命令用于区分它们。

回答by Peter Host

Upstream (as related to) Tracking

上游(相关)跟踪

The term upstreamalso has some unambiguous meaning as comes to the suite of GIT tools, especially relative to tracking

上游这个术语对于 GIT 工具套件也有一些明确的含义,特别是相对于跟踪

For example :

例如 :

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

will print (the last cached value of) the number of commits behind (left) and ahead (right) of your current working branch, relative to the (if any) currently tracking remote branchfor this local branch. It will print an error message otherwise:

    >error: No upstream branch found for ''
   $git rev-list --count --left-right "@{upstream}"...HEAD
   >4   12

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

    >error: No upstream branch found for ''
  • As has already been said, you may have any number of remotes for one local repository, for example, if you fork a repository from github, then issue a 'pull request', you most certainly have at least two: origin(your forked repo on github) and upstream(the repo on github you forked from). Those are just interchangeable names, only the 'git@...' url identifies them.
  • 如前所述,您可能有任意数量的远程仓库用于一个本地存储库,例如,如果您从 github 分叉存储库,然后发出“拉取请求”,那么您肯定至少有两个:(origin您的分叉存储库位于github)和upstream(你从 github 上分叉的仓库)。这些只是可互换的名称,只有 'git@...' url 标识它们。

Your .git/configreads :

   [remote "origin"]
       fetch = +refs/heads/*:refs/remotes/origin/*
       url = [email protected]:myusername/reponame.git
   [remote "upstream"]
       fetch = +refs/heads/*:refs/remotes/upstream/*
       url = [email protected]:authorname/reponame.git

你的.git/config阅读:

   [remote "origin"]
       fetch = +refs/heads/*:refs/remotes/origin/*
       url = [email protected]:myusername/reponame.git
   [remote "upstream"]
       fetch = +refs/heads/*:refs/remotes/upstream/*
       url = [email protected]:authorname/reponame.git
  • On the other hand, @{upstream}'s meaning for GIT is unique :
  • 另一方面,@{upstream}对 GIT 的意义是独一无二的:

it is 'the branch'(if any) on 'said remote', which is tracking the 'current branch'on your 'local repository'.

It's the branch you fetch/pull from whenever you issue a plain git fetch/git pull, without arguments.

它是' said remote''the branch'(如果有),它正在跟踪您的'local repository'上的'current branch '

它是您在不带参数的情况下发出普通git fetch/时从中获取/拉出的分支git pull

Let's say want to set the remote branch origin/master to be the tracking branch for the local master branch you've checked out. Just issue :

假设想要将远程分支 origin/master 设置为您已签出的本地 master 分支的跟踪分支。只是问题:

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

This adds 2 parameters in .git/config:

   [branch "master"]
       remote = origin
       merge = refs/heads/master

now try (provided 'upstream' remote has a 'dev' branch)

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

.git/confignow reads:

   [branch "master"]
       remote = upstream
       merge = refs/heads/dev

git-push(1)Manual Page:

   -u
   --set-upstream

For every branch that is up to date or successfully pushed, add upstream (tracking)reference, used by argument-less git-pull(1) and other commands. For more information, see branch.<name>.mergein git-config(1).

git-config(1)Manual Page:

   branch.<name>.merge

Defines, together with branch.<name>.remote, the upstreambranch for the given branch. It tells git fetch/git pull/git rebase which branch to merge and can also affect git push (see push.default). \ (...)

   branch.<name>.remote

When in branch < name >, it tells git fetch and git push which remote to fetch from/push to. It defaults to origin if no remote is configured. origin is also used if you are not on any branch.

   $ 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

现在尝试(前提是“上游”遥控器有一个“开发”分支)

   $ 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) 和其他命令使用。有关更多信息,请参阅branch.<name>.mergegit-config(1)。

git-config(1)手册页

   branch.<name>.merge

与 一起定义给定分支branch.<name>.remote上游分支。它告诉 git fetch/git pull/git rebase 要合并哪个分支,也可以影响 git push(参见 push.default)。\ (...)

   branch.<name>.remote

当在分支 <name> 中时,它告诉 git fetch 和 git push 从/推送到哪个远程。如果未配置远程,则默认为 origin。如果您不在任何分支上,也会使用 origin。

Upstream and Push (Gotcha)

上游和推送(陷阱)

take a look at git-config(1)Manual Page

看看git-config(1)手册页

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

This is to prevent accidental pushes to branches which you're not ready to push yet.

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

这是为了防止意外推送到您尚未准备好推送的分支。

回答by hasen

That's a bit of informal terminology.

这是一些非正式的术语。

As far as Git is concerned, every other repository is just a remote.

就 Git 而言,其他所有存储库都只是一个远程存储库。

Generally speaking, upstream is where you cloned from (the origin). Downstream is any project that integrates your work with other works.

一般来说,上游是您从(原点)克隆的地方。下游是将您的作品与其他作品相结合的任何项目。

The terms are not restricted to Git repositories.

这些条款不限于 Git 存储库。

For instance, Ubuntu is a Debian derivative, so Debian is upstream for Ubuntu.

例如,Ubuntu 是 Debian 的衍生版本,因此 Debian 是 Ubuntu 的上游。

回答by matt

Upstream Called Harmful

上游称为有害

There is, alas, another use of "upstream" that the other answers here are not getting at, namely to refer to the parent-child relationship of commits within a repo. Scott Chacon in the Pro Git bookis particularly prone to this, and the results are unfortunate. Do not imitate this way of speaking.

唉,这里的其他答案没有提到“上游”的另一种用法,即指代回购中提交的父子关系。Pro Git 书中的Scott Chacon特别容易出现这种情况,结果很不幸。不要模仿这种说话方式。

For example, he says of a merge resulting a fast-forward that this happens because

例如,他说合并导致快进,这是因为

the commit pointed to by the branch you merged in was directly upstream of the commit you're on

您合并的分支指向的提交直接位于您所在的提交的上游

He wants to say that commit B is the only child of the only child of ... of the only child of commit A, so to merge B into A it is sufficient to move the ref A to point to commit B. Why this direction should be called "upstream" rather than "downstream", or why the geometry of such a pure straight-line graph should be described "directly upstream", is completely unclear and probably arbitrary. (The man page for git-mergedoes a far better job of explaining this relationship when it says that "the current branch head is an ancestor of the named commit." That is the sort of thing Chacon should have said.)

他想说 commit B 是 commit A 的独生子的...的独生子的独生子,所以要将 B 合并到 A 中,只需将 ref A 移动到 commit B 就可以了。 为什么是这个方向应该被称为“上游”而不是“下游”,或者为什么这种纯直线图的几何形状应该被描述为“直接上游”,这是完全不清楚的,可能是任意的。(git-merge当它说“当前分支头是命名提交的祖先。”这是 Chacon 应该说的那种事情时,它的手册页在解释这种关系方面做得更好。)

Indeed, Chacon himself appears to use "downstream" later to mean exactly the same thing, when he speaks of rewriting all child commits of a deleted commit:

事实上,当 Chacon 谈到重写已删除提交的所有子提交时,他自己似乎后来使用“下游”来表示完全相同的意思:

You must rewrite all the commits downstream from 6df76 to fully remove this file from your Git history

您必须重写 6df76 下游的所有提交才能从 Git 历史记录中完全删除此文件

Basically he seems not to have any clear idea what he means by "upstream" and "downstream" when referring to the history of commits over time. This use is informal, then, and not to be encouraged, as it is just confusing.

基本上,当提到随着时间的推移提交的历史时,他似乎并不清楚他所说的“上游”和“下游”是什么意思。这种使用是非正式的,因此不鼓励使用,因为它只是令人困惑。

It is perfectly clear that every commit (except one) has at least one parent, and that parents of parents are thus ancestors; and in the other direction, commits have children and descendants. That's accepted terminology, and describes the directionality of the graph unambiguously, so that's the way to talk when you want to describe how commits relate to one another within the graph geometry of a repo. Do not use "upstream" or "downstream" loosely in this situation.

很明显,每个提交(除了一个)都有至少一个父级,因此父级的父级是祖先;在另一个方向,提交有孩子和后代。这是公认的术语,并且明确地描述了图形的方向性,因此当您想描述提交在存储库的图形几何中如何相互关联时,这就是谈话的方式。在这种情况下,不要松散地使用“上游”或“下游”。

[Additional note: I've been thinking about the relationship between the first Chacon sentence I cite above and the git-mergeman page, and it occurs to me that the former may be based on a misunderstanding of the latter. The man page does go on to describe a situation where the use of "upstream" is legitimate: fast-forwarding often happens when "you are tracking an upstream repository, you have committed no local changes, and now you want to update to a newer upstream revision." So perhaps Chacon used "upstream" because he saw it here in the man page. But in the man page there is a remote repository; there is no remote repository in Chacon's cited example of fast-forwarding, just a couple of locally created branches.]

[附加说明:我一直在思考我上面引用的第一个 Chacon 句子和git-merge手册页之间的关系,我突然想到前者可能是基于对后者的误解。手册页确实继续描述了使用“上游”是合法的情况:快进通常发生在“您正在跟踪上游存储库,您没有提交任何本地更改,现在您想要更新到更新的”上游修订。” 所以也许 Chacon 使用了“上游”,因为他在手册页中看到了它。但是在手册页中有一个远程存储库;Chacon 引用的快速转发示例中没有远程存储库,只有几个本地创建的分支。]