Определение «вниз по течению» и «вверх по течению» - PullRequest
817 голосов
/ 29 апреля 2010

Я начал играть с Git и столкнулся с терминами «upstream» и «downstream». Я видел это раньше, но никогда не понимал их полностью. Что означают эти термины в контексте SCM ( Software Configuration Management tools) и исходного кода?

Ответы [ 5 ]

634 голосов
/ 29 апреля 2010

С точки зрения контроля исходного кода, вы " downstream ", когда копируете (клон, извлечение и т. Д.) Из хранилища. Информация текла к вам «вниз по течению».

Когда вы вносите изменения, вы обычно хотите отправить их обратно " upstream ", чтобы они вошли в этот репозиторий, чтобы каждый, кто извлекал данные из одного и того же источника, работал со всеми одинаковыми изменениями. В основном это социальный вопрос о том, как каждый может координировать свою работу, а не техническое требование контроля источников. Вы хотите внести свои изменения в основной проект, чтобы не отслеживать разные линии развития.

Иногда вы будете читать о менеджерах пакетов или выпусков (люди, а не инструмент), говорящих об отправке изменений в «апстрим». Обычно это означает, что им пришлось настроить исходные источники, чтобы они могли создать пакет для своей системы. Они не хотят продолжать вносить эти изменения, поэтому, если они отправят их «в исходное состояние» в первоисточник, им не придется иметь дело с той же проблемой в следующем выпуске.

220 голосов
/ 01 мая 2010

Когда вы читаете в git tag справочную страницу :

Одним из важных аспектов git является то, что он распространяется, и его распространение в значительной степени означает, что в системе не существует «восходящего» или «нисходящего».

, это просто означает, что нет абсолютного обратного или обратного репо.
Эти понятия всегда являются относительными между двумя репозиториями и зависят от способа передачи данных:

Если «yourRepo» объявил «otherRepo» удаленным, то :

  • вы вытягиваете из восходящего потока"otherRepo" ("otherRepo" означает "upstream from you", а вы "downstream for otherRepo").
  • вы подталкиваете к восходящему потоку («otherRepo» по-прежнему «восходящий», куда теперь возвращается информация).

Обратите внимание на «от» и «для»: вы не просто «ниже по течению», вы «ниже по течению» от / для », отсюда и относительный аспект.


Изюминка DVCS (распределенной системы управления версиями) такова: вы не представляете, что на самом деле представляет собой нисходящий поток, кроме вашего собственного репо относительно объявленных вами удаленных репо.

  • Вы знаете, что вверх по течению (репо, из которых вы тянете или толкаете)
  • вы не знаете, из чего сделан нисходящий поток (другие репо тянут из или ваше репо ).

В основном:

В терминах « потока данных » ваше хранилище находится в нижней части («ниже по течению») потока, поступающего из вышестоящих хранилищ («тянуть из») и возвращающегося к ( те же или другие) репозитории в восходящем направлении («push to»).


Вы можете увидеть иллюстрацию на справочной странице git-rebase с параграфом «ВОССТАНОВЛЕНИЕ ОТ РЕБАЗЫ UPSTREAM»:

Это означает, что вы вытягиваете из репо "вверх по течению", где произошла перебазировка , а вы (репо "вниз по течению") застряли с последствием (много дублирующих коммитов, потому что ветвь перебазирована апстрим воссоздал коммиты той же ветки, что и у вас локально).

Это плохо, потому что для одного репо «вверх по течению» может быть много репо вниз по течению (т. Е. Репо, вытягивающие из апстрима, с перебазированной ветвью), все они потенциально иметь дело с дублирующими коммитами.

Опять же, по аналогии с «потоком данных», в DVCS одна плохая команда «upstream» может иметь « волновой эффект » downstream.


Примечание: это не ограничивается данными.
Это также относится к параметрам , поскольку команды git (например, «фарфоровые») часто вызывают внутри себя другие команды git («сантехнические»). См. rev-parse справочную страницу :

Многие команды git porcelainish принимают смесь флагов (то есть параметров, которые начинаются с тире '-') и параметров, предназначенных для базовой команды git rev-list, которую они используют внутри, и флагов и параметров для других команд, которые они используйте ниже git rev-list. Эта команда используется для различения между ними.

82 голосов
/ 05 июня 2011

Upstream (в связи с) Tracking

Термин upstream также имеет некоторое недвусмысленное значение, как и набор инструментов GIT, особенно относительно tracking

Например:

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

напечатает (последнее кэшированное значение) количество коммитов позади (слева) и впереди (справа) вашей текущей рабочей ветви, относительно( если есть ) отслеживание удаленной ветви для этой локальной ветви.В противном случае будет выведено сообщение об ошибке:

    >error: No upstream branch found for ''
  • Как уже было сказано, для одного локального репозитория может быть любое количество удаленных устройств, например, если вы разветвляете репозиторий изgithub, а затем выполните «запрос на извлечение», у вас наверняка есть как минимум два: origin (ваше разветвленное репо на github) и upstream (репо на github, с которого вы разветвлялись)Это просто взаимозаменяемые имена, их идентифицирует только URL «git @ ...».

Ваш .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, без аргументов.

Допустим, мы хотим установить источник / ветку удаленной ветви какветка отслеживания для локальной ветки master, которую вы извлекли.Просто введите:

   $ 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

git-push(1) Страница «Справочник» :

   -u
   --set-upstream

Для каждой ветки, которая обновлена ​​или успешно отправлена, добавьте восходящий (отслеживание) справочник, используемыйgit-pull (1) и другие команды без аргументов.Для получения дополнительной информации см. branch.<name>.merge в git-config (1).

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, с какого пульта следует выбрать / push.По умолчанию используется источник, если пульт не настроен.origin также используется, если вы не находитесь на какой-либо ветке.

Upstream и Push (Gotcha)

взгляните на git-config(1) Manual Page

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

Это предотвращает случайные толчки к ветвям, которые вы еще не готовы нажать.

52 голосов
/ 01 мая 2010

Это немного неформальной терминологии.

Что касается Git, все остальные репозитории - это просто удаленные.

Вообще говоря, вверх по течению это то место, откуда вы клонировали (источник). Downstream - это любой проект, который объединяет вашу работу с другими работами.

Условия не ограничиваются репозиториями Git.

Например, Ubuntu является производной от Debian, поэтому Debian является основной веткой разработки для Ubuntu.

48 голосов
/ 27 сентября 2012

Вверх по течению называется Вредным

Существует, увы, еще одно использование «восходящего потока», на которое другие ответы здесь не дошли, а именно, чтобы сослаться на родительско-дочерние отношения коммитов в репо. Скотт Чакон в книге Pro Git особенно склонен к этому, и результаты к сожалению. Не подражайте такому выражению.

Например, он говорит о слиянии, в результате которого происходит ускоренная перемотка, потому что

коммит, на который указывает ветка, в которую вы слились, был напрямую перед коммитом вы находитесь на

Он хочет сказать, что коммит B является единственным потомком единственного потомка ... единственного потомка коммита A, поэтому для слияния B с A достаточно переместить ссылку A для указания на фиксацию B. Почему это направление следует называть «восходящим», а не «нисходящим», или почему геометрию такого чисто линейного графа следует описывать «непосредственно вверх по течению», совершенно неясно и, вероятно, произвольно. (Страница man для git-merge гораздо лучше объясняет эту взаимосвязь, когда говорит, что «текущая глава ветки является предком именованного коммита. Это то, что должен был сказать Чакон.)

Действительно, сам Чакон, по-видимому, позже использует «вниз по течению», чтобы обозначать то же самое, когда говорит о переписывании всех дочерних коммитов удаленного коммита:

Вы должны переписать все коммиты вниз по течению от 6df76, чтобы полностью удалить этот файл из вашей истории Git

По сути, он, похоже, не имеет четкого представления о том, что он подразумевает под «восходящим» и «нисходящим», когда ссылается на историю коммитов во времени. Это использование неформально, и его не следует поощрять, поскольку оно просто сбивает с толку.

Совершенно очевидно, что каждый коммит (кроме одного) имеет по крайней мере одного родителя и что родители родителей, таким образом, являются предками; а в другом направлении коммиты имеют детей и потомков. Это принятая терминология, и она однозначно описывает направленность графа, так что это способ говорить, когда вы хотите описать, как коммиты связаны друг с другом в геометрии графа репо. В этой ситуации не используйте свободно вверх или вниз по течению.

[Дополнительное примечание: я размышлял о связи между первым предложением Чакона, которое я цитирую выше, и страницей справочника git-merge, и мне приходит в голову, что первое может быть основано на неправильном понимании последнего. Страница man продолжает описывать ситуацию, в которой использование «upstream» является законным: быстрая перемотка часто происходит, когда «вы отслеживаете репозиторий upstream, вы не зафиксировали локальных изменений, и теперь вы хотите перейти на более новую версию». редакция вверх по течению. " Так что, возможно, Чакон использовал «upstream», потому что он видел это здесь на странице руководства. Но на странице руководства есть удаленное хранилище; в приведенном Чаконе примере быстрой пересылки нет удаленного репозитория, только пара локально созданных веток.]

...