Зачем мне все время делать `--set-upstream`?
Я создаю новую ветку в Git:
git branch my_branch
Нажмите это:
git push origin my_branch
Теперь скажите, что кто-то сделал некоторые изменения на сервере, и я хочу вытащить из origin/my_branch
, Я делаю:
git pull
Но я получаю:
You asked me to pull without telling me which branch you
want to merge with, and 'branch.my_branch.merge' in
your configuration file does not tell me, either. Please
specify which branch you want to use on the command line and
try again (e.g. 'git pull <repository> <refspec>').
See git-pull(1) for details.
If you often merge with the same branch, you may want to
use something like the following in your configuration file:
[branch "my_branch"]
remote = <nickname>
merge = <remote-ref>
[remote "<nickname>"]
url = <url>
fetch = <refspec>
See git-config(1) for details.
Я узнал, что могу заставить его работать с:
git branch --set-upstream my_branch origin/my_branch
Но зачем мне это делать для каждой создаваемой мной ветки? Разве не очевидно, что если я нажму my_branch
в origin/my_branch
то я бы хотел потянуть origin/my_branch
в my_branch
? Как я могу сделать это поведение по умолчанию?
29 ответов
Ярлык, который не зависит от запоминания синтаксиса для git branch --set-upstream
1 сделать:
git push -u origin my_branch
... в первый раз, когда вы нажимаете эту ветку. Или, чтобы перейти к текущей ветви к ветви с тем же именем (удобно для псевдонима):
git push -u origin HEAD
Вам нужно только использовать -u
один раз, и это устанавливает связь между вашей веткой и origin
так же, как git branch --set-upstream
делает.
Лично я думаю, что было бы хорошо установить эту связь между вашей веткой и одной удаленно. Обидно, что правила разные git push
а также git pull
,
1 Это может звучать глупо, но я очень часто забываю указывать текущую ветку, предполагая, что это по умолчанию - это не так, и результаты являются наиболее запутанными:)
Обновление 2012-10-11: Видимо, я не единственный, кому легко ошибиться! Спасибо VonC за указание, что git 1.8.0 представляет более очевидный git branch --set-upstream-to
, который можно использовать следующим образом, если вы находитесь на ветке my_branch
:
git branch --set-upstream-to origin/my_branch
... или с короткой опцией:
git branch -u origin/my_branch
Это изменение и его обоснование описаны в примечаниях к выпуску git 1.8.0, кандидат на выпуск 1:
Было заманчиво сказать
git branch --set-upstream origin/master
, но это говорит Git организовать местный филиалorigin/master
интегрировать с проверенной веткой, что маловероятно, что имел в виду пользователь. Опция устарела; использовать новый--set-upstream-to
(с коротким и сладким-u
) вариант вместо.
Вы можете сделать это с меньшим количеством печати. Во-первых, измените способ работы push:
git config --global push.default current
Это выведет origin my_branch
часть, таким образом, вы можете сделать:
git push -u
Который будет создавать удаленную ветку с тем же именем и отслеживать его.
Это мое самое распространенное использование для The Fuck.
$ git push
fatal: The current branch master has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin master
$ fuck
git push --set-upstream origin master [enter/↑/↓/ctrl+c]
Counting objects: 9, done.
...
Кроме того, интересно набирать нецензурные слова в своем терминале.
ОП спрашивает:
Я узнал, что могу заставить его работать с:
git branch --set-upstream my_branch origin/my_branch
Но почему мне нужно делать это для каждой ветки, которую я создаю?
Вам не нужно постоянно устанавливать upstream.
Больше нет (одиннадцать лет спустя).
С Git 2.37 (3 кв. 2022 г.)
git config --global push.autoSetupRemote true
позаботится об этом за вас.
См. , коммит 8a649be, коммит bdaf1df (29 апреля 2022 г.) от Tao Klerks (
TaoK
) .
(Объединено Junio C Hamano --
gitster
-- в коммите f49c478, 26 мая 2022 г.)
коммит 05d5775
push
: новая опция конфигурации "" поддерживает "" pushПодписано: Тао Клеркс
В некоторых "" централизованных рабочих процессах пользователи ожидают, что имена удаленных веток отслеживания будут соответствовать именам локальных веток.
"git push
" ( man) отправляет на удаленную версию/экземпляр ветки и "git pull
" (man) вытягивает любые изменения в удаленную ветку (изменения, сделанные тем же пользователем в другом месте или другими пользователями).Это ожидание поддерживается параметром по умолчанию "", который отклоняет отправку по умолчанию для несоответствующего имени ветки отслеживания, а также новым
branch.autosetupmerge
параметр "", который настраивает удаленное отслеживание только для удаленных ветвей с одинаковыми именами.Когда новая ветвь создана пользователем и еще не отправлена (и для нее не задано значение ""), пользователю предлагается сообщение об ошибке "" и инструкции о том, как отправить и добавить отслеживание.
Эта ошибка полезна тем, что следование совету один раз для каждой ветки «решает» проблему для этой ветки навсегда, но неудобна тем, что для «простого» централизованного рабочего процесса это всегда правильно, поэтому было бы лучше просто сделай это.
Поддержите этот рабочий процесс с помощью нового параметра конфигурации, который приведет к отправке по умолчанию, когда не настроена удаленная ветвь отслеживания, к тому же имени на удаленном и .
Также добавьте подсказку, предлагающую эту новую опцию, когда "
The current branch %s has no upstream branch
"обнаружена ошибка, и добавьте соответствующие тесты.
Новая подсказка:
Чтобы это происходило автоматически для веток без отслеживания
вверх по течению, см. '' в 'git help config'
git config
теперь включает в свою справочную страницу :
push.autoSetupRemote
Если установлено "
true
" предполагать--set-upstream
при отправке по умолчанию, когда для текущей ветки не существует восходящего отслеживания;Эта опция вступает в силу с
push.default
опции '', 'upstream
', а также 'current
'.Это полезно, если по умолчанию вы хотите, чтобы новые ветки отправлялись на удаленный сервер по умолчанию (например, поведение '
push.default=current
'), и вы также хотите, чтобы было установлено восходящее отслеживание.
Рабочие процессы, которые, скорее всего, выиграют от этого варианта:simple
' центральные рабочие процессы, где ожидается, что все ветки будут иметь одно и то же имя на удаленном компьютере.
Вы можете просто
git checkout -b my-branch origin/whatever
на первом месте. Если вы установите branch.autosetupmerge
или же branch.autosetuprebase
(мой любимый) always
(по умолчанию true
), my-branch
будет автоматически отслеживать origin/whatever
,
Увидеть git help config
,
Вы можете настроить upstream проще двумя способами. Сначала при создании ветки:
git branch -u origin/my-branch
или после того, как вы создали ветку, вы можете использовать эту команду.
git push -u origin my-branch
Вы также можете разветвляться, проверять и устанавливать апстрим с помощью одной команды:
git checkout -b my-branch -t origin/my-branch
Лично я предпочитаю делать это в два этапа:
git checkout -b my-branch
git push -u origin my-branch
Ты можешь использовать:
git config --global branch.autosetupmerge всегда
которая будет связывать ветку upstream каждый раз, когда вы создаете или извлекаете новую ветку.
См. https://felipec.wordpress.com/2013/09/01/advanced-git-concepts-the-upstream-tracking-branch/
Это также работает с autosetuprebase, если вы следуете более ориентированному на перебазирование рабочему процессу, но не используете его, если не знаете, что делаете, так как по умолчанию ваше поведение извлечения перебазируется, что может привести к странным результатам.
Кстати, ярлык для отправки текущей ветки на удаленный компьютер с таким же именем:
$ git push -u origin HEAD
Я лично использую следующие псевдонимы в Bash
в файле ~/.gitconfig
[alias]
pushup = "!git push --set-upstream origin $(git symbolic-ref --short HEAD)"
и в файле ~/.basehrc или ~/.zshrc
alias gpo="git pushup"
alias gpof="gpo -f"
alias gf="git fetch"
alias gp="git pull"
Если следующее не работает:
git config --global push.default current
Вы также должны обновить локальную конфигурацию вашего проекта, поскольку, возможно, ваш проект имеет локальные конфигурации git:
git config --local push.default current
Я использую этот псевдоним Git вместо того, чтобы каждый раз копировать / вставлять предложение из Git: https://gist.github.com/ekilah/88a880c84a50b73bd306
Источник скопирован ниже (добавьте это к вашему ~/.gitconfig
файл):
[alias]
pushup = "!gitbranchname() { git symbolic-ref --short HEAD; }; gitpushupstream() { git push --set-upstream origin `gitbranchname`; }; gitpushupstream"
Для чего стоит, если вы пытаетесь отследить ветку, которая уже существует на удаленном компьютере (например, origin / somebranch), но еще не проверила ее локально, вы можете сделать:
$ git checkout --track origin/somebranch
Примечание: "-t" - это сокращенная версия опции "--track".
Это создает ту же ассоциацию сразу.
Вы также можете явно указать git pull, какую удаленную ветку извлекать (как это упоминается в сообщении об ошибке):
git pull <remote-name> <remote-branch>
Однако будьте осторожны с этим: если вы находитесь в другой ветке и выполняете явное извлечение, ссылка, которую вы извлекаете, будет объединена с ветвью, в которой вы находитесь!
Вы можете установить действительно хороший псевдоним, который может справиться с этим без слишком подробного синтаксиса.
У меня есть следующий псевдоним в ~/.gitconfig
:
po = "!git push -u origin \"$(git rev-parse --abbrev-ref HEAD)\""
Сделав коммит в новой ветке, вы можете нажать новую ветку, просто набрав команду:
git po
Я сделал что-то похожее на многих других пользователей, но хотел поделиться этим в качестве альтернативы, так как я не видел, чтобы кто-то еще опубликовал это.
alias gpu='git push --set-upstream origin $(git branch --show-current)'
(oh-my-zsh уже имеет псевдоним gpu, так отредактированный, что в .oh-my-zsh/plugins/git/git.plugin.zsh)
Для тех, кто ищет псевдоним, который работает с git pull
вот что я использую:
alias up="git branch | awk '/^\\* / { print \$2 }' | xargs -I {} git branch --set-upstream-to=origin/{} {}"
Теперь, когда вы получаете:
$ git pull
There is no tracking information for the current branch.
...
Просто беги:
$ up
Branch my_branch set up to track remote branch my_branch from origin.
$ git pull
И ты хорош идти
В git2.37.0
или новее, вы можете указать git автоматически настроить пульт. Это делается с
git config --global --add --bool push.autoSetupRemote true
Тогда вы можете просто написатьgit push
и он будет нажимать на пульт по умолчанию.
99% of the time I want to set the upstream to a branch of the same name, so I use this (in *nix or Git Bash):
git branch --set-upstream-to=origin/`git branch --show-current`
It's nice because it's branch agnostic. Note the sub-command
git branch --show-current
prints your current branch name, or nothing if you are detached.
Side note: I have my config set such that I can use
git push -u
, so I rarely need to do this. But I still do sometimes, and it's usually when I decide I want to reset my local changes to whatever's on the remote, and at that moment I realize I previously pushed without -u. So, typically the next command I'm going to run after setting my upstream, is resetting to the remote branch:
git reset --hard @{u}
Which also happens to be branch agnostic. (Maybe I just really dislike typing in my branch name.)
Плагин git oh-my-zsh уже имеет этот псевдоним как
gpsup
. Это подталкивает и устанавливает восходящий поток к ветке. Все за один раз!
Лично я ищу стандартизированные и последовательные решения. Рекомендовал бы другим использовать тот же псевдоним. :)
вы можете позволить git автоматически создавать восходящую ветку, выполнив любую из следующих команд git
- git config --global --add текущий push.default
- git config --global --add push.autoSetupRemote true
Потому что у git есть отличная возможность вставлять / извлекать разные ветки в разные "исходящие" репозитории. Вы можете даже использовать отдельные репозитории для толкания и вытягивания - в одной и той же ветке. Это может создать распределенный многоуровневый поток, и я вижу, что это полезно в таких проектах, как ядро Linux. Git был изначально построен для использования в этом проекте.
Как следствие, это не делает предположения о том, какое хранилище должно отслеживать ваше отделение.
С другой стороны, большинство людей не используют git таким образом, так что это может быть хорошим вариантом для варианта по умолчанию.
Git, как правило, довольно низкоуровневый, и это может разочаровать. Тем не менее, есть GUI, и должно быть легко написать вспомогательные скрипты, если вы все еще хотите использовать его из оболочки.
Мы используем фабрикатор и не используем git. Мне пришлось создать псевдоним bash, который работает на Linux/ Mac
vim ~/.bash_aliases
new_branch() {
git checkout -b "$1"
git branch --set-upstream-to=origin/master "$1"
}
спасти
source ~/.bash_aliases
new_branch test #instead of git checkout -b test
git pull
Все, что я хотел, это сделать что-то вроде этого:
git checkout -b my-branch
git commit -a -m "my commit"
git push
Так как я не нашел лучшего решения, я только что создал псевдоним bash на ~/.bashrc
:
alias push="git push -u origin HEAD"
сейчас просто делаю push
команда выполняет свою работу (вы можете добавить этот псевдоним на ~/.gitconfig
тоже с другим именем, например pushup
)
Вот псевдоним bash для git push, который безопасно запускать для каждого push и будет автоматически переключаться между настройкой upstream для первого push и затем выполнением обычных push после этого.
alias gpu='[[ -z $(git config "branch.$(git symbolic-ref --short HEAD).merge") ]] && git push -u origin $(git symbolic-ref --short HEAD) || git push'
Здесь есть много хороших ответов, однако все они требуют, чтобы вы сделали что-то еще правильно перед запуском
git pull
Это, безусловно, помогает иметь псевдонимы, которые делают такие вещи, как «заставить git push работать так, как он должен, путем создания удаленной ветки, которую должным образом отслеживает локальная». Однако ничто из этого не поможет вам, если вы забудете их использовать или перейдете к другому рабочему процессу.
Вот функция bash, которую вы можете использовать для извлечения так, как она должна работать, обнаруживая, когда у вас нет настроенной удаленной цели слияния, но на удаленном сервере есть ветвь с тем же именем, что и ваша локальная ветвь. , и установите эту ветвь в качестве цели слияния, а затем потяните.
git-pulldown() {
head="$(git rev-parse --abbrev-ref HEAD)"
if [[ $(git config "branch.$head.merge") ]]; then #there's already a merge target configured, just pull as normal from there
git pull
else
if [[ $(git ls-remote --heads origin $head) ]]; then #there is an upstream branch existing with the same name as our branch
git branch --set-upstream-to origin/$head #set merge target to upstream branch with same name
git pull
else #fail with explanation
echo "Branch $head has no upstream or merge target! You will likely have to push first, or manually configure it"
return 1
fi
fi
}
Я вроде заново открыл legit
из-за этой проблемы (только OS X). Теперь все, что я использую при ветвлении, это две команды:
legit publish [<branch>]
Публикует указанную ветку на удаленной. (Псевдоним: pub
)
legit unpublish <branch>
Удаляет указанную ветку с пульта. (Псевдоним: unp
)
SublimeGit поставляется с legit
поддержка по умолчанию, что делает всю процедуру ветвления такой же простой, как нажатие Ctrl-b.
По-видимому, не существует поддерживаемого способа переопределить параметры команд git по умолчанию. Основываясь на этом ответе на определение псевдонима git с тем же именем для затенения исходной команды , мы можем переопределить поведение
git push
в bash всегда звонить
git push -u
. Поместите следующее в свой
~/.bash_profile
файл, и он должен быть эквивалентен запуску --set-upstream каждый раз, когда вы нажимаете.
function do_git {
cmd=$1
shift
myArgs=( "$@" )
if [ "$cmd" == "push" ]; then
myArgs=( "-u" "${myArgs[@]}" )
fi
myArgs=( "$cmd" "${myArgs[@]}" )
$(which git) "${myArgs[@]}"
}
alias git='do_git'