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

发布于 2024-08-30 09:38:08 字数 183 浏览 4 评论 0原文

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

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 Management tools) and source code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

我们只是彼此的过ke 2024-09-06 09:38:08

就源代码控制而言,当您从存储库复制(克隆、签出等)时,您处于下游。信息“顺流而下”流向你。

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

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

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.

雪落纷纷 2024-09-06 09:38:08

当您阅读 git tag 时手册页

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

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

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

  • 从上游“otherRepo”(“otherRepo”是“您的上游”,而您是“otherRepo 的下游”)。
  • 您正在推送到上游(“otherRepo”仍然是“上游”,信息现在返回到的位置)。

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


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

  • 你知道上游是什么(你从中拉取或推入的存储库),但
  • 你不知道下游是什么(从你的存储库拉取或推入的其他存储库)。

基本上:

就“数据流”而言,您的存储库位于来自上游存储库(“拉取”)并返回到(相同或其他)上游存储库(“推送到”)。


您可以在 git-rebase 手册页,其中包含“从上游 REBASE 恢复”段落:

这意味着您正在从发生 rebase 的“上游”存储库中提取,而您(“下游”存储库)则陷入了后果(大量重复提交,因为上游分支重新基化重新创建了您在本地拥有的同一分支的提交)。

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

再次以“数据流”进行类比,在 DVCS 中,“上游”的一个错误命令可能会在下游产生“涟漪效应”。


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

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

When you read in git tag man page:

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

, that simply means there is no absolute upstream 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:

  • you are pulling from upstream "otherRepo" ("otherRepo" is "upstream from you", and you are "downstream for otherRepo").
  • you are pushing to upstream ("otherRepo" is still "upstream", where the information now goes back to).

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


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.

  • 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-rebase man page with the paragraph "RECOVERING FROM UPSTREAM 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 many downstream 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.


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-parse man page:

Many git porcelainish commands take mixture of flags (i.e. parameters that begin with a dash '-') and parameters meant for the underlying git rev-list command 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.

和我恋爱吧 2024-09-06 09:38:08

上游(与相关)跟踪

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

例如:

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

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

 >错误:找不到“”的上游分支

  • 正如已经说过的,一个本地存储库可能有任意数量的遥控器,例如,如果您从 github 分叉一个存储库,然后发出一个“拉取请求”,您肯定会在至少两个:origin(您在 github 上分叉的存储库)和 upstream(您在 github 上分叉的存储库)。这些只是可互换的名称,只有“git@...”url 可以识别它们。

您的.git/config内容为:

 [远程“原点”]
       fetch = +refs/heads/*:refs/remotes/origin/*
       url = [电子邮件受保护]:myusername/reponame.git
   [远程“上游”]
       fetch = +refs/heads/*:refs/remotes/upstream/*
       url = [电子邮件受保护]:authorname/reponame.git
  • 另一方面,@{upstream} 对 GIT 的含义是独特的:

它是“所述远程”上的“分支”(如果有),正在跟踪“当前分支” > 在您的“本地存储库”上。

每当您发出不带参数的普通 git fetch/git pull 时,您都会从中获取/拉取分支。

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

 $ gitbranch --set-upstream master origin/master
   >设置分支主控以跟踪来自原点的远程分支主控。

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

 [分支“master”]
       远程=原点
       合并 = refs/heads/master

现在尝试(假设“上游”远程有一个“dev”分支)

 $ gitbranch --set-upstream masterupstream/dev
   >分支主机设置为跟踪来自上游的远程分支开发。

.git/config 现在显示为:

 [分支“master”]
       远程=上游
       合并 = refs/heads/dev

git-push(1)手册页

<前><代码> -u
--设置上游

对于每个最新或成功推送的分支,添加上游(跟踪)引用,由无参数 git-pull(1) 和其他命令使用。有关更多信息,请参阅 git-config(1) 中的 branch..merge

git-config(1) 手册页

 分支.<名称>.merge

branch..remote一起定义给定分支的上游分支。它告诉 git fetch/git pull/git rebase 要合并哪个分支,并且还可以影响 git Push(请参阅push.default)。
\
(...)

 分支.<名称>.remote

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

上游和推送(问题)

请查看 git-config(1) 手册页

 git config --global Push.default 上游
   git config --global Push.default 跟踪(已弃用)

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

Upstream (as related to) Tracking

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

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 branch for this local branch. It will print an error message otherwise:

    >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.

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
  • On the other hand, @{upstream}'s meaning for GIT is unique :

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.

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 :

   $ 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/config now 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>.merge in git-config(1).

git-config(1) Manual Page :

   branch.<name>.merge

Defines, together with branch.<name>.remote, the upstream branch 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.

Upstream and Push (Gotcha)

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

   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.

ペ泪落弦音 2024-09-06 09:38:08

这是一些非正式术语。

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

一般来说,上游是您克隆的位置(原点)。下游是将您的作品与其他作品集成的任何项目。

这些术语不限于 Git 存储库。

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

That's a bit of informal terminology.

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

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.

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

我要还你自由 2024-09-06 09:38:08

上游称为有害

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

例如,他说合并导致快进,发生这种情况是因为

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

提交 B 是提交 A 的唯一子级的唯一子级的唯一子级,因此要将 B 合并到 A 中,只需将引用 A 移动到为什么这个方向应该被称为“上游”而不是“下游”,或者为什么这样一个纯直线图的几何形状应该被描述为“直接上游”,是完全不清楚的,并且可能是任意的。 (git-merge 的手册页在解释这种关系方面做得更好,它说“当前分支头是指定提交的祖先。”这就是 Chacon 应该做的事情。 )

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

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

基本上,当提到一段时间内的提交历史记录时,他似乎并不清楚“上游”和“下游”的含义。那么,这种使用是非正式的,不值得鼓励,因为它只是令人困惑。

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

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

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 book is particularly prone to this, and the results are unfortunate. Do not imitate this way of speaking.

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-merge does 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.)

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:

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

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-merge man 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.]

無心 2024-09-06 09:38:08

使用河流的类比,我们可以沿着我们的上游资源,直到找到源头(溪流或河流的源头)。

继续与河流类比,下游是河流中水流的方向。下坡。

因此,如果我分叉某人的项目,我分叉的项目就是上游的。我的叉子在下游。

如果有人分叉我的分叉项目,那么我的分叉相对于我的项目的分叉成为上游。

而我的叉子的叉子就变成了下游。

示例时间!

假设项目 B 分叉了项目 A,而项目 C 又分叉了项目 B

那么,项目 A 就是上游项目。

项目 B 是相对于项目 A 的下游项目。

Project B 是相对于Project C 的上游项目。

项目C是相对于项目B的下游项目。

生命的循环还在继续。

注意:请注意,这是开源项目中相当常见的开发风格,用于创建项目的分支,修复错误或在该分支中添加功能,然后向原始项目提交补丁项目。

另请注意,“质量运动”和统计过程控制的一个明显教训是,从源头上解决质量问题的干预措施几乎总是比重复工作来解决可预防的问题更好的投资。因此,请贡献补丁(发送Pull requests)。

Using the analogy of a river, we can follow a resource upstream from us until we find the headwaters (the source of a stream or river).

Continuing with the river analogy, downstream is the direction that the water in a river flows. Downhill.

So, if I fork someone's project, The project I forked is upstream. And my fork is downstream.

if someone forks my forked project, Then my fork becomes upstream relative to the fork of my project.

And the fork of my fork becomes downstream.

Example Time!

Suppose Project B forked Project A and Project C forked Project B.

Then, Project A is the upstream project.

Project B is the downstream project relative to Project A.

Project B is the upstream project relative to Project C.

Project C is the downstream project relative to Project B.

And the circle of life continues.

NOTE: Please note that, this is a rather common development style in open source projects to create a fork of a project, fix a bug or add a feature in that fork and then submit a patch to the original project.

Also note that, a clear lesson from the “quality movement” and statistical process control is that interventions that fix quality problems at their source are almost always a better investment than repeated work to fix problems that were preventable. So please contribute patches (send Pull requests).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文