Определение "вниз по течению" и "вверх по течению"

Я начал играть с Git и столкнулся с терминами "upstream" и "downstream". Я видел это раньше, но никогда не понимаю их полностью. Что означают эти термины в контексте SCM (инструменты управления конфигурацией программного обеспечения) и исходного кода?

6 ответов

Решение

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

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

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

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

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

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

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

  • вы вытягиваете из "другого" репо вверх по течению ("другоеРепо" означает " от вас вверх по течению", а вы " для другогоРепо" ниже по течению)).
  • Вы подталкиваете к восходящему потоку ("otherRepo" по-прежнему является "восходящим", куда теперь возвращается информация).

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


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

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

В принципе:

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


Вы можете увидеть иллюстрацию в git-rebase Страница справочника с пунктом "ВОССТАНОВЛЕНИЕ ОТ UPSBREAM 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 ''
  • Как уже было сказано, у вас может быть любое количество удаленных устройств для одного локального репозитория, например, если вы разветвляете репозиторий из 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

Теперь попробуйте (при условии, что удаленный "upstream" имеет ветку "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 также используется, если вы не находитесь ни на одной ветке.

Вверх по течению и толчок (Gotcha)

Взгляни на git-config(1) Страница руководства

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

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

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

Что касается Git, то любой другой репозиторий является просто удаленным.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Продолжая аналогию с рекой, ниже по течению идет вода в реке. Скоростной спуск.

Итак, если я форк чьего-то проекта, то проект, который я форкнул, будет апстримом. И моя вилка находится ниже по течению.

если кто-то форкнет мой разветвленный проект, тогда мой форк станет восходящим. И вилка моей вилки становится нисходящей.

И круговорот жизни продолжается.

ПРИМЕЧАНИЕ. Четкий урок из «движения за качество» и статистического контроля процессов состоит в том, что вмешательства, направленные на устранение проблем качества в их источнике, почти всегда являются более выгодным вложением, чем повторная работа по устранению проблем, которые можно было предотвратить. Пожалуйста, отправьте Pull requests.

Другие вопросы по тегам