8xx8 (Андрей Кулаков)

Творческая мастерская

Все или не все? (Git Push)

| Comments

Часто ли вы задумывались над тем, какие ветки будут отправлены в удалённый репозиторий при выполнении команды push?

А поможет ли вам задуматься над этим такая картина?

Наверное, поможет, особенно если увидеть это в ночь перед релизом. А началось-то все с того, что хотели фичу красиво слить через rebase.

Так давайте разберёмся, что пошло не так.

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

1
2
3
4
5
6
$ git push --help
       git push [--all | --mirror | --tags] [-n | --dry-run]
[--receive-pack=<git-receive-pack>]
                  [--repo=<repository>] [-f | --force] [--prune] [-v |
--verbose] [-u | --set-upstream]
                  [<repository> [<refspec>...]]

Как видно из документации, мы можем пропустить указание назначения(repository) и refspec (конструкция вида ЛОКАЛЬНАЯВЕТКА[:][УДАЛЁННАЯВЕТКА]), по умолчанию в качестве назначения будет использовано origin, а в качестве refspec будет использована одна из стратегий определённых в настройке push.default. Она может принимать такие значения:

  • nothing – не пушить ничего
  • matching – пушить все ветки, названия которых в локальном репозитории совпадают с названиями в удалённом репозитории. Это как раз та опция, которая используется, если ничего не задано
  • upstream – пушить только текущую ветку в ту ветку на удалённом репозитории, которая прописана в конфиге как upstream
  • tracking – устаревший синоним для upstream
  • current – пушить только текущую ветку в ту ветку на удалённом репозитории с которой совпадёт имя

Самый лучший способ решить проблему – это указывать repository и refspec всегда при выполнении команд push/pull.

Либо полностью:

1
git push origin branch:branch

Либо в качестве refspec использовать HEAD:

1
git push origin HEAD

В таком случае текущая ветка будет запушена в ветку с таким же названием в удалённом репозитории.

Можно сделать псевдоним для команды, чтобы было удобнее

1
git config --global alias.put 'git push origin HEAD'

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

1
git config --global push.default upstream

Comments