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 использует (в порядке приоритета):
-
Аргументы <refspec> (например,
mainвgitpushoriginmain) или параметры--all,--mirrorили--tags -
Конфигурацию
remote.<name>.pushдля репозитория, в который отправляются изменения -
Конфигурацию
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>. Полные шестнадцатеричные имена объектов также не поддерживаются. Например, командаgitpushoriginrefs/heads/*'^refs/heads/dev-*'отправит все ветки, кроме тех, имена которых начинаются сdev- -
Если
<src>пуст, ссылка<dst>удаляется из удалённого репозитория. Например, командаgitpushorigin:devудалит веткуdev. -
tag<tag> раскрывается вrefs/tags/<tag>:refs/tags/<tag>. Технически это специальный синтаксис дляgitpush, а не спецификация ссылки, поскольку в командеgitpushorigintagv1.0аргументыtagиv1.0разделены. -
Если спецификацию ссылки невозможно раскрыть однозначно, Git выдаёт сообщение об ошибке с указанием того, что было проверено, и, в зависимости от конфигурации
advice.pushUnqualifiedRefname(см. git-config[1]), предлагает пространство имён ссылок, в которое, возможно, нужно было отправить изменения.
-
Разрешены не все обновления: подробности см. ниже в разделе ПРАВИЛА ОТПРАВКИ.
-
--all -
--branches -
Отправить все ветви (то есть ссылки под
refs/heads/); нельзя использовать вместе с другими <refspec>. -
--prune -
Удалить удалённые ветви, у которых нет локального аналога. Например, удалённая ветвь
tmpбудет удалена, если локальной ветви с таким же именем больше не существует. При этом также учитываются спецификации ссылок: например,gitpush--pruneremoterefs/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> -
Обычно
gitpushотказывается обновлять удалённую ссылку, если она не является предком локальной ссылки, используемой для её перезаписи.Этот параметр отменяет данное ограничение, если текущее значение удалённой ссылки совпадает с ожидаемым. В противном случае
gitpushзавершится ошибкой.Предположим, что вам нужно перебазировать уже опубликованные изменения. Чтобы заменить опубликованную историю историей после перебазирования, придётся обойти правило «только перемотка вперёд». Если во время перебазирования кто-то другой создаст изменения на основе исходной истории, вершина ветви на удалённом сервере может переместиться вперёд вместе с его коммитом, и бездумная отправка с параметром
--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>, крайне плохо сочетается с любыми процессами, которые в фоновом режиме неявно выполняют на удалённом репозитории, куда производится отправка, командуgitfetch, например сgitfetchoriginв вашем репозитории, запускаемым заданием cron.Защита, которую этот параметр обеспечивает по сравнению с
--force, заключается в том, что последующие изменения, на которых не основана ваша работа, не будут затёрты. Однако фоновый процесс, обновляющий ссылки, легко сводит эту защиту на нет. В качестве эвристики для определения ссылок, которые вы, предположительно, видели и готовы затереть, у нас нет ничего, кроме сведений об отслеживании удалённого репозитория.Если ваш редактор или другая система в фоновом режиме выполняет за вас
gitfetch, можно смягчить эту проблему, просто настроив ещё один удалённый репозиторий:git remote add origin-push $(git config remote.origin.url) git fetch origin-push
Теперь, когда фоновый процесс выполняет
gitfetchorigin, ссылки вorigin-pushобновляться не будут, и поэтому такие команды, как:git push --force-with-lease origin-push
завершатся ошибкой, если вручную не выполнить
gitfetchorigin-push. Разумеется, этот метод не поможет, если что-то выполняетgitfetch--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 -
Обычно
gitpushотказывается обновлять ветвь, если она не является предком отправляемого коммита.Этот флаг отключает эту проверку, остальные проверки безопасности, описанные ниже в разделе «ПРАВИЛА ОТПРАВКИ», а также проверки в
--force-with-lease. Это может привести к потере коммитов в удалённом репозитории; используйте его осторожно.Обратите внимание, что
--forceприменяется ко всем отправляемым ссылкам. Поэтому его использование при значенииmatchingдляpush.defaultили при настройке нескольких мест назначения отправки с помощьюremote.<name>.pushможет привести к перезаписи ссылок, отличных от текущей ветви (включая локальные ссылки, значительно отстающие от соответствующих удалённых ссылок). Чтобы принудительно отправить только одну ветвь, добавьте+перед спецификацией отправляемой ссылки (например,gitpushorigin+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 использует вышестоящую ветку для операций с удалённым репозиторием, например:
-
Она используется по умолчанию командами
gitpullиgitfetch, вызванными без аргументов. -
Она используется по умолчанию командой
gitpush, вызванной без аргументов, за некоторыми исключениями. Например, параметрbranch.<name>.pushRemoteпозволяет отправить изменения в другой удалённый репозиторий, отличный от того, из которого вы получаете изменения; кроме того, по умолчанию с параметромpush.default=simpleу настроенной вышестоящей ветки должно быть то же имя. -
Различные команды, включая
gitcheckoutиgitstatus, показывают, сколько коммитов было добавлено в текущую ветку и вышестоящую ветку с момента их ответвления, например: «Ваша ветка и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, командаgitpushавтоматически настроит вышестоящую ветку при первой отправке ветки. -
При переключении на ветку удалённого отслеживания с помощью команды
gitcheckout<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>
-
Для успешно отправленной ссылки сводка показывает её старое и новое значения в формате, который можно использовать в качестве аргумента команды
gitlog(в большинстве случаев это <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 разрешает только определённые виды обновлений, чтобы не допустить случайной потери данных в удалённом репозитории.
Поскольку ветки и теги предназначены для разных целей, правила безопасности при отправке изменений в ветку отличаются от правил для тегов. В приведённых ниже правилах под «обновлением» понимаются любые изменения, кроме удаления и создания. Удаление и создание всегда разрешены, если они не запрещены настройками или хуками.
-
Если назначение отправки — ветка (
refs/heads/*): разрешены только обновления с перемоткой вперёд, то есть целевой коммит должен быть предком исходного коммита. Исходный объект должен быть коммитом. -
Если назначение отправки — тег (
refs/tags/*): все обновления будут отклонены. Исходным объектом может быть любой объект. -
Если назначение отправки не является веткой или тегом:
-
Если исходный объект — дерево или 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 следует использовать только тогда, когда вы действительно намерены потерять историю.
Примеры
-
gitpush -
Работает как
gitpush<remote>, где <remote> — удалённый репозиторий текущей ветки (илиorigin, если для текущей ветки не настроен удалённый репозиторий). -
gitpushorigin -
Без дополнительной настройки отправляет текущую ветку в настроенную вышестоящую ветку (переменная конфигурации
branch.<name>.merge), если её имя совпадает с именем текущей ветки; в противном случае завершается с ошибкой и ничего не отправляет.Поведение этой команды по умолчанию, если параметр
<refspec>не указан, можно настроить с помощью параметраpushудалённого репозитория или переменной конфигурацииpush.default.Например, чтобы по умолчанию отправлять только текущую ветку в
origin, используйтеgitconfigremote.origin.pushHEAD. Любое допустимое значение<refspec>(например, приведённые ниже) можно настроить в качестве значения по умолчанию дляgitpushorigin. -
gitpushorigin: -
Отправляет в
originветки с совпадающими именами. Описание таких веток см. в разделе<refspec>выше. -
gitpushoriginmaster -
Находит ссылку, соответствующую
masterв исходном репозитории (скорее всего, это будетrefs/heads/master) и обновляет ею ту же ссылку (например,refs/heads/master) в репозиторииorigin. Еслиmasterещё не существует в удалённом репозитории, она будет создана. -
gitpushoriginHEAD -
Удобный способ отправить текущую ветку в удалённый репозиторий, сохранив её имя.
-
gitpushmothershipmaster:satellite/masterdev:satellite/dev -
Использует исходную ссылку, соответствующую
master(например,refs/heads/master), чтобы обновить ссылку, соответствующуюsatellite/master(скорее всего,refs/remotes/satellite/master), в репозиторииmothership; то же самое выполняется дляdevиsatellite/dev.Обсуждение правил сопоставления см. в разделе выше, посвящённом <refspec>....
Это позволяет имитировать выполнение команды
gitfetchна компьютереmothershipс использованием командыgitpush, выполняемой в обратном направлении для включения работы, выполненной наsatellite. Это часто необходимо, когда соединение можно установить только в одном направлении (то есть компьютер satellite может подключиться по ssh к mothership, но mothership не может инициировать соединение с satellite, поскольку последний находится за брандмауэром или на нём не запущен sshd).После выполнения этой команды
gitpushна компьютереsatelliteподключитесь по ssh к компьютеруmothershipи выполните там командуgitmerge, чтобы завершить имитацию выполнения командыgitpullна компьютереmothershipдля получения изменений, внесённых наsatellite. -
gitpushoriginHEAD:master -
Отправляет текущую ветку в удалённую ссылку, соответствующую
masterв репозиторииorigin. Эта форма удобна, когда нужно отправить текущую ветку, не задумываясь о её локальном имени. -
gitpushoriginmaster:refs/heads/experimental -
Создаёт ветку
experimentalв репозиторииorigin, копируя текущую веткуmaster. Эта форма нужна только для создания новой ветки или тега в удалённом репозитории, если локальное и удалённое имена отличаются; в противном случае достаточно указать имя ссылки. -
gitpushorigin:experimental -
Находит ссылку, соответствующую
experimentalв репозиторииorigin(например,refs/heads/experimental) и удаляет её. -
gitpushorigin+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 больше не будут принадлежать ветке с символическим именем, поэтому станут недостижимыми. Такие коммиты будут удалены командой
gitgcв репозитории origin.
Безопасность
Протоколы fetch и push не предназначены для защиты от кражи одной стороной данных из другого репозитория, которыми не предполагалось делиться. Если у вас есть конфиденциальные данные, которые нужно защитить от злоумышленника, лучше всего хранить их в другом репозитории. Это касается и клиентов, и серверов. В частности, пространства имён на сервере не обеспечивают эффективного контроля доступа на чтение; предоставляйте доступ на чтение к пространству имён только тем клиентам, которым вы доверили бы доступ на чтение ко всему репозиторию.
Известны следующие векторы атак:
-
Жертва отправляет строки "have", сообщая идентификаторы имеющихся у неё объектов, которыми явно не предполагалось делиться, но которые можно использовать для оптимизации передачи, если они есть и у другой стороны. Злоумышленник выбирает идентификатор объекта X, который хочет украсть, и отправляет ссылку на X, но ему не нужно отправлять содержимое X, поскольку оно уже есть у жертвы. Теперь жертва считает, что у злоумышленника есть X, и позднее отправляет ему содержимое X. (Клиенту проще всего выполнить эту атаку на сервере: создать ссылку на X в доступном клиенту пространстве имён, а затем получить его. Серверу проще всего выполнить её на клиенте, «слив» X в общедоступную ветку и надеясь, что пользователь выполнит дополнительную работу в этой ветке и отправит её обратно на сервер, не заметив слияния.)
-
Как и в случае с атакой № 1, злоумышленник выбирает идентификатор объекта X, который хочет украсть. Жертва отправляет объект Y, который уже есть у злоумышленника, а злоумышленник ложно заявляет, что у него есть X, но нет Y, поэтому жертва отправляет Y в виде дельты относительно X. Дельта раскрывает злоумышленнику области X, похожие на Y.
Конфигурация
Всё содержимое ниже этой строки в данном разделе выборочно включено из документации git-config[1]. Оно совпадает с содержимым, приведённым там:
-
push.autoSetupRemote -
Если установлено значение
true, считать--set-upstreamвариантом по умолчанию для push, если для текущей ветки не настроено отслеживание upstream; этот параметр действует с вариантамиpush.defaultsimple,upstreamиcurrent. Это полезно, если вы хотите, чтобы новые ветки по умолчанию отправлялись в удалённый репозиторий по умолчанию (как при использованииpush.default=current), и при этом хотите настроить отслеживание upstream. Наиболее полезен этот параметр в централизованных рабочих процессахsimple, где ожидается, что все ветки будут иметь на удалённом репозитории те же имена. -
push.default -
Определяет, какое действие должна выполнять команда
gitpush, если refspec не задан (в командной строке, конфигурации или где-либо ещё). Разные значения подходят для разных рабочих процессов; например, в полностью централизованном рабочем процессе (то есть когда источник fetch совпадает с назначением push) вам, вероятно, подойдётupstream. Возможны следующие значения:-
nothing -
ничего не отправлять (завершиться с ошибкой), если не указан refspec. Это значение предназначено главным образом для тех, кто хочет избегать ошибок и всегда явно задавать параметры.
-
current -
отправить текущую ветку, обновив ветку с тем же именем на принимающей стороне. Работает как в централизованных, так и в нецентрализованных рабочих процессах.
-
upstream -
отправить текущую ветку обратно в ветку, изменения из которой обычно интегрируются в текущую ветку (она называется
@{upstream}). Этот режим имеет смысл только при отправке в тот же репозиторий, из которого вы обычно выполняете pull (то есть в централизованном рабочем процессе). -
tracking -
устаревший синоним для
upstream. -
simple -
отправить текущую ветку в одноимённую ветку на удалённом репозитории.
Для этого режима необходимо знать, в какой удалённый репозиторий будет выполняться отправка. При отправке обратно в тот же удалённый репозиторий, из которого выполняется pull, для текущей ветки также должна быть настроена отслеживаемая ветка upstream с тем же именем.
Этот режим используется по умолчанию начиная с Git 2.0 и является самым безопасным вариантом для начинающих.
-
matching -
отправить все ветки, имеющие одинаковые имена на обеих сторонах. Благодаря этому в репозитории, в который выполняется отправка, запоминается набор отправляемых веток (например, если вы всегда отправляете туда
maintиmasterи не отправляете другие ветки, в целевом репозитории будут эти две ветки, и ваши локальныеmaintиmasterбудут отправлены туда).Чтобы эффективно использовать этот режим, необходимо убедиться, что
allветки, которые вы собираетесь отправить, готовы к отправке до запускаgitpush, поскольку этот режим предназначен для отправки всех веток за один раз. Если вы обычно завершаете работу только над одной веткой и отправляете результат, пока другие ветки ещё не готовы, этот режим вам не подходит. Кроме того, этот режим не подходит для отправки в общий централизованный репозиторий, поскольку другие люди могут добавлять туда новые ветки или обновлять вершины существующих веток без вашего контроля.Раньше это значение использовалось по умолчанию, но начиная с Git 2.0 это не так (новое значение по умолчанию —
simple).
-
-
push.followTags -
Если установлено значение true, по умолчанию включается параметр
--follow-tags. При отправке можно переопределить эту настройку, указав--no-follow-tags. -
push.gpgSign -
Может принимать логическое значение или строку
if-asked. Значение true приводит к подписыванию GPG всех отправок, как если бы команде git-push[1] был передан параметр--signed. Строкаif-askedприводит к подписыванию отправок, если сервер поддерживает эту возможность, как если бы командеgitpushбыл передан параметр--signed=if-asked. Значение false может переопределить значение из конфигурационного файла с более низким приоритетом. Явно указанный параметр командной строки всегда переопределяет этот параметр конфигурации. -
push.pushOption -
Если в командной строке не задан аргумент
--push-option=<option>, командаgitpushдействует так, как если бы каждое<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, отключить использование битовых карт дляgitpush, даже если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