Поведение по умолчанию «git push» без указания ветки

1366

Я использую следующую команду для отправки в мою удаленную ветку:

git push origin sandbox

Если я говорю

git push origin

это тоже подталкивает изменения в других моих ветках или только обновляет мою текущую ветку? У меня есть три ветви: master, productionи sandbox.

В git pushдокументации не очень ясно об этом, поэтому я хотел бы уточнить это навсегда.

Какие ветви и пульты git pushточно обновляют следующие команды?

git push 
git push origin

origin выше это пульт.

Я понимаю, что git push [remote] [branch]будет толкать только эту ветку к удаленному.

PlagueHammer
источник
Что касается конфигурации инструментов diff в целом и нового скрипта git difftool, я добавил новый ответ на этот другой вопрос SO: stackoverflow.com/questions/255202/…
VonC
67
Я сделал сообщение в блоге об удивительном поведении git push, которое может представлять интерес
Марк Лонгэйр,
1
@Mark: в другой работе, подталкивая только текущую ветвь к ее отслеживаемой восходящей. Ницца.
VonC
help.github.com/articles/pushing-to-a-remote разместив эту ссылку здесь для немедленной помощи таким новичкам, как я
MycrofD

Ответы:

1591

Вы можете управлять поведением по умолчанию, установив push.default в вашем git config. Из документации git-config (1) :

push.default

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

  • nothing: ничего не толкай

  • matching: нажать на все соответствующие ветви

    Все ветви, имеющие одинаковое имя на обоих концах, считаются совпадающими.

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

  • upstream: выдвинуть текущую ветвь в ее восходящую ветвь ( trackingявляется устаревшим синонимом для восходящей ветки )

  • current: нажать текущую ветку на ветку с тем же именем

  • simple: (новое в Git 1.7.11), как в апстриме, но отказывается выдвигать, если имя ветки в апстриме отличается от локального.

    Это самый безопасный вариант и хорошо подходит для начинающих.

    Этот режим стал режимом по умолчанию в Git 2.0.

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

Примеры командной строки:

Для просмотра текущей конфигурации:

git config --global push.default

Чтобы установить новую конфигурацию:

git config --global push.default current
UncleZeiv
источник
11
Вероятно, стоит отметить, что это новое в v1.6.3: kernel.org/pub/software/scm/git/docs/RelNotes-1.6.3.txt
CB Bailey
8
Этот push.default - величайшая вещь для работы с несколькими репо. Установите его на «отслеживание», и у вас все хорошо. В сочетании с ответвлением --set-upstream это делает способ push и pull более удобным.
jpswain
13
«tracking» является устаревшим синонимом «upstream»: kernel.org/pub/software/scm/git/docs/git-config.html
LuckyMalaka,
22
Стоит отметить, что в Git 1.7.11 появился новый simpleрежим. Этот режим предназначен для использования по умолчанию в будущем. simpleработает как upstream, но вроде currentтребует, чтобы имена ветвей были одинаковыми на обоих концах.
Кай
9
Стоит отметить, что в Git 2.0 simpleповедение теперь является стандартным.
до0г
209

Вы можете настроить поведение по умолчанию для вашего git с push.default

git config push.default current

или если у вас много репозиториев и вы хотите то же самое для всех, то

git config --global push.default current

Тока в этой установке означает , что по умолчанию будет только нажать текущую ветвь , когда вы делаете Git толчок

Другие варианты:

  • ничего: ничего не толкай
  • соответствие: Нажмите все соответствующие ветви (по умолчанию)
  • отслеживание: нажмите текущую ветку на то, что она отслеживает
  • current: Нажмите текущую ветку

ОБНОВЛЕНИЕ - НОВЫЙ СПОСОБ СДЕЛАТЬ ЭТО

Начиная с Git 1.7.11, сделайте следующее:

git config --global push.default simple

Это новая введенная настройка, которая работает так же, как и текущая, и по умолчанию будет установлена ​​версия git из v 2.0.

Кристоффер
источник
29
Да, я прочитал ответ, на который вы ссылаетесь, но этот ответ говорит только о том, что делать, а не о том, как это сделать. Поэтому я добавил свой ответ, чтобы вся информация, необходимая для его настройки, была на одной странице.
Кристофер
3
ХОРОШО; лучше предложить редактировать указанный пост, потому что никто не увидит ваш ответ, так как вряд ли он
наберет
как можно потянуть за текущую ветку? мерзавец происхождения?
Франсуа
200

git push originподтолкнет все изменения в локальных ветвях, которые имеют соответствующие удаленные ветки в originAs дляgit push

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

Из раздела «Примеры» git-pushсправочной страницы

baudtack
источник
2
Да, это проясняет. Я, вероятно, использую старую версию git (1.6.1.1 Mac OS X), в которой нет этих примеров на странице руководства.
PlagueHammer
Вероятно, я работаю 1.6.3.1. Однако я нашел его на сайте, на который я ссылался.
Бодэкт
2
Таким образом, в моем случае, когда все локальные ветви имеют одно и то же удаленное «происхождение», «git push» будет точно таким же, как «git push origin», которое будет выдвигать только локальные ветви, имеющие соответствующую ветку на удаленном компьютере.
PlagueHammer
@ Debajit Отлично! Отличный вопрос, кстати. Я всегда предполагал, что git push будет только толкать текущую ветку. Очевидно нет! Очень приятно знать.
Бодэкт
5
Этот вопрос старый, но для любого нового @docgnome подходит. Просто запустив 'git push origin', вы нажмете все ветви вместо текущей. Используйте 'git push -f -v -n origin development', чтобы заставить push ветку с именем development. Используйте флаг -n для имитации результата git push, чтобы вы могли заранее увидеть, какие ветви будут затронуты. Если все выглядит хорошо, запустите 'git push -f -v origin development'. Это может быть полезно stackoverflow.com/questions/3741136/git-push-f-vs
Дилан Валаде
54

Я просто зафиксировал свой код в ветке и отправил его в github, вот так:

git branch SimonLowMemoryExperiments
git checkout SimonLowMemoryExperiments
git add .
git commit -a -m "Lots of experimentation with identifying the memory problems"
git push origin SimonLowMemoryExperiments
neoneye
источник
3
Вы можете сжать коммит в `git commit -am" ... "`
Джеймс Харрингтон
17
Этот ответ имеет какое-либо отношение к вопросу? :?
Асим К.Т.
26

Вот очень полезная и полезная информация о Git Push : Git Push: только подсказка

Наиболее распространенное использование git push - это отправка локальных изменений в ваш общедоступный репозиторий. Предполагая, что восходящий поток является удаленным с именем «origin» (удаленное имя по умолчанию, если ваш репозиторий является клоном), а ветвь, которую нужно обновить в / из, называется «master» (имя ветви по умолчанию), это делается с помощью:git push origin master

git push origin перенесет изменения из всех локальных веток в соответствующие ветки удаленного источника.

git push origin master перенесет изменения из локальной ветки master в удаленную ветку master.

git push origin master:staging перенесет изменения из локальной ветки master в удаленную промежуточную ветку, если она существует.

Мукеш Чапагейн
источник
git push origin branch_nameпочему-то пихают не только branch_nameветку, но и другие мои локальные ветки (git version 1.9.1).
mrgloom
git push origin master:stagingэто удивительный скрытый драгоценный камень!
Шакил
19

(Март 2012)
Остерегайтесь: эта matchingполитика " " по умолчанию может скоро измениться
(иногда после git1.7.10 +)
:

Смотрите " Пожалуйста, обсудите: что должен делать" git push ", когда вы не говорите, что нужно нажимать? "

В текущей настройке (то есть push.default=matching) git pushбез аргумента будут выдвигаться все ветви, которые существуют локально и удаленно, с одинаковыми именами. .
Обычно это уместно, когда разработчик проталкивает свой собственный общедоступный репозиторий, но может сбивать с толку, если не опасно при использовании общего репозитория.

Предложение состоит в том, чтобы изменить значение по умолчанию на ' upstream' , то есть подтолкнуть только текущую ветвь, и подтолкнуть ее к ветке, из которой будет работать git pull.
Другой кандидат - это ' current'; это толкает только текущую ветку к удаленной ветке с тем же именем.

То, что обсуждалось до сих пор, можно увидеть в этой теме:

http://thread.gmane.org/gmane.comp.version-control.git/192547/focus=192694

Предыдущие соответствующие обсуждения включают в себя:

Чтобы присоединиться к обсуждению, отправьте свои сообщения по адресу: git@vger.kernel.org

VonC
источник
18

Я просто помещаю это в мой раздел псевдонимов .gitconfig и люблю, как это работает:

pub = "!f() { git push -u ${1:-origin} `git symbolic-ref HEAD`; }; f"

Будет подталкивать текущую ветку к источнику с git pubили другим репо с git pub repo-name. Вкусный.

Мэт Шаффер
источник
4
Это хорошо, но, к сожалению, предполагается, что ветвь имеет то же имя в другом хранилище. Попробуй git push -u --repo="origin" $1;вместо этого. Это работает довольно хорошо, за исключением того, что если вы отправляете в другой репозиторий, именем ветви будет имя, используемое другим репозиторием, а не то, из которого вы отправляете
Casebash
Эй спасибо Заставляет меня хотеть сделать более полную версию, которая проверяет статус отслеживания перед нажатием. Но пока я буду придерживаться своего, так как у меня редко бывают разные имена веток между репозиториями.
Мат Шаффер
10

Вы можете нажать текущую ветку с помощью команды

git push origin HEAD

(взял отсюда )

Андрей Федорович
источник
8

Git push попытается отправить все локальные ветви на удаленный сервер, это, скорее всего, то, что вам не нужно. У меня есть пара удобных настроек, чтобы справиться с этим:

Псевдонимы "gpull" и "gpush" соответственно:

В моем ~ / .bash_profile

get_git_branch() {
  echo `git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'`
}
alias gpull='git pull origin `get_git_branch`'
alias gpush='git push origin `get_git_branch`'

Таким образом, выполнение «gpush» или «gpull» подтолкнет только мою «текущую» ветку.

Коди Коулан
источник
3
Если вам всегда нужно поведение gpush, вы также можете установить remote.origin.push = HEAD (например, «git config remote.origin.push HEAD»), как упомянуто в разделе примеров на странице руководства git-push.
Тревор Робинсон
5
В этом нет необходимости, если вы посмотрите на пост выше «Брайан Л».
jpswain
1
Это так, как нет экв. для pull pull.default
SamGoody
8

Вы можете изменить это поведение по умолчанию в вашем .gitconfig, например:

[push]
  default = current

Чтобы проверить текущие настройки, запустите:

git config --global --get push.default
kenorb
источник
3

Вместо того, чтобы использовать псевдонимы, я предпочитаю создавать сценарии git-XXX, чтобы я мог легче контролировать их источники (у всех наших разработчиков есть определенный dir, управляемый источником на своем пути для такого типа вещей).

Этот скрипт (вызывается git-setpush) установит значение конфигурации для remote.origin.pushзначения на что-то, что будет только выдвигать текущую ветку:

#!/bin/bash -eu

CURRENT_BRANCH=$(git branch | grep '^\*' | cut -d" " -f2)
NEW_PUSH_REF=HEAD:refs/for/$CURRENT_BRANCH

echo "setting remote.origin.push to $NEW_PUSH_REF"
git config remote.origin.push $NEW_PUSH_REF

обратите внимание, что, как мы используем Gerrit, он устанавливает цель, refs/for/XXXчтобы нажать в ветке обзора. Это также предполагает, что origin - ваше удаленное имя.

Вызвать его после проверки ветки с

git checkout your-branch
git setpush

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

Марк Фишер
источник
отличная идея настройки remote.origin.push для использования gerrit. Все мои локальные ветки функций feature/fix_fubarуказывают на более общие ветки восходящего потока, такие как masterили develop, так что это будет указывать на неправильный восходящий поток. Как выглядит ваш локальный поток для репозиториев с герритным контролем?
спазм
Если у вас есть только одна «целевая» ветвь на gerrit, попробуйте просто git config remote.origin.push HEAD:refs/for/master.
Fracz
2

Я добавил следующие функции в мой файл .bashrc для автоматизации этих задач. Это делает git push / git pull + имя текущей ветви.

function gpush()
{
  if [[ "x$1" == "x-h" ]]; then
    cat <<EOF
Usage: gpush
git: for current branch: push changes to remote branch;
EOF
  else
    set -x
    local bname=`git rev-parse --abbrev-ref --symbolic-full-name @{u} | sed -e "s#/# #"`
    git push ${bname}
    set +x
  fi
}

function gpull()
{
  if [[ "x$1" == "x-h" ]]; then
    cat <<EOF
Usage: gpull
git: for current branch: pull changes from
EOF
  else
    set -x
    local bname=`git rev-parse --abbrev-ref --symbolic-full-name @{u} | sed -e "s#/# #"`
    git pull ${bname}
    set +x
  fi
}
MichaelMoser
источник