Spec-Zone.ru › Git

git-push

Название

git-push — обновление удалённых ссылок вместе со связанными объектами

Краткое описание

git push [--all | --branches | --mirror | --tags] [--follow-tags] [--atomic] [-n | --dry-run] [--receive-pack=<git-receive-pack>]
         [--repo=<repository>] [-f | --force] [-d | --delete] [--prune] [-q | --quiet] [-v | --verbose]
         [-u | --set-upstream] [-o <string> | --push-option=<string>]
         [--[no-]signed | --signed=(true|false|if-asked)]
         [--force-with-lease[=<refname>[:<expect>]] [--force-if-includes]]
         [--no-verify] [<repository> [<refspec>…​]]

Описание

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

Самый простой способ отправить изменения — git push <remote> <branch>. git push origin main отправит локальную ветку main в ветку main на удалённом репозитории с именем origin.

Также можно отправлять изменения сразу в несколько удалённых репозиториев, используя группу удалённых репозиториев. Группа удалённых репозиториев — это именованный список удалённых репозиториев, заданный с помощью remotes.<name> в конфигурации Git:

$ git config remotes.all-remotes "origin gitlab backup"

Затем команда git push all-remotes поочерёдно отправит изменения в origin, gitlab и backup, как если бы вы выполнили git push отдельно для каждого из них. Изменения отправляются в каждый удалённый репозиторий независимо, с использованием его собственной конфигурации сопоставления для отправки. В файле конфигурации есть запись remotes.<group>. (См. git-config[1]).

Аргумент <repository> по умолчанию соответствует вышестоящему репозиторию текущей ветки или origin, если вышестоящий репозиторий не настроен.

Чтобы определить, какие ветки, теги или другие ссылки отправлять, Git использует (в порядке приоритета):

  1. Аргументы <refspec> (например, main в git push origin main) или параметры --all, --mirror или --tags

  2. Конфигурацию remote.<name>.push для репозитория, в который отправляются изменения

  3. Конфигурацию push.default. По умолчанию используется значение push.default=simple, при котором изменения отправляются в ветку с тем же именем, что и текущая ветка. Подробнее о push.default см. в разделе КОНФИГУРАЦИЯ ниже.

Команда git push может завершиться с ошибкой, если для текущей ветки не задан вышестоящий репозиторий. Это зависит от значения параметра push.default. Подробнее о настройке и использовании вышестоящих репозиториев см. в разделе ВЫШЕСТОЯЩИЕ ВЕТКИ ниже.

Настроив в репозитории hooks, можно добиться интересных результатов при каждой отправке изменений в него. См. документацию для git-receive-pack[1].

Параметры

<repository>

«Удалённый» репозиторий, являющийся назначением операции отправки изменений. Этот параметр может быть URL-адресом (см. раздел URL-АДРЕСА GIT ниже), именем удалённого репозитория (см. раздел УДАЛЁННЫЕ РЕПОЗИТОРИИ ниже) или именем группы удалённых репозиториев (см. раздел ГРУППЫ УДАЛЁННЫХ РЕПОЗИТОРИЕВ ниже).

<refspec>...

Указывает, какую ссылку назначения обновить каким исходным объектом.

Формат спецификации ссылки: [+]<src>[:<dst>], например main, main:other или HEAD^:refs/heads/main.

<src> часто представляет собой имя локальной ветки, которую нужно отправить, но может быть любым произвольным «выражением SHA-1» (см. gitrevisions[7]).

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

+ является необязательным и выполняет ту же функцию, что и --force.

Спецификацию ссылки можно записать в полном виде (например, refs/heads/main:refs/heads/main), задающем точные источник и назначение, или в сокращённом виде (например, main или main:other). Ниже приведены правила раскрытия спецификаций ссылок, а также различные другие специальные формы спецификаций ссылок:

  • <src> без :<dst> означает обновление той же ссылки, что и <src>, если только конфигурация remote.<repository>.push не задаёт другое значение <dst>. Например, если main — это ветка, то спецификация ссылки main раскрывается в main:refs/heads/main.

  • Если <dst> однозначно указывает на ссылку в удалённом репозитории <repository>, он раскрывается в эту ссылку. Например, если v1.0 — это тег в удалённом репозитории, то HEAD:v1.0 раскрывается в HEAD:refs/tags/v1.0.

  • Если <src> разрешается в ссылку, начинающуюся с refs/heads/ или refs/tags/, этот префикс добавляется к <dst>. Например, если main — это ветка, то main:other раскрывается в main:refs/heads/other

  • Специальная спецификация ссылки : (или +:, разрешающая обновления, не являющиеся перемоткой вперёд) указывает Git отправить «совпадающие» ветки: для каждой ветки, существующей в локальном репозитории, удалённая ветка обновляется, если на удалённой стороне уже существует ветка с таким же именем.

  • <src> может содержать * для указания простого сопоставления с шаблоном. Это работает как шаблон glob, соответствующий любой ссылке, подходящей под шаблон. В <src> и <dst> должен быть только один символ *. Ссылки сопоставляются с назначением заменой символа * на содержимое, соответствующее в источнике. Например, команда refs/heads/*:refs/heads/* отправит все ветки.

  • Спецификация ссылки, начинающаяся с ^, является отрицательной спецификацией ссылки. Она задаёт ссылки, которые нужно исключить. Ссылка считается подходящей, если она соответствует хотя бы одной положительной спецификации ссылки и не соответствует ни одной отрицательной. Отрицательные спецификации ссылок могут быть шаблонными. Они должны содержать только один <src>. Полные шестнадцатеричные имена объектов также не поддерживаются. Например, команда git push origin refs/heads/*' ^refs/heads/dev-*' отправит все ветки, кроме тех, имена которых начинаются с dev-

  • Если <src> пуст, ссылка <dst> удаляется из удалённого репозитория. Например, команда git push origin :dev удалит ветку dev.

  • tag <tag> раскрывается в refs/tags/<tag>:refs/tags/<tag>. Технически это специальный синтаксис для git push, а не спецификация ссылки, поскольку в команде git push origin tag v1.0 аргументы tag и v1.0 разделены.

  • Если спецификацию ссылки невозможно раскрыть однозначно, Git выдаёт сообщение об ошибке с указанием того, что было проверено, и, в зависимости от конфигурации advice.pushUnqualifiedRefname (см. git-config[1]), предлагает пространство имён ссылок, в которое, возможно, нужно было отправить изменения.

Разрешены не все обновления: подробности см. ниже в разделе ПРАВИЛА ОТПРАВКИ.

--all
--branches

Отправить все ветви (то есть ссылки под refs/heads/); нельзя использовать вместе с другими <refspec>.

--prune

Удалить удалённые ветви, у которых нет локального аналога. Например, удалённая ветвь tmp будет удалена, если локальной ветви с таким же именем больше не существует. При этом также учитываются спецификации ссылок: например, git push --prune remote refs/heads/*:refs/tmp/* гарантирует, что удалённая ветвь refs/tmp/foo будет удалена, если refs/heads/foo не существует.

--mirror

Вместо указания каждой отправляемой ссылки задаёт зеркальное отображение всех ссылок под refs/ (включая, помимо прочего, refs/heads/, refs/remotes/ и refs/tags/) в удалённом репозитории. Новые локальные ссылки будут отправлены на удалённый сервер, локально обновлённые ссылки будут принудительно обновлены на удалённом сервере, а удалённые ссылки будут удалены на удалённом сервере. Это значение используется по умолчанию, если задан параметр конфигурации remote.<remote>.mirror.

-n
--dry-run

Выполнить все действия, кроме фактической отправки обновлений.

--porcelain

Выводить данные в формате, предназначенном для машинной обработки. Строки статуса для каждой ссылки будут разделены символами табуляции и отправлены в stdout вместо stderr. Будут указаны полные символические имена ссылок.

-d
--delete

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

--tags

Отправить все ссылки под refs/tags в дополнение к спецификациям ссылок, явно указанным в командной строке.

--follow-tags

Отправить все ссылки, которые были бы отправлены без этого параметра, а также аннотированные теги из refs/tags, отсутствующие в удалённом репозитории, но указывающие на коммит, достижимый из отправляемых ссылок. Это также можно задать с помощью переменной конфигурации push.followTags. Подробнее см. push.followTags в git-config[1].

--signed
--no-signed
--signed=(true|false|if-asked)

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

false
--no-signed

подпись не создаётся.

true
--signed

отправка завершится ошибкой, если сервер не поддерживает подписанные отправки.

if-asked

подписывать только в том случае, если сервер поддерживает подписанные отправки. Отправка также завершится ошибкой, если фактический вызов gpg --sign завершится неудачно. Подробнее о принимающей стороне см. в git-receive-pack[1].

--atomic
--no-atomic

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

-o <option>
--push-option=<option>

Передать указанную строку серверу, который передаст её хукам pre-receive и post-receive. Указанная строка не должна содержать символ NUL или LF. Если указано несколько параметров --push-option=<option>, все они передаются на другую сторону в порядке, указанном в командной строке. Если в командной строке не указан параметр --push-option=<option>, вместо него используются значения переменной конфигурации push.pushOption.

--receive-pack=<git-receive-pack>
--exec=<git-receive-pack>

Путь к программе git-receive-pack на удалённой стороне. Иногда полезно при отправке в удалённый репозиторий по ssh, если программа отсутствует в каталоге, указанном в $PATH по умолчанию.

--force-with-lease
--no-force-with-lease
--force-with-lease=<refname>
--force-with-lease=<refname>:<expect>

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

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

Предположим, что вам нужно перебазировать уже опубликованные изменения. Чтобы заменить опубликованную историю историей после перебазирования, придётся обойти правило «только перемотка вперёд». Если во время перебазирования кто-то другой создаст изменения на основе исходной истории, вершина ветви на удалённом сервере может переместиться вперёд вместе с его коммитом, и бездумная отправка с параметром --force приведёт к потере его работы.

Этот параметр позволяет указать, что обновляемая история — это история после перебазирования, которой вы хотите заменить текущую. Если удалённая ссылка по-прежнему указывает на указанный вами коммит, можно быть уверенным, что никто другой не изменял эту ссылку. Это похоже на получение «аренды» ссылки без её явной блокировки: удалённая ссылка обновляется, только если «аренда» всё ещё действительна.

Параметр --force-with-lease без указания подробностей защитит все удалённые ссылки, которые будут обновлены: их текущие значения должны совпадать с соответствующими ссылками отслеживания удалённых репозиториев.

Параметр --force-with-lease=<refname> без указания ожидаемого значения защитит только <refname>, если она будет обновляться: её текущее значение должно совпадать с соответствующей ссылкой отслеживания удалённого репозитория.

Параметр --force-with-lease=<refname>:<expect> защитит только <refname>, если она будет обновляться: её текущее значение должно совпадать с указанным значением <expect> (оно может отличаться от ссылки отслеживания удалённого репозитория для данного имени ссылки; при использовании этой формы такая ссылка отслеживания удалённого репозитория может вообще отсутствовать). Если <expect> — пустая строка, указанная ссылка не должна уже существовать.

Обратите внимание, что все формы, кроме --force-with-lease=<refname>:<expect>, в которой ожидаемое текущее значение ссылки указывается явно, всё ещё являются экспериментальными, и их семантика может измениться по мере накопления опыта использования этой функции.

Параметр --no-force-with-lease отменяет все предыдущие параметры --force-with-lease в командной строке.

Общее замечание о безопасности: использование этого параметра без ожидаемого значения, то есть в виде --force-with-lease или --force-with-lease=<refname>, крайне плохо сочетается с любыми процессами, которые в фоновом режиме неявно выполняют на удалённом репозитории, куда производится отправка, команду git fetch, например с git fetch origin в вашем репозитории, запускаемым заданием cron.

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

Если ваш редактор или другая система в фоновом режиме выполняет за вас git fetch, можно смягчить эту проблему, просто настроив ещё один удалённый репозиторий:

git remote add origin-push $(git config remote.origin.url)
git fetch origin-push

Теперь, когда фоновый процесс выполняет git fetch origin, ссылки в origin-push обновляться не будут, и поэтому такие команды, как:

git push --force-with-lease origin-push

завершатся ошибкой, если вручную не выполнить git fetch origin-push. Разумеется, этот метод не поможет, если что-то выполняет git fetch --all; в таком случае эту функцию нужно либо отключить, либо воспользоваться более трудоёмким способом, например:

git fetch              # update 'master' from remote
git tag base master    # mark our base point
git rebase -i master   # rewrite some commits
git push --force-with-lease=master:base master:master

То есть создать тег base для версий кода вышестоящего репозитория, которые вы видели и готовы перезаписать, затем переписать историю и, наконец, принудительно отправить изменения в master, если удалённая версия по-прежнему находится на base, независимо от того, до какого состояния в фоновом режиме обновилась ваша локальная remotes/origin/master.

В качестве альтернативы, указание --force-if-includes как дополнительного параметра вместе с --force-with-lease[=<refname>] (то есть без указания конкретного коммита, на который должна указывать ссылка на удалённой стороне, или ссылок на удалённой стороне, которые нужно защитить) при выполнении команды «push» позволит проверить, включены ли локально обновления ссылок отслеживания удалённых репозиториев, которые могли быть неявно обновлены в фоновом режиме, прежде чем разрешить принудительное обновление.

-f
--force

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

Этот флаг отключает эту проверку, остальные проверки безопасности, описанные ниже в разделе «ПРАВИЛА ОТПРАВКИ», а также проверки в --force-with-lease. Это может привести к потере коммитов в удалённом репозитории; используйте его осторожно.

Обратите внимание, что --force применяется ко всем отправляемым ссылкам. Поэтому его использование при значении matching для push.default или при настройке нескольких мест назначения отправки с помощью remote.<name>.push может привести к перезаписи ссылок, отличных от текущей ветви (включая локальные ссылки, значительно отстающие от соответствующих удалённых ссылок). Чтобы принудительно отправить только одну ветвь, добавьте + перед спецификацией отправляемой ссылки (например, git push origin +master принудительно отправит ветвь master). Подробнее см. выше в разделе <refspec>....

--force-if-includes
--no-force-if-includes

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

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

Если параметр передан без указания --force-with-lease или указан вместе с --force-with-lease=<refname>:<expect>, он ничего не меняет.

Указание --no-force-if-includes отключает это поведение.

--repo=<repository>

Этот параметр эквивалентен аргументу <repository>. Если указаны оба, приоритет имеет аргумент командной строки.

-u
--set-upstream

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

--thin
--no-thin

Эти параметры передаются команде git-send-pack[1]. Тонкая передача значительно сокращает объём передаваемых данных, если у отправителя и получателя много общих объектов. По умолчанию используется значение --thin.

-q
--quiet

Подавить весь вывод, включая список обновлённых ссылок, если только не произошла ошибка. Сведения о ходе выполнения не выводятся в стандартный поток ошибок.

-v
--verbose

Выводить подробную информацию.

--progress

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

--no-recurse-submodules
--recurse-submodules=(check|on-demand|only|no)

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

check

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

on-demand

будут отправлены все подмодули, изменённые в отправляемых ревизиях. Если on-demand не сможет отправить все необходимые ревизии, отправка также будет прервана с ненулевым кодом завершения.

only

будут отправлены все подмодули, а суперпроект отправлен не будет.

no

переопределить переменную конфигурации push.recurseSubmodules, если рекурсия подмодулей не требуется. Аналогично использованию --no-recurse-submodules.

При использовании on-demand или only, если для подмодуля настроен параметр push.recurseSubmodules=(on-demand|only) или submodule.recurse, рекурсия продолжится. В этом случае only рассматривается как on-demand.

--verify
--no-verify

Включить или отключить хук pre-push (см. githooks[5]). По умолчанию используется значение --verify, позволяющее хуку предотвратить отправку. При использовании --no-verify хук полностью пропускается.

-4
--ipv4

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

-6
--ipv6

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

URL-адреса Git

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

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

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

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

  • ssh://[<user>@]<host>[:<port>]/<path-to-git-repo>

  • git://<host>[:<port>]/<path-to-git-repo>

  • http[s]://<host>[:<port>]/<path-to-git-repo>

  • ftp[s]://<host>[:<port>]/<path-to-git-repo>

Для протокола ssh также можно использовать альтернативный формат, похожий на синтаксис scp:

  • [<user>@]<host>:/<path-to-git-repo>

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

Протоколы ssh и git также поддерживают подстановку ~<username>:

  • ssh://[<user>@]<host>[:<port>]/~<user>/<path-to-git-repo>

  • git://<host>[:<port>]/~<user>/<path-to-git-repo>

  • [<user>@]<host>:~<user>/<path-to-git-repo>

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

  • /path/to/repo.git/

  • file:///path/to/repo.git/

Эти два формата в основном эквивалентны, за исключением клонирования: первый подразумевает параметр --local. Подробнее см. в git-clone[1].

git clone, git fetch и git pull, но не git push, также принимают подходящий файл bundle. См. git-bundle[1].

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

  • <transport>::<address>

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

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

        [url "<actual-url-base>"]
                insteadOf = <other-url-base>

Например, при такой настройке:

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

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

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

        [url "<actual-url-base>"]
                pushInsteadOf = <other-url-base>

Например, при такой настройке:

        [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 в качестве аргумента <repository> можно использовать имя одного из следующих объектов:

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

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

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

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

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

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

        [remote "<name>"]
                url = <URL>
                pushurl = <pushurl>
                push = <refspec>
                fetch = <refspec>

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

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

Можно указать имя файла в каталоге $GIT_DIR/remotes. URL в этом файле будет использоваться для доступа к репозиторию. Если не указать refspec в командной строке, по умолчанию будет использоваться refspec из этого файла. Файл должен иметь следующий формат:

        URL: one of the above URL formats
        Push: <refspec>
        Pull: <refspec>

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

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

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

        <URL>#<head>

Параметр <URL> обязателен; #<head> необязателен.

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

Команда git fetch использует:

        refs/heads/<head>:refs/heads/<branch>

Команда git push использует:

        HEAD:refs/heads/<head>

Вышестоящие ветки

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

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

  • Она используется по умолчанию командой git push, вызванной без аргументов, за некоторыми исключениями. Например, параметр branch.<name>.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 <remote> <branch>, однако Git часто настраивает её автоматически, например:

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

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

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

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

Группы удалённых репозиториев

Группа удалённых репозиториев — это именованный список удалённых репозиториев, настроенный с помощью remotes.<name> в конфигурации git:

$ git config remotes.all-remotes "r1 r2 r3"

Если в качестве аргумента <repository> указано имя группы, отправка изменений поочерёдно выполняется в каждый удалённый репозиторий из этой группы. Основной принцип таков:

git push <options> all-remotes <args>

полностью эквивалентно следующей команде:

git push <options> r1 <args>
git push <options> r2 <args>
...
git push <options> rN <args>

где r1, r2, …​, rN — участники группы all-remotes. Никакого особого поведения не добавляется и не убирается — группа служит лишь сокращённой записью для выполнения одной и той же команды отправки изменений отдельно для каждого удалённого репозитория.

При отправке изменений в группу, состоящую более чем из одного удалённого репозитория, Git последовательно запускает отдельный подпроцесс git push для каждого участника группы. Каждый подпроцесс получает те же флаги и refspec, что и исходный вызов. Это означает, что настроенные для отдельных удалённых репозиториев правила сопоставления при отправке через remote.<name>.push и режим зеркала (remote.<name>.mirror) обрабатываются независимо для каждого удалённого репозитория; зеркальный удалённый репозиторий в группе не может повлиять на отправку изменений в другие репозитории этой группы, не являющиеся зеркалами.

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

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

Это означает, что пользователь сам отвечает за корректность последовательности отдельных операций отправки. Если команда git push r1 завершилась бы с ошибкой при заданном наборе параметров и аргументов, то команда git push all-remotes завершится аналогичным образом при обработке r1. Групповая отправка не делает ничего особенного, чтобы отдельная неудачная операция отправки завершилась успешно.

Вывод

Вывод команды «git push» зависит от используемого способа транспортировки; в этом разделе описан вывод при отправке через протокол Git (локально или по ssh).

Статус отправки выводится в виде таблицы, где каждая строка соответствует статусу одной ссылки. Каждая строка имеет следующий формат:

 <flag> <summary> <from> -> <to> (<reason>)

Если используется параметр --porcelain, каждая строка вывода имеет следующий формат:

 <flag> \t <from>:<to> \t <summary> (<reason>)

Статус актуальных ссылок выводится только при использовании параметра --porcelain или --verbose.

<flag>

Один символ, обозначающий статус ссылки:

(пробел)

успешная отправка с перемоткой вперёд;

+

успешное принудительное обновление;

-

успешное удаление ссылки;

*

успешная отправка новой ссылки;

!

ссылка, отправка которой была отклонена или завершилась неудачно; и

=

ссылка, которая уже была актуальной и не требовала отправки.

<summary>

Для успешно отправленной ссылки сводка показывает её старое и новое значения в формате, который можно использовать в качестве аргумента команды git log (в большинстве случаев это <old>..<new>, а для принудительных обновлений без перемотки вперёд — <old>...<new>).

Для неудачного обновления приводятся дополнительные сведения:

rejected

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

remote rejected

Удалённая сторона отказалась принять обновление. Обычно это вызвано хуком на удалённой стороне или тем, что в удалённом репозитории включён один из следующих параметров безопасности: receive.denyCurrentBranch (для отправки в текущую ветку), receive.denyNonFastForwards (для принудительных обновлений без перемотки вперёд), receive.denyDeletes или receive.denyDeleteCurrent. См. git-config[1].

remote failure

Удалённая сторона не сообщила об успешном обновлении ссылки, возможно, из-за временной ошибки на удалённой стороне, обрыва сетевого соединения или другой временной ошибки.

from

Имя отправляемой локальной ссылки без префикса refs/<type>/. При удалении имя локальной ссылки не указывается.

to

Имя обновляемой удалённой ссылки без префикса refs/<type>/.

reason

Пояснение для пользователя. Для успешно отправленных ссылок пояснение не требуется. Для ссылки, отправка которой завершилась неудачно, указывается причина сбоя.

Правила отправки изменений

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

Поскольку ветки и теги предназначены для разных целей, правила безопасности при отправке изменений в ветку отличаются от правил для тегов. В приведённых ниже правилах под «обновлением» понимаются любые изменения, кроме удаления и создания. Удаление и создание всегда разрешены, если они не запрещены настройками или хуками.

  1. Если назначение отправки — ветка (refs/heads/*): разрешены только обновления с перемоткой вперёд, то есть целевой коммит должен быть предком исходного коммита. Исходный объект должен быть коммитом.

  2. Если назначение отправки — тег (refs/tags/*): все обновления будут отклонены. Исходным объектом может быть любой объект.

  3. Если назначение отправки не является веткой или тегом:

    • Если исходный объект — дерево или blob, любые обновления будут отклонены.

    • Если исходный объект — тег или коммит, разрешено любое обновление с перемоткой вперёд, даже если перематываемый объект не является коммитом, а представляет собой объект-тег, который указывает на новый коммит, являющийся потомком коммита, на который указывал заменяемый последний тег (или коммит). Также разрешена замена тега совершенно другим тегом, если он указывает на тот же коммит, а также отправка развёрнутого тега, то есть коммита, на который указывает существующий объект-тег, или нового объекта-тега, на который указывает существующий коммит.

Эти правила можно переопределить, указав --force или добавив необязательный начальный символ + к refspec. Исключения: никакое принудительное обновление не позволит ветке принять объект, не являющийся коммитом, и принудительная отправка не позволит удалённому репозиторию принять изменения, которые он настроен отклонять.

Хуки и настройки также могут переопределять или дополнять эти правила; см., например, receive.denyNonFastForwards и receive.denyDeletes в git-config[1], а также pre-receive и update в githooks[5].

Примечание об обновлениях с перемоткой вперёд

Если в результате обновления ветка (или, в более общем случае, ссылка), которая указывала на коммит A, начинает указывать на другой коммит B, такое обновление называется обновлением с перемоткой вперёд тогда и только тогда, когда B является потомком A.

При обновлении с перемоткой вперёд от A к B набор коммитов, на основе которых был создан исходный коммит A, является подмножеством набора коммитов, на основе которых создан новый коммит B. Следовательно, история не теряется.

В отличие от этого, обновление без перемотки вперёд приводит к потере истории. Например, предположим, что вы и кто-то ещё начали с одного коммита X, после чего вы создали историю, ведущую к коммиту B, а другой человек — историю, ведущую к коммиту A. История выглядит так:

      B
     /
 ---X---A

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

Отправка изменений другим человеком обновила ветку: вместо коммита X она стала указывать на коммит A. Это обновление с перемоткой вперёд.

Но если вы попытаетесь отправить изменения, то попробуете обновить ветку (которая теперь указывает на A) коммитом B. Это not перемотка вперёд. Если бы вы это сделали, изменения, внесённые коммитом A, были бы потеряны, поскольку теперь все начали бы работу на основе B.

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

Чтобы не потерять ни свою работу (историю от X до B), ни работу другого человека (историю от X до A), сначала нужно получить историю из репозитория, создать историю, включающую изменения обеих сторон, и отправить результат обратно.

Можно выполнить «git pull», разрешить возможные конфликты и отправить результат командой «git push». Команда «git pull» создаст коммит слияния C между коммитами A и B.

      B---C
     /   /
 ---X---A

Обновление A получившимся коммитом слияния будет выполнено с перемоткой вперёд, и ваша отправка будет принята.

Также можно перенести свои изменения между X и B поверх A с помощью git pull --rebase и отправить результат обратно. В результате перебазирования будет создан новый коммит D, содержащий изменения между X и B, применённые поверх A.

      B   D
     /   /
 ---X---A

И в этом случае обновление A этим коммитом будет выполнено с перемоткой вперёд, и ваша отправка будет принята.

Есть и другая распространённая ситуация, когда при отправке изменений можно получить отказ из-за отсутствия перемотки вперёд. Такое возможно даже при отправке в репозиторий, куда никто другой не отправляет изменения. После того как вы сами отправили коммит A (на первом рисунке в этом разделе), заменили его с помощью git commit --amend, создав коммит B, и попытались отправить его, вы могли забыть, что уже отправили A. В таком случае, и только если вы уверены, что за это время никто не получил ваш предыдущий коммит A (и не начал создавать на его основе новые коммиты), можно выполнить команду git push --force, чтобы перезаписать его. Иными словами, git push --force следует использовать только тогда, когда вы действительно намерены потерять историю.

Примеры

git push

Работает как git push <remote>, где <remote> — удалённый репозиторий текущей ветки (или origin, если для текущей ветки не настроен удалённый репозиторий).

git push origin

Без дополнительной настройки отправляет текущую ветку в настроенную вышестоящую ветку (переменная конфигурации branch.<name>.merge), если её имя совпадает с именем текущей ветки; в противном случае завершается с ошибкой и ничего не отправляет.

Поведение этой команды по умолчанию, если параметр <refspec> не указан, можно настроить с помощью параметра push удалённого репозитория или переменной конфигурации push.default.

Например, чтобы по умолчанию отправлять только текущую ветку в origin, используйте git config remote.origin.push HEAD. Любое допустимое значение <refspec> (например, приведённые ниже) можно настроить в качестве значения по умолчанию для git push origin.

git push origin :

Отправляет в origin ветки с совпадающими именами. Описание таких веток см. в разделе <refspec> выше.

git push origin master

Находит ссылку, соответствующую master в исходном репозитории (скорее всего, это будет refs/heads/master) и обновляет ею ту же ссылку (например, refs/heads/master) в репозитории origin. Если master ещё не существует в удалённом репозитории, она будет создана.

git push origin HEAD

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

git push mothership master:satellite/master dev:satellite/dev

Использует исходную ссылку, соответствующую master (например, refs/heads/master), чтобы обновить ссылку, соответствующую satellite/master (скорее всего, refs/remotes/satellite/master), в репозитории mothership; то же самое выполняется для dev и satellite/dev.

Обсуждение правил сопоставления см. в разделе выше, посвящённом <refspec>....

Это позволяет имитировать выполнение команды git fetch на компьютере mothership с использованием команды git push, выполняемой в обратном направлении для включения работы, выполненной на satellite. Это часто необходимо, когда соединение можно установить только в одном направлении (то есть компьютер satellite может подключиться по ssh к mothership, но mothership не может инициировать соединение с satellite, поскольку последний находится за брандмауэром или на нём не запущен sshd).

После выполнения этой команды git push на компьютере satellite подключитесь по ssh к компьютеру mothership и выполните там команду git merge, чтобы завершить имитацию выполнения команды git pull на компьютере mothership для получения изменений, внесённых на satellite.

git push origin HEAD:master

Отправляет текущую ветку в удалённую ссылку, соответствующую master в репозитории origin. Эта форма удобна, когда нужно отправить текущую ветку, не задумываясь о её локальном имени.

git push origin master:refs/heads/experimental

Создаёт ветку experimental в репозитории origin, копируя текущую ветку master. Эта форма нужна только для создания новой ветки или тега в удалённом репозитории, если локальное и удалённое имена отличаются; в противном случае достаточно указать имя ссылки.

git push origin :experimental

Находит ссылку, соответствующую experimental в репозитории origin (например, refs/heads/experimental) и удаляет её.

git push origin +dev:master

Обновляет ветку master в репозитории origin веткой dev, разрешая обновления без перемотки вперёд. Это может привести к появлению в репозитории origin недостижимых коммитов без ссылок. Рассмотрим следующую ситуацию, в которой перемотка вперёд невозможна:

            o---o---o---A---B  origin/master
                     \
                      X---Y---Z  dev

Приведённая выше команда изменит репозиторий origin следующим образом:

                      A---B  (unnamed branch)
                     /
            o---o---o---X---Y---Z  master

Коммиты A и B больше не будут принадлежать ветке с символическим именем, поэтому станут недостижимыми. Такие коммиты будут удалены командой git gc в репозитории origin.

Безопасность

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

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

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

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

Конфигурация

Всё содержимое ниже этой строки в данном разделе выборочно включено из документации git-config[1]. Оно совпадает с содержимым, приведённым там:

push.autoSetupRemote

Если установлено значение true, считать --set-upstream вариантом по умолчанию для push, если для текущей ветки не настроено отслеживание upstream; этот параметр действует с вариантами push.default simple, upstream и current. Это полезно, если вы хотите, чтобы новые ветки по умолчанию отправлялись в удалённый репозиторий по умолчанию (как при использовании push.default=current), и при этом хотите настроить отслеживание upstream. Наиболее полезен этот параметр в централизованных рабочих процессах simple, где ожидается, что все ветки будут иметь на удалённом репозитории те же имена.

push.default

Определяет, какое действие должна выполнять команда git push, если refspec не задан (в командной строке, конфигурации или где-либо ещё). Разные значения подходят для разных рабочих процессов; например, в полностью централизованном рабочем процессе (то есть когда источник fetch совпадает с назначением push) вам, вероятно, подойдёт upstream. Возможны следующие значения:

nothing

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

current

отправить текущую ветку, обновив ветку с тем же именем на принимающей стороне. Работает как в централизованных, так и в нецентрализованных рабочих процессах.

upstream

отправить текущую ветку обратно в ветку, изменения из которой обычно интегрируются в текущую ветку (она называется @{upstream}). Этот режим имеет смысл только при отправке в тот же репозиторий, из которого вы обычно выполняете pull (то есть в централизованном рабочем процессе).

tracking

устаревший синоним для upstream.

simple

отправить текущую ветку в одноимённую ветку на удалённом репозитории.

Для этого режима необходимо знать, в какой удалённый репозиторий будет выполняться отправка. При отправке обратно в тот же удалённый репозиторий, из которого выполняется pull, для текущей ветки также должна быть настроена отслеживаемая ветка upstream с тем же именем.

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

matching

отправить все ветки, имеющие одинаковые имена на обеих сторонах. Благодаря этому в репозитории, в который выполняется отправка, запоминается набор отправляемых веток (например, если вы всегда отправляете туда maint и master и не отправляете другие ветки, в целевом репозитории будут эти две ветки, и ваши локальные maint и master будут отправлены туда).

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

Раньше это значение использовалось по умолчанию, но начиная с Git 2.0 это не так (новое значение по умолчанию — simple).

push.followTags

Если установлено значение true, по умолчанию включается параметр --follow-tags. При отправке можно переопределить эту настройку, указав --no-follow-tags.

push.gpgSign

Может принимать логическое значение или строку if-asked. Значение true приводит к подписыванию GPG всех отправок, как если бы команде git-push[1] был передан параметр --signed. Строка if-asked приводит к подписыванию отправок, если сервер поддерживает эту возможность, как если бы команде git push был передан параметр --signed=if-asked. Значение false может переопределить значение из конфигурационного файла с более низким приоритетом. Явно указанный параметр командной строки всегда переопределяет этот параметр конфигурации.

push.pushOption

Если в командной строке не задан аргумент --push-option=<option>, команда git push действует так, как если бы каждое <option> этой переменной было задано в виде --push-option=<option>.

Эта переменная может иметь несколько значений. Чтобы очистить значения, унаследованные от конфигурационных файлов с более низким приоритетом (например, $HOME/.gitconfig), в конфигурационном файле с более высоким приоритетом (например, в репозитории) можно указать пустое значение .git/config.

Example:

/etc/gitconfig
  push.pushoption = a
  push.pushoption = b

~/.gitconfig
  push.pushoption = c

repo/.git/config
  push.pushoption =
  push.pushoption = b

This will result in only b (a and c are cleared).
push.recurseSubmodules

Может принимать значения check, on-demand, only или no; поведение такое же, как у push --recurse-submodules. Если значение не задано, по умолчанию используется no, если только не задан параметр submodule.recurse (в этом случае значение true означает on-demand).

push.useForceIfIncludes

Если установлено значение true, это эквивалентно указанию параметра --force-if-includes для git-push[1] в командной строке. Указание --no-force-if-includes при отправке переопределяет эту настройку.

push.negotiate

Если установлено значение true, попытаться уменьшить размер отправляемого pack-файла с помощью раундов согласования, в ходе которых клиент и сервер пытаются найти общие коммиты. Если установлено значение false, Git будет искать общие коммиты только по объявленным сервером ссылкам.

push.useBitmaps

Если установлено значение false, отключить использование битовых карт для git push, даже если pack.useBitmaps имеет значение true, не запрещая использовать битовые карты в других операциях Git. По умолчанию установлено значение true.

push

© 2005–2026 Linus Torvalds and others
Licensed under the GNU General Public License version 2.
https://git-scm.com/docs/git-push

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API