Русский ▾ Topics ▾ Latest version ▾ git-pull last updated in 2.54.0

НАЗВАНИЕ

git-pull - Получение и слияние изменений из другого репозитория или локальной ветки

ОБЗОР

git pull' [<параметры>] [<репозиторий> [<спецификатор-ссылки>…​]]

ОПИСАНИЕ

Интегрировать изменения из внешнего репозитория в текущую ветку.

Сначала git pull выполняет git fetch с теми же аргументами (исключая параметры слияния), чтобы получить внешнюю ветку (ветки). Затем он решает, какую внешнюю ветку интегрировать: если вы запускаете git pull без аргументов, по умолчанию это вышестоящая для текущей ветки. Затем он интегрирует эту ветку в текущую ветку.

Существует 4 основных параметра для интеграции внешней ветки:

  1. git pull --ff-only будет выполнять только обновления "перемоткой вперёд": он завершается ошибкой, если ваша локальная ветка разошлась с внешней веткой. Это значение по умолчанию.

  2. git pull --rebase выполняет git rebase

  3. git pull --no-rebase выполняет git merge.

  4. git pull --squash выполняет git merge --squash

Вы также можете установить параметры конфигурации pull.rebase, pull.squash или pull.ff в соответствии с предпочтительным поведением.

Если во время слияния или перемещения возник конфликт слияния, который вы не хотите обрабатывать, вы можете безопасно прервать его с помощью git merge --abort или git rebase --abort.

ПАРАМЕТРЫ

<репозиторий>

«Внешний» репозиторий, из которого выполняется получение. Это может быть либо URL (см. раздел URL-АДРЕСА GIT ниже), либо имя внешнего репозитория (см. раздел ВНЕШНИЕ РЕПОЗИТОРИИ ниже).

По умолчанию используется настроенная вышестоящая для текущей ветки или origin. См. ВЫШЕСТОЯЩИЕ ВЕТКИ ниже для получения дополнительной информации о настройке вышестоящих.

<спецификатор-ссылки>

Какая ветка или другие ссылки должны быть получены и интегрированы в текущую ветку, например main в git pull origin main. По умолчанию используется настроенная вышестоящая для текущей ветки.

Это может быть ветка, метка или другая коллекция ссылок. Полный синтаксис см. в <спецификатор-ссылки> ниже в разделе "Параметры, связанные с получением", а о том, как git pull использует этот аргумент для определения того, какую внешнюю ветку интегрировать, см. в разделе ПОВЕДЕНИЕ ПО УМОЛЧАНИЮ ниже.

-q
--quiet

Это передаётся как нижележащему git-fetch для подавления отчётов во время передачи, так и нижележащему git-merge для подавления вывода во время слияния.

-v
--verbose

Передать --verbose в git-fetch и git-merge.

--recurse-submodules[=(yes|on-demand|no)]
--no-recurse-submodules

Этот параметр управляет тем, должны ли быть получены новые коммиты заполненных подмодулей и должны ли также быть обновлены рабочие каталоги активных подмодулей (см. git-fetch[1], git-config[1] и gitmodules[5]).

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

Если обновление выполняется через слияние, конфликты подмодулей разрешаются и переключаются.

Параметры, связанные со слиянием

--commit
--no-commit

Выполнить слияние и зафиксировать результат. Этот параметр можно использовать для переопределения --no-commit. Полезно только при слиянии.

С --no-commit выполнить слияние и остановиться непосредственно перед созданием коммита слияния, чтобы дать пользователю возможность проверить и дополнительно настроить результат слияния перед фиксацией.

Обратите внимание, что обновления-перемотки вперёд (fast-forward) не создают коммит слияния, и поэтому нет способа остановить такие слияния с помощью --no-commit. Таким образом, если вы хотите гарантировать, что ваша ветка не будет изменена или обновлена командой слияния, используйте --no-ff вместе с --no-commit.

--edit
-e
--no-edit

Вызвать редактор перед фиксацией успешного механического слияния, чтобы дополнительно отредактировать автоматически сгенерированное сообщение слияния, чтобы пользователь мог объяснить и обосновать слияние. Параметр --no-edit можно использовать для принятия автоматически сгенерированного сообщения (обычно это не рекомендуется).

Старые сценарии могут зависеть от исторического поведения, когда пользователю не разрешалось редактировать сообщение журнала слияния. Они увидят, что при запуске git merge открывается редактор. Чтобы упростить адаптацию таких сценариев к обновлённому поведению, в начале них можно установить переменную среды GIT_MERGE_AUTOEDIT в no.

--cleanup=<режим>

Этот параметр определяет, как сообщение слияния будет очищено перед фиксацией. Дополнительные сведения см. в git-commit[1]. Кроме того, если <режим> получит значение scissors, в случае конфликта слияния к MERGE_MSG будет добавлен разделитель scissors перед передачей механизму фиксации.

--ff-only

Обновлять до новой истории только в том случае, если нет расходящейся локальной истории. Это значение по умолчанию, когда не предоставлен метод согласования расходящихся историй (через флаги --rebase).

--ff
--no-ff

При слиянии, а не перемещении (rebase), указывает, как обрабатывается слияние, когда сливаемая история уже является потомком текущей истории. Если запрошено слияние, --ff используется по умолчанию, если только не выполняется слияние аннотированной (и, возможно, подписанной) метки, которая не хранится в своём естественном месте в иерархии refs/tags/, и в этом случае подразумевается --no-ff.

С --ff, когда возможно, разрешить слияние как перемотку вперёд (fast-forward) (только обновить указатель ветки, чтобы он соответствовал сливаемой ветке; не создавать коммит слияния). Когда это невозможно (когда сливаемая история не является потомком текущей истории), создать коммит слияния.

С --no-ff создавать коммит слияния во всех случаях, даже если слияние могло бы быть разрешено как перемотка вперёд (fast-forward).

-S[<id-ключа>]
--gpg-sign[=<id-ключа>]
--no-gpg-sign

Подписать результирующий коммит слияния с помощью GPG. Аргумент <id-ключа> необязателен и по умолчанию соответствует личности коммиттера; если указан, он должен быть прикреплён к опции без пробела. --no-gpg-sign полезен для отмены как переменной конфигурации commit.gpgSign, так и ранее указанного --gpg-sign.

--log[=<n>]
--no-log

В дополнение к именам веток заполнять сообщение журнала однострочными описаниями не более чем из <n> фактических коммитов, которые сливаются. См. также git-fmt-merge-msg[1]. Полезно только при слиянии.

С --no-log не выводить однострочные описания из фактических сливаемых коммитов.

--signoff
--no-signoff

Добавить завершитель Signed-off-by в конец сообщения коммита. Смысл этого действия зависит от проекта, с которым вы сотрудничаете. Например, это может удостоверять, что коммиттер имеет все права на то, чтобы предоставить данную работу в проект под его лицензией, или что он соглашается с каким-нибудь соглашением участника, вроде Сертификата Происхождения Разработчика (тот что используется в проектах Linux и Git см. в https://developercertificate.org). Проконсультируйтесь с документацией или руководством проекта, в который вы хотите внести свой вклад, чтобы понять, какой именно смысл эта приписка имеет в конкретном проекте.

С помощью параметра --no-signoff можно отменить параметр --signoff, указанный раннее в командной строке.

Git не имеет (и не будет иметь) переменной конфигурации для включения параметра командной строки --signoff по умолчанию; подробности см. в записи commit.signoff в gitfaq[7].

--stat
-n
--no-stat

Показывать diffstat в конце слияния. Diffstat также управляется параметром конфигурации merge.stat.

С -n или --no-stat не показывать diffstat в конце слияния.

--compact-summary

Показывать компактную сводку (compact-summary) в конце слияния.

--squash
--no-squash

Создать состояние рабочего каталога и индекса, как если бы произошло реальное слияние (за исключением информации о слиянии), но фактически не создавать коммит, не перемещать HEAD и не записывать $GIT_DIR/MERGE_HEAD (чтобы следующая команда git commit создала коммит слияния). Это позволяет вам создать один коммит поверх текущей ветки, эффект от которого будет таким же, как и от слияния другой ветки (или более в случае слияния octopus).

С --no-squash выполнить слияние и зафиксировать результат. Этот параметр можно использовать для переопределения --squash.

С --squash --commit не разрешён и приведёт к ошибке.

Полезно только при слиянии.

--verify
--no-verify

По умолчанию запускаются перехватчики (hooks) pre-merge и commit-msg. Когда указан --no-verify, они обходятся. См. также githooks[5]. Полезно только при слиянии.

-s <стратегия>
--strategy=<стратегия>

Использовать указанную стратегию слияния; может быть указана более одного раза для задания порядка их применения. Если опция -s отсутствует, используется встроенный список стратегий (ort при слиянии одной головы, octopus в противном случае).

-X <параметр>
--strategy-option=<параметр>

Передать параметр, специфичный для стратегии слияния, самой стратегии слияния.

--verify-signatures
--no-verify-signatures

Проверить, что верхушка (tip) сливаемой побочной ветки подписана действительным ключом, т.е. ключом, имеющим действительный uid: в модели доверия по умолчанию это означает, что ключ подписи был подписан доверенным ключом. Если верхушка побочной ветки не подписана действительным ключом, слияние прерывается.

Полезно только при слиянии.

--summary
--no-summary

Синонимы для --stat и --no-stat; они устарели и будут удалены в будущем.

--autostash
--no-autostash

Автоматически создать временную запись в тайнике (stash) перед началом операции, записать её в ссылку MERGE_AUTOSTASH и применить её после завершения операции. Это означает, что вы можете выполнять операцию на грязном рабочем каталоге. Однако используйте с осторожностью: финальное применение тайника после успешного слияния может привести к нетривиальным конфликтам.

--allow-unrelated-histories

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

Полезно только при слиянии.

-r
--rebase[=(true|merges|false|interactive)]
true

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

merges

перемещение с использованием git rebase --rebase-merges, чтобы локальные коммиты слияния были включены в перемещение (подробности см. в git-rebase[1]).

false

слить вышестоящую ветку в текущую ветку.

interactive

включить интерактивный режим перемещения.

См. pull.rebase, branch.<имя>.rebase и branch.autoSetupRebase в git-config[1], если вы хотите, чтобы git pull всегда использовал --rebase вместо слияния.

+

Note
Это потенциально опасный режим работы. Он переписывает историю, что не сулит ничего хорошего, если вы уже опубликовали эту историю. Не используйте этот параметр, если вы внимательно не прочитали git-rebase[1].
--no-rebase

Это краткая форма для --rebase=false.

Параметры, связанные с извлечением изменений

--all
--no-all

Загрузить все удалённые репозитории, за исключением тех, для которых установлена конфигурационная переменная remote.<имя>.skipFetchAll. Это переопределяет конфигурационную переменную fetch.all.

-a
--append

Добавляет имена ссылок и объектов загруженных ссылок к существующему содержимому .git/FETCH_HEAD. Без этой опции старые данные в .git/FETCH_HEAD будут перезаписаны.

--atomic

Использовать атомарную транзакцию для обновления локальных ссылок. Либо все ссылки обновляются, либо при ошибке никакие ссылки не обновляются.

--depth=<глубина>

Ограничивает загрузку указанным количеством коммитов от конца истории каждой удалённой ветки. При загрузке в мелкий (shallow) репозиторий, созданный git clone с опцией --depth=<глубина> (см. git-clone[1]), углубляет или укорачивает историю до указанного количества коммитов. Теги для углублённых коммитов не загружаются.

--deepen=<глубина>

Аналогично --depth, но указывает количество коммитов от текущей границы мелкого репозитория, а не от конца истории каждой удалённой ветки.

--shallow-since=<дата>

Углубляет или укорачивает историю мелкого репозитория, чтобы включить все достижимые коммиты после <даты>.

--shallow-exclude=<ссылка>

Углубляет или укорачивает историю мелкого репозитория, чтобы исключить коммиты, достижимые из указанной удалённой ветки или тега. Эту опцию можно указать несколько раз.

--unshallow

Если исходный репозиторий полный, преобразует мелкий репозиторий в полный, удаляя все ограничения, накладываемые мелкими репозиториями.

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

--update-shallow

По умолчанию при загрузке из мелкого репозитория git fetch отклоняет ссылки, требующие обновления .git/shallow. Эта опция обновляет .git/shallow и принимает такие ссылки.

--negotiation-tip=(<коммит>|<шаблон-glob>)

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

Эту опцию можно указать несколько раз; в этом случае Git будет сообщать о коммитах, достижимых из любого из указанных коммитов.

Аргументом этой опции может быть glob для имён ссылок, ссылка или (возможно, сокращённый) SHA-1 коммита. Указание glob эквивалентно указанию этой опции несколько раз, по одному разу для каждого совпадающего имени ссылки.

См. также конфигурационные переменные fetch.negotiationAlgorithm и push.negotiate, описанные в git-config[1], и опцию --negotiate-only ниже.

--negotiate-only

Не загружает ничего с сервера, а вместо этого печатает предков указанных аргументов --negotiation-tip=, которые есть у нас общего с сервером.

Несовместимо с --recurse-submodules=(yes|on-demand). Внутренне используется для реализации опции push.negotiate, см. git-config[1].

--dry-run

Показать, что будет сделано, без внесения изменений.

--porcelain

Выводит результат в стандартный вывод в удобном для разбора скриптами формате. Подробности см. в разделе OUTPUT в git-fetch[1].

Несовместимо с --recurse-submodules=(yes|on-demand) и имеет приоритет над опцией конфигурации fetch.output.

--filter=<спецификатор-фильтра>

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

Если используется --filter=auto, спецификация фильтра определяется автоматически путём объединения спецификаций фильтра, объявленных сервером для внешних репозиториев-промисоров, которые принимает клиент (см. gitprotocol-v2[5] и параметр конфигурации promisor.acceptFromServer в git-config[1]).

Подробности обо всех других доступных спецификациях фильтров см. в параметре --filter=<спецификатор-фильтра> в git-rev-list[1].

Например, --filter=blob:none отфильтрует все blob-объекты (содержимое файлов), пока они не понадобятся Git. Кроме того, --filter=blob:limit=<размер> отфильтрует все blob-объекты размером не менее <размер>.

-f
--force

Когда git fetch используется с рефспеком <src>:<dst>, он может отказаться обновлять локальную ветку, как обсуждается в части <рефспек> документации git-fetch[1]. Этот параметр отменяет эту проверку.

-k
--keep

Сохранять загруженный pack-файл.

--prefetch

Изменяет настроенный рефспек, чтобы поместить все ссылки в пространство имён refs/prefetch/. См. задачу prefetch в git-maintenance[1].

-p
--prune

Перед загрузкой удаляет все удалённые отслеживающие ссылки, которые больше не существуют на удалённом репозитории. Теги не подлежат обрезке, если они загружаются только из-за автоматического отслеживания тегов по умолчанию или из-за опции --tags. Однако если теги загружаются из-за явного рефспекта (либо в командной строке, либо в конфигурации удалённого репозитория, например, если удалённый репозиторий был клонирован с опцией --mirror), то они также подлежат обрезке. Указание --prune-tags является сокращением для указания рефспекта тега.

--no-tags

По умолчанию теги, указывающие на объекты, загружаемые из удалённого репозитория, загружаются и сохраняются локально. Эта опция отключает это автоматическое отслеживание тегов. Поведение по умолчанию для удалённого репозитория может быть задано настройкой remote.<имя>.tagOpt. См. git-config[1].

--refmap=<спецификатор-ссылки>

При загрузке ссылок, перечисленных в командной строке, использует указанный рефспект (можно указать несколько раз) для отображения ссылок на удалённые отслеживающие ветки вместо значений конфигурационных переменных remote.<имя>.fetch для удалённого репозитория. Предоставление пустого <рефспекта> для опции --refmap заставляет Git игнорировать настроенные рефспекты и полностью полагаться на рефспекты, предоставленные в качестве аргументов командной строки. Подробности см. в разделе "Настроенные удалённые отслеживающие ветки".

-t
--tags

Загружает все теги из удалённого репозитория (т.е. загружает удалённые теги refs/tags/* в локальные теги с теми же именами), в дополнение ко всему, что было бы загружено иначе. Использование этой опции само по себе не подвергает теги обрезке, даже если используется --prune (хотя теги всё равно могут быть обрезаны, если они также являются целью явного рефспекта; см. --prune).

-j <n>
--jobs=<n>

Параллелизует все формы загрузки до <n> заданий одновременно.

Значение 0 приведёт к использованию некоторого разумного значения по умолчанию.

Если указана опция --multiple, разные удалённые репозитории будут загружаться параллельно. Если загружается несколько подмодулей, они также будут загружаться параллельно. Чтобы управлять ими независимо, используйте настройки конфигурации fetch.parallel и submodule.fetchJobs (см. git-config[1]).

Обычно параллельная рекурсивная и многопользовательская загрузка будет быстрее. По умолчанию загрузка выполняется последовательно, а не параллельно.

--set-upstream

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

--upload-pack <пакет-отправки>

Когда указано и репозиторий для извлечения обрабатывается git fetch-pack, --exec=<пакет-отправки> передаётся команде для указания нестандартного пути для команды, выполняемой на другом конце.

--progress

Прогресс по умолчанию направляется в стандартный поток ошибок, если этот поток подключён к терминалу, если не указан параметр -q. Этот флаг принудительно включает отображение прогресса, даже если стандартный поток ошибок не направлен на терминал.

-o <параметр>
--server-option=<параметры>

Передать заданную строку на сервер при обмене данными по протоколу версии 2. Заданная строка не должна содержать символы NUL или LF. Обработка сервером параметров сервера, включая неизвестные, зависит от конкретного сервера. Когда указано несколько --server-option=<параметр>, все они отправляются на другую сторону в порядке, перечисленном в командной строке. Если в командной строке не указано ни одной --server-option=<параметр>, вместо этого используются значения переменной конфигурации remote.<имя>.serverOption.

--show-forced-updates

По умолчанию git проверяет, была ли ветка принудительно обновлена во время загрузки. Это можно отключить через fetch.showForcedUpdates, но опция --show-forced-updates гарантирует выполнение этой проверки. См. git-config[1].

--no-show-forced-updates

По умолчанию git проверяет, была ли ветка принудительно обновлена во время загрузки. Передайте --no-show-forced-updates или установите fetch.showForcedUpdates в false, чтобы пропустить эту проверку по соображениям производительности. Если используется во время git-pull, опция --ff-only всё равно будет проверять принудительные обновления перед попыткой быстрого перемотки. См. git-config[1].

-4
--ipv4

Использовать только IPv4 адреса, игнорируя IPv6 адреса.

-6
--ipv6

Использовать только IPv6 адреса, игнорируя адреса IPv4.

<репозиторий>

«Внешний» (remote) репозиторий, являющийся источником операции получения (fetch) или извлечения (pull). Этот параметр может быть либо URL-адресом (см. раздел URL-АДРЕСА GIT ниже), либо именем внешнего репозитория (см. раздел ВНЕШНИЕ РЕПОЗИТОРИИ ниже).

<спецификатор-ссылки>

Указывает, какие ссылки получать (fetch) и какие локальные ссылки обновлять. Если в командной строке нет <спецификатор-ссылки>, получаемые ссылки считываются из переменных remote.<репозиторий>.fetch (см. раздел «НАСТРОЕННЫЕ ОТСЛЕЖИВАЕМЫЕ ВНЕШНИЕ ВЕТКИ» в git-fetch[1]).

Формат параметра <спецификатор-ссылки>: необязательный плюс +, затем источник <источник>, затем двоеточие :, затем назначение <назначение>. Двоеточие можно опустить, если <назначение> пусто. <источник> обычно является ссылкой или glob-шаблоном с одним символом *, используемым для сопоставления набора ссылок, но также может быть полностью указанным шестнадцатеричным именем объекта.

<спецификатор-ссылки> может содержать * в своём <источник> для указания простого сопоставления с образцом. Такой спецификатор ссылки функционирует как glob-шаблон, соответствующий любой ссылке, подходящей под образец. Шаблонный <спецификатор-ссылки> должен содержать один и только один * как в <источник>, так и в <назначение>. Он будет сопоставлять ссылки с назначением, заменяя * содержимым, сопоставленным из источника.

Если спецификатор ссылки имеет префикс ^, он интерпретируется как отрицательный спецификатор ссылки. Такой спецификатор ссылки вместо указания того, какие ссылки получать или какие локальные ссылки обновлять, указывает ссылки для исключения. Ссылка будет считаться соответствующей, если она соответствует хотя бы одному положительному спецификатору ссылки и не соответствует ни одному отрицательному спецификатору ссылки. Отрицательные спецификаторы ссылок могут быть полезны для ограничения области действия шаблонного спецификатора ссылки, чтобы он не включал определённые ссылки. Отрицательные спецификаторы ссылок сами могут быть шаблонными спецификаторами ссылок. Однако они могут содержать только <источник> и не указывают <назначение>. Полностью указанные шестнадцатеричные имена объектов также не поддерживаются.

tag <метка> означает то же, что и refs/tags/<метка>:refs/tags/<метка>; это запрашивает получение всего вплоть до указанной метки.

Получается внешняя ссылка, соответствующая <источник>, и если <назначение> не является пустой строкой, предпринимается попытка обновить локальную ссылку, соответствующую ей.

Разрешено ли такое обновление без --force, зависит от пространства имён ссылок, в которое оно извлекается, типа получаемого объекта и того, считается ли обновление перемоткой вперёд (fast-forward). Как правило, для получения (fetch) применяются те же правила, что и для отправки (push); узнать, что это за правила, можно в разделе <спецификатор-ссылки>... git-push[1]. Исключения из этих правил, характерные для git fetch, отмечены ниже.

До версии Git 2.20, в отличие от отправки с помощью git-push[1], любые обновления refs/tags/* принимались без + в спецификаторе ссылки (или --force). При получении мы без разбора считали все обновления меток из внешнего репозитория принудительными получениями. Начиная с версии Git 2.20, получение для обновления refs/tags/* работает так же, как и при отправке. Т.е. любые обновления будут отклоняться без + в спецификаторе ссылки (или --force).

В отличие от отправки с помощью git-push[1], любые обновления за пределами refs/{tags,heads}/* будут приниматься без + в спецификаторе ссылки (или --force), будь то замена, например, объекта-дерева на blob-объект или коммита на другой коммит, у которого предыдущий коммит не является предком, и т.д.

В отличие от отправки с помощью git-push[1], не существует конфигурации, которая изменяла бы эти правила, и нет ничего похожего на перехватчик (hook) pre-fetch, аналогичный перехватчику pre-receive.

Как и при отправке с помощью git-push[1], все описанные выше правила относительно того, что не разрешено в качестве обновления, можно отменить, добавив необязательный начальный символ + к спецификатору ссылки (или используя параметр командной строки --force). Единственным исключением является то, что никакое принуждение не заставит пространство имён refs/heads/* принять объект, не являющийся коммитом.

Note
Если известно, что внешняя ветка, которую вы хотите получить, регулярно перематывается назад и перемещается (rebase), ожидается, что её новая верхушка (tip) не будет потомком её предыдущей верхушки (как сохранено в вашей отслеживаемой внешней ветке при последнем получении). Вам следует использовать знак +, чтобы указать, что для таких веток потребуются обновления, не являющиеся перемоткой вперёд. Невозможно определить или объявить, что ветка будет доступна в репозитории с таким поведением; пользователь, выполняющий извлечение (pull), просто должен знать, что это ожидаемый шаблон использования для данной ветки.
Note
Существует разница между перечислением нескольких <спецификатор-ссылки> непосредственно в командной строке git pull и наличием нескольких записей remote.<репозиторий>.fetch в вашей конфигурации для <репозиторий> с последующим запуском команды git pull без каких-либо явных параметров <спецификатор-ссылки>. <Спецификатор-ссылки>, явно перечисленные в командной строке, всегда сливаются (merge) в текущую ветку после получения (fetch). Другими словами, если вы перечислите более одной внешней ссылки, git pull создаст слияние Octopus (восьминог). С другой стороны, если вы не перечислите ни одного явного параметра <спецификатор-ссылки> в командной строке, git pull получит все <спецификатор-ссылки>, которые найдёт в конфигурации remote.<репозиторий>.fetch, и сольёт только первый найденный <спецификатор-ссылки> в текущую ветку. Это связано с тем, что создание Octopus из внешних ссылок выполняется редко, в то время как отслеживание нескольких внешних голов (heads) за один раз путём получения более одной ссылки часто бывает полезно.

URL-АДРЕСА GIT

В целом, URL-адреса содержат информацию о транспортном протоколе, адресе удалённого сервера и пути к репозиторию. В зависимости от транспортного протокола, некоторые из этих элементов могут отсутствовать.

Git поддерживает следующие протоколы: ssh, git, http и https (кроме того, ftp и ftps могут быть использованы для извлечения из репозиториев, но это неэффективно и является устаревшей (deprecated) возможностью; не используйте эти протоколы).

Родной транспорт (т.е. адреса вида git://) не имеет аутентификации и должен использоваться с осторожностью в незащищённых сетях.

Для этих протоколов может использоваться следующий синтаксис:

  • ssh://[<пользователь>@]<хост>[:<порт>]/<путь-к-репозиторию-git>

  • git://<хост>[:<порт>]/<путь-к-репозиторию-git>

  • http[s]://<хост>[:<порт>]/<путь-к-репозиторию-git>

  • ftp[s]://<хост>[:<порт>]/<путь-к-репозиторию-git>

В качестве альтернативы для протокола ssh можно также использовать scp-подобный синтаксис:

  • [<пользователь>@]<хост>:/<путь-к-репозиторию-git>

Этот синтаксис распознаётся только в том случае, если перед первым двоеточием нет слэшей. Это позволяет отличить его от локального пути, который содержит двоеточие. Например, локальный путь foo:bar можно записан как ./foo:bar или как абсолютный путь, дабы он не был бы ошибочно интерпретирован как ssh-адреса.

Кроме того протоколы ssh и git поддерживают расширение ~<имени-пользователя>:

  • ssh://[<пользователь>@]<хост>[:<порт>]/~<имя-пользователя>/<путь-к-репозиторию-git>

  • git://<хост>[:<порт>]/~<имя-пользователя>/<путь-к-репозиторию-git>

  • [<пользователь>@]<хост>:/~<имя-пользователя>/<путь-к-репозиторию-git>

Для локальных репозиториев, для которых поддержка у Git также родная, могут использоваться следующие варианты синтаксиса:

  • /путь/к/репозиторию.git/

  • file:///путь/к/репозиторию.git/

Эти два синтаксиса по большей части эквивалентны, кроме как при клонировании; в этом случае первый подразумевает параметр --local. См. подробности в git-clone[1].

git clone, git fetch и git pull, но не git push, также примут сформированный соответствующим образом pack-файл. См. git-bundle[1].

Когда Git не знает, как работать с определённым транспортным протоколом, он пытается использовать вспомогательную программу remote-<транспорт>, помощник работы со внешним репозиторием, если таковая существует. Для явного запроса такого помощника можно использовать следующий синтаксис:

  • <транспорт>::<адрес>

где <адрес> может быть путём, сервером и путём, или произвольной URL-подобной строкой, которая распознаётся конкретным помощником работы с удалённым репозиторием. См. подробности в gitremote-helpers[7].

Если у вас много внешних репозиториев с похожими друг на друга именами, и вы хотите использовать для них свой собственный формат (так, что бы использовать свои собственные удобные вам URL-адреса, которые будут автоматически преобразовываться в те, которые работают), вы можете добавить раздел конфигурации следующего вида:

	[url "<настоящая-база-url>"]
		insteadOf = <другая-база-url>

Например, при такой конфигурации:

	[url "git://git.host.xz/"]
		insteadOf = host.xz:/path/to/
		insteadOf = work:

URL-адрес вида "work:repo.git" или "host.xz:/path/to/repo.git", будет преобразовываться в любом контексте, в котором ожидается URL-адрес, в "git.host.xz/repo.git".

Если вы хотите, чтобы URL-адреса преобразовывались только при отправки изменений во внешний репозиторий, вы можете добавить раздел конфигурации следующего вида:

	[url "<настоящая-база-url>"]
		pushInsteadOf = <другая-база-url>

Например, при такой конфигурации:

	[url "ssh://example.org/"]
		pushInsteadOf = git://example.org/

URL-адрес вида "git://example.org/path/to/repo.git", будет преобразован в "ssh://example.org/path/to/repo.git" для отправки изменений, но при получении изменений будет по-прежнему использоваться оригинальный URL-адрес.

ВНЕШНИЕ РЕПОЗИТОРИИ

Имя одного из следующих может использоваться вместо URL в качестве аргумента <репозиторий>:

  • внешний репозиторий в файле конфигурации Git: $GIT_DIR/config,

  • файл в каталоге $GIT_DIR/remotes или

  • файл в каталоге $GIT_DIR/branches.

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

Именованный внешний репозиторий в файле конфигурации

Вы можете указать имя внешнего репозитория, который вы ранее настроили с помощью git-remote[1], git-config[1] или даже путём ручного редактирования файла $GIT_DIR/config. URL этого внешнего репозитория будет использоваться для доступа к репозиторию. Спецификатор ссылки этого внешнего репозитория будет использоваться по умолчанию, если вы не укажете спецификатор ссылки в командной строке. Запись в файле конфигурации будет выглядеть так:

	[remote "<имя>"]
		url = <URL>
		pushurl = <URL-отправки>
		push = <спецификатор-ссылки>
		fetch = <спецификатор-ссылки>

<URL-отправки> используется только для отправки. Он необязателен и по умолчанию равен <URL>. Отправка во внешний репозиторий влияет на все определённые pushurl-ы или все определённые url-ы, если pushurl-ы не определены. Однако получение будет выполняться только из первого определённого url, если определено несколько url-ов.

Именованный файл в $GIT_DIR/remotes

Вы можете указать имя файла в $GIT_DIR/remotes. URL в этом файле будет использоваться для доступа к репозиторию. Спецификатор ссылки в этом файле будет использоваться по умолчанию, если вы не укажете спецификатор ссылки в командной строке. Этот файл должен иметь следующий формат:

	URL: один из вышеуказанных форматов URL
	Push: <спецификатор-ссылки>
	Pull: <спецификатор-ссылки>

Строки Push: используются git push, а строки Pull: используются git pull и git fetch. Для дополнительных сопоставлений веток может быть указано несколько строк Push: и Pull:.

Именованный файл в $GIT_DIR/branches

Вы можете указать имя файла в $GIT_DIR/branches. URL в этом файле будет использоваться для доступа к репозиторию. Этот файл должен иметь следующий формат:

	<URL>#<голова>

<URL> обязателен; #<голова> необязателен.

В зависимости от операции git будет использовать один из следующих спецификаторов ссылок, если вы не укажете его в командной строке. <ветка> — это имя этого файла в $GIT_DIR/branches, а <голова> по умолчанию равна master.

git fetch использует:

	refs/heads/<голова>:refs/heads/<ветка>

git push использует:

	HEAD:refs/heads/<голова>

ВЫШЕСТОЯЩИЕ ВЕТКИ

Ветки в Git могут опционально иметь вышестоящую внешнюю ветку. Git по умолчанию использует вышестоящую ветку для операций с внешними репозиториями, например:

  • Это значение по умолчанию для git pull или git fetch без аргументов.

  • Это значение по умолчанию для git push без аргументов, с некоторыми исключениями. Например, вы можете использовать параметр branch.<имя>.pushRemote, чтобы отправлять в другой внешний репозиторий, отличный от того, из которого вы получаете, и по умолчанию с push.default=simple настраиваемая вами вышестоящая ветка должна иметь то же имя.

  • Различные команды, включая git checkout и git status, покажут вам, сколько коммитов было добавлено в вашу текущую ветку и вышестоящую с момента ответвления от неё, например: "Ваша ветка и origin/main разошлись, и имеют 2 и 3 разных коммита соответственно".

Вышестоящая ветка хранится в .git/config в полях "remote" и "merge". Например, если вышестоящей для main является origin/main:

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

Вы можете явно установить вышестоящую ветку с помощью git push --set-upstream <внешний-репозиторий> <ветка>, но Git часто автоматически устанавливает вышестоящую ветку за вас, например:

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

  • Если у вас установлен параметр конфигурации push.autoSetupRemote, git push автоматически установит вышестоящую ветку при первой отправке ветки.

  • Переключение на отслеживаемую внешнюю ветку с помощью git checkout <ветка> автоматически создаст локальную ветку с этим именем и установит вышестоящую ветку на внешнюю ветку.

Note
Вышестоящие ветки иногда называют "информацией об отслеживании", как в выражении "установить информацию об отслеживании ветки".

СТРАТЕГИИ СЛИЯНИЯ

Механизм слияния (команды git merge и git pull) позволяет выбирать внутренние стратегии слияния с помощью параметра -s. Некоторые стратегии также могут принимать свои собственные параметры, которые можно передать, указав аргументы -X<параметр> для git merge и/или git pull.

ort

Это стратегия слияния по умолчанию при получении или слиянии одной ветки. Эта стратегия может разрешить только две головы с использованием алгоритма трёхходового слияния. Когда существует более одного общего предка, который может быть использован для трёхходового слияния, она создаёт слитое дерево общих предков и использует его в качестве эталонного дерева для трёхходового слияния. Сообщается, что это приводит к уменьшению количества конфликтов слияния без неправильных слияний по результатам тестов, проведённых на реальных коммитах слияния из истории разработки ядра Linux 2.6. Кроме того, эта стратегия может обнаруживать и обрабатывать слияния, включающие переименования. Она не использует обнаруженные копии. Название этого алгоритма — аббревиатура ("Ostensibly Recursive’s Twin") и возникло из-за того, что он был написан как замена предыдущему алгоритму по умолчанию, recursive.

В случае, когда путь является подмодулем, если коммит подмодуля, используемый на одной стороне слияния, является потомком коммита подмодуля, используемого на другой стороне слияния, Git пытается выполнить перемотку вперёд к потомку. В противном случае Git будет рассматривать этот случай как конфликт, предлагая в качестве разрешения коммит подмодуля, который является потомком конфликтующих, если таковой существует.

Стратегия ort может принимать следующие параметры:

ours

Этот параметр заставляет конфликтующие блоки автоматически разрешаться чисто в пользу нашей версии. Изменения из другого дерева, которые не конфликтуют с нашей стороной, отражаются в результате слияния. Для двоичного файла всё содержимое берётся с нашей стороны.

Это не следует путать со стратегией слияния ours, которая вообще даже не смотрит на то, что содержит другое дерево. Она отбрасывает всё, что сделало другое дерево, объявляя, что наша история содержит всё, что в нём произошло.

theirs

Это противоположность ours; обратите внимание, что, в отличие от ours, нет стратегии слияния theirs, с которой можно было бы перепутать этот параметр слияния.

ignore-space-change
ignore-all-space
ignore-space-at-eol
ignore-cr-at-eol

Обрабатывает строки с указанным типом изменения пробелов как неизменённые для целей трёхходового слияния. Изменения пробелов, смешанные с другими изменениями в строке, не игнорируются. См. также git-diff[1] -b, -w, --ignore-space-at-eol и --ignore-cr-at-eol.

  • Если их версия вносит только изменения пробелов в строку, используется наша версия;

  • Если наша версия вносит изменения пробелов, но их версия включает существенное изменение, используется их версия;

  • В противном случае слияние продолжается обычным образом.

renormalize

Это выполняет виртуальное переключение и фиксацию всех трёх стадий любого файла, которому требуется трёхходовое слияние. Этот параметр предназначен для использования при слиянии веток с разными фильтрами очистки или правилами нормализации концов строк. Подробности см. в разделе "Слияние веток с различными атрибутами фиксации/переключения" в gitattributes[5].

no-renormalize

Отключает параметр renormalize. Это переопределяет переменную конфигурации merge.renormalize.

find-renames[=<n>]

Включает обнаружение переименований, опционально устанавливая порог схожести. Это поведение по умолчанию. Это переопределяет переменную конфигурации merge.renames. См. также git-diff[1] --find-renames.

rename-threshold=<число>

Устаревший синоним для find-renames=<число>.

no-renames

Отключает обнаружение переименований. Это переопределяет переменную конфигурации merge.renames. См. также git-diff[1] --no-renames.

histogram

Устаревший синоним для diff-algorithm=histogram.

patience

Устаревший синоним для diff-algorithm=patience.

diff-algorithm=(histogram|minimal|myers|patience)

Использовать другой алгоритм сравнения при слиянии, что может помочь избежать неправильных слияний, возникающих из-за неважных совпадающих строк (например, скобок из разных функций). См. также git-diff[1] --diff-algorithm. Обратите внимание, что ort по умолчанию использует diff-algorithm=histogram, в то время как обычные сравнения в настоящее время по умолчанию используют настройку конфигурации diff.algorithm.

subtree[=<путь>]

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

recursive

Теперь это синоним для ort. Это была альтернативная реализация до v2.49.0, но в v2.50.0 была перенаправлена на ort. Предыдущая рекурсивная стратегия была стратегией по умолчанию для разрешения двух голов начиная с Git v0.99.9k до v2.33.0.

resolve

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

octopus

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

ours

Эта стратегия разрешает любое количество голов, но результирующее дерево слияния всегда является деревом головы текущей ветки, фактически игнорируя все изменения из всех других веток. Она предназначена для замены старой истории разработки побочных веток. Обратите внимание, что это отличается от параметра -Xours для стратегии слияния ort.

subtree

Это модифицированная стратегия ort. При слиянии деревьев A и B, если B соответствует поддереву A, B сначала настраивается в соответствии со структурой дерева A, вместо того чтобы читать деревья на одном уровне. Эта настройка также выполняется для дерева общего предка.

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

ПОВЕДЕНИЕ ПО УМОЛЧАНИЮ

Часто люди используют git pull без указания каких-либо параметров. Традиционно это было эквивалентно git pull origin. Однако, когда присутствует конфигурация branch.<имя>.remote, а вы находитесь на ветке <имя>, это значение используется вместо origin.

Чтобы определить, какой URL использовать для получения, используется значение конфигурации remote.<origin>.url, и если такой переменной нет, используется значение в строке URL: в $GIT_DIR/remotes/<origin>.

Чтобы определить, какие внешние ветки получать (и опционально сохранять в отслеживаемых внешних ветках), когда команда запускается без параметров спецификатора ссылки в командной строке, используются значения переменной конфигурации remote.<origin>.fetch, а если их нет, используется $GIT_DIR/remotes/<origin> и используются его строки Pull:. В дополнение к форматам спецификаторов ссылок, описанным в разделе ПАРАМЕТРЫ, вы можете иметь спецификатор ссылки с подстановочными знаками, который выглядит так:

refs/heads/*:refs/remotes/origin/*

Спецификатор ссылки с подстановочными знаками должен иметь непустую правую часть (т.е. должен сохранять полученное в отслеживаемых внешних ветках), и его левая и правая части должны заканчиваться на /*. Вышеуказанное указывает, что все внешние ветки отслеживаются с использованием отслеживаемых внешних веток в иерархии refs/remotes/origin/ под тем же именем.

Правило определения того, какую внешнюю ветку сливать после получения, довольно сложное, чтобы не нарушить обратную совместимость.

Если явные спецификаторы ссылок были указаны в командной строке git pull, все они сливаются.

Если в командной строке не был указан спецификатор ссылки, то git pull использует спецификатор ссылки из конфигурации или $GIT_DIR/remotes/<origin>. В таких случаях применяются следующие правила:

  1. Если существует конфигурация branch.<имя>.merge для текущей ветки <имя>, то это имя ветки на внешнем сайте, которая сливается.

  2. Если спецификатор ссылки содержит подстановочные знаки, ничего не сливается.

  3. В противном случае сливается внешняя ветка первого спецификатора ссылки.

ПРИМЕРЫ

  • Обновить отслеживаемые внешние ветки для репозитория, из которого вы клонировали, затем слить одну из них в вашу текущую ветку:

    $ git pull
    $ git pull origin

    Обычно сливаемая ветка — это HEAD внешнего репозитория, но выбор определяется параметрами branch.<имя>.remote и branch.<имя>.merge; подробности см. в git-config[1].

  • Слить в текущую ветку внешнюю ветку next:

    $ git pull origin next

    Это оставляет копию next временно в FETCH_HEAD и обновляет отслеживаемую внешнюю ветку origin/next. То же самое можно сделать, вызвав fetch и merge:

    $ git fetch origin
    $ git merge origin/next

Если вы попробовали выполнить pull, который привёл к сложным конфликтам, и хотите начать заново, вы можете восстановиться с помощью git reset.

ЗАЩИТА

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

Известные векторы атак следующие:

  1. Жертва отправляет строки «have», рекламируя идентификаторы объектов, которые у неё есть и которые явно не предназначены для общего доступа, но могут использоваться для оптимизации передачи, если они также есть у участника. Злоумышленник выбирает идентификатор объекта X для кражи и отправляет ссылку на X, но не обязан отправлять содержимое X, потому что оно уже есть у жертвы. Теперь жертва считает, что у злоумышленника есть X, и позже отправляет содержимое X обратно злоумышленнику. (Эту атаку проще всего выполнить клиенту на сервере, создав ссылку на X в пространстве имён, к которому у клиента есть доступ, а затем получив её. Наиболее вероятный способ для сервера выполнить её на клиенте — «слить» X в публичную ветку и надеяться, что пользователь выполнит дополнительную работу в этой ветке и отправит её обратно на сервер, не заметив слияния.)

  2. Как и в №1, злоумышленник выбирает идентификатор объекта X для кражи. Жертва отправляет объект Y, который у злоумышленника уже есть, а злоумышленник ложно заявляет, что у него есть X, а Y нет, поэтому жертва отправляет Y как дельту относительно X. Дельта раскрывает злоумышленнику области X, похожие на Y.

ОШИБКИ

Использование --recurse-submodules в настоящее время может получать только новые коммиты в уже переключённых подмодулях. Когда, например, вышестоящая ветка добавляет новый подмодуль в только что полученные коммиты суперпроекта, сам подмодуль не может быть получен, что делает невозможным переключение этого подмодуля позже без повторного выполнения fetch. Ожидается, что это будет исправлено в будущей версии Git.

GIT

Является частью пакета git[1]