Чому мені потрібно постійно робити "-set-upstream"?


1466

Я створюю нову філію в 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? Як я можу зробити це поведінкою за замовчуванням?


21
За замовчуванням branch.autosetupmergeозначає, що конфігурація висхідної лінії для нової гілки автоматично встановлюється лише при створенні гілки з гілки віддаленого відстеження (наприклад <remote-name>/<branch-name>) (див. Git-config (1) ). Ви, ймовірно, створюєте свої філії з існуючих місцевих гілок. Якщо ви ефективно розгалужуєтесь безпосередньо від кінця віддаленої гілки (незважаючи на те, що перебуваєте на локальній гілці), тоді ви можете використовувати git branch my_branch <remote-name>/<branch-name>для автоматичного налаштування конфігурації вище за потоком.
Кріс Джонсен

20
FYI, --set-upstreamопція застаріла. Ви повинні використовувати --trackабо --set-upstream-toзамість цього.
Шон Бін

139
якщо --set-upstreamзастарілий, то, можливо, git devs повинен видалити його з довідкового повідомлення, яке відображається, коли ви запускаєте git pushбез параметрів і не встановлено верхній потік?
Крістофер Хантер

17
@ChristopherHunter Минуло рік з вашого коментаря, і це все ще говорить про це. Це просто неохайний зворотній зв'язок чи, можливо, є технічно мудра причина, щоб тримати його навколо того, про що ми не знаємо?
Конрад Вільтерстен

15
@ChristopherHunter git branch --set-upstreamзастарілий. git push --set-upstreamне.
Брайан Гордон

Відповіді:


1538

Ярлик, який не залежить від запам'ятовування синтаксису для 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) варіантом.


95
Також зауважте, що навіть якщо ви забудете -uперший раз, коли натискаєте, ви можете запустити натискання ще раз із цим прапором, і він почне відстежувати.
Генрік N

70
Жоден із них не задовольняє випадки використання git push без аргументів. Залишається, що я все ще маю пам’ятати, щоб «git push -u origin my-branch» під час першого переміщення нової гілки на віддалений.
Карл Язичник

19
Я ненавиджу згадувати цей синтаксис, тому я створив такий псевдонім:alias gpo="git push --set-upstream origin $(git branch | awk '/^\* / { print $2 }')"
lillialexis

99
Це все нормально, але я все ще думаю, що скарга ОП є справедливою. Ви запускаєте локальну гілку, працюєте над нею, підштовхуєте її до походження, щоб поділитися (без аргументів); чому це не повинно встановлювати вище? Чи насправді бажано чомусь НЕ встановлювати вгору за течією, коли натискати нову гілку на пульт?
GaryO

23
Зовсім не варто чорт часу. Чому він не робить це автоматично?
судо

1346

Ви можете зробити це за допомогою меншого набору тексту. По-перше, змінити спосіб вашого натискання:

git config --global push.default current

Це призведе до висновку origin my_branchчастини, таким чином ви можете зробити:

git push -u

Що і створить віддалену гілку з однойменною назвою і відстежить її.


4
Яким чином можна отримати висновок originпід час запуску git push -uновоствореної гілки в новоствореному сховищі? Чи припущення про те, що сховище було клоновано, таким чином, поточне відділення має віддалений встановлений режим origin?
Пьотр Доброгост

73
Це має бути за замовчуванням. Так багато речей у git можуть бути зручнішими для користувачів, якби вони просто постачалися з кращими налаштуваннями за замовчуванням.
фрікхед

13
Будьте в курсі, що "струм" трохи небезпечніше, ніж використання "простого", щоб зробити те ж саме, див. Stackoverflow.com/questions/23918062/…
Air

30
Так, але тоді, коли ви намагатиметесь, pullвам доведеться вказати, звідки. Встановлює -uвідстеження гілок між походженням і місцевим репо.
Заміт

7
Незважаючи на те, що це зручно, це все ж зобов’язує виконувати іншу команду для першої і єдиної, pushяка перемагає всю точку цього питання. Словом, хорошої відповіді немає. Те, що розробники Git наполягають на збереженні цього незручного користувача eXperience (AUX) в умовах широкого розколу громади, є ... просвітлюючим. І відлякує. (Здебільшого відлякує.)
Сесіль Карі

87

Можна просто

git checkout -b my-branch origin/whatever

на першому місці. Якщо ви встановите branch.autosetupmergeабо branch.autosetuprebase(мій улюблений) значення always(за замовчуванням є true), my-branchбуде автоматично відстежуватися origin/whatever.

Див git help config.


5
Це призводить до "фатального: Не вдається оновити контури та одночасно перейти до гілки" моя гілка "."
Карл Язичник

12
До речі, я зазвичай просто git checkout -t origin/whatever, що також вибираю whateverяк нову гілку-ім'я. Дуже зручно!
cdunn2001

2
@cdunn Цей ідеальний, але навряд чи послідовний. Прапор слід називати -u/ --set-upstream.
Тобу

1
git checkout -t origin/whateverне працює для мене при спробі створення нової гілки:fatal: Cannot update paths and switch to branch 'whatever' at the same time.
wisbucky

1
git checkout -b my-branch origin/whateverтакож є така ж помилка (я намагаюся створити нову гілку, яка не існує на локальному або віддаленому): fatal: Cannot update paths and switch to branch 'whatever' at the same time.
wisbucky

81

Ви можете налаштувати вище за течію двома способами. Спочатку при створенні гілки:

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

1
Чудова відповідь! Адресує обидва випадки звичайного використання. Після запуску git branch -u origin/my-branchя можу бігти, git pullщоб зняти свої зміни.
Бенджамін Аткін

2
"git checkout -b my-branch -t origin / my-branch" це не працює, якщо "origin / my-branch" ще не існує.
Спонж

1
Ви насправді просто можете обійтися git checkout -t origin/my-branchбез цього -b my-branch, воно автоматично автоматично зробить my-branchназву локальної філії. Однак, як зазначав @Spongman, ця команда не працює, якщо її origin/my-branchне існує спочатку.
Вісбукі

Так, буде працювати @wisbucky, - це працює чудово. Хоча я особисто навіть через два роки після того, як я написав цю відповідь, я все ж вважаю за краще розділити на два рядки з замовленням -b та push -u. Це явніше і немає помилки при оформленні замовлення -b, коли у мене немає дистанційного - що трапляється досить часто при експерименті :)
Тзен

2
git push -u origin/my-branchне вдається мені fatal: 'origin/my-branch' does not appear to be a git repository. Це працює:git push -u origin my-branch
стасон

80

Це моє найпоширеніше використання для 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.
...

Крім того, цікаво набирати лайливі слова у своєму терміналі.


Це потрібно перенести в Windows (або принаймні git-bash).
BrianHVB

1
ну це маленьке відкриття просто зробило мій день. дякую
Іван Дерст

Чудовий інструмент, дякую!
Юрій

48

Ви можете використовувати:

git config --global branch.autosetupmerge завжди

яка буде пов'язувати гілку вище за течією щоразу, коли ви створюєте або отримуєте нову гілку.

Дивіться https://felipec.wordpress.com/2013/09/01/advanced-git-concepts-the-upstream-tracking-branch/

Це також працює branch.autosetuprebase, якщо ви дотримуєтесь більш орієнтованого робочого процесу, але не використовуйте це, якщо ви не знаєте, що ви робите, оскільки це за замовчуванням ваше потягування буде перезавантажуватися, що може призвести до незвичайних результатів.


8
Не працює, я все одно отримую --set-upstreamповідомлення
Доріан

2
@Dorian, Ви повинні встановити це перед створенням філії. Див stackoverflow.com/a/9753268/263998
cdunn2001

8
але це не встановлює гілку відстеження як віддалену з тією ж гілкою, але до поточної локальної гілки .. тому, коли ви натискаєте, вона спробує натиснути на локальну гілку, якою ви були до створення нової гілки ..
Арнольд Роа

1
Це навіть більш дивна поведінка, ніж за замовчуванням. Якщо ви працюєте у відділенні, це дійсно дивно.
Beefster

1
Будьте обережні з цим налаштуванням !! Після встановлення ви отримуєте таку поведінку. 1. Перейти на master. 2. Бігати git checkout -b new_branch. 3. Додайте комісію до цієї гілки. 4. 4 git push origin new_branch. Це поштовх, який зобов’язується до masterгілки за походженням (а не до нової гілки з походженням, званої new_branch).
stwr667

38

До речі, ярлик до переміщення поточної гілки на віддалений з однойменною назвою:

$ git push -u origin HEAD

22

Я особисто використовую ці наступні псевдоніми в баші

у файлі ~ / .gitconfig

[alias]
    pushup = "!git push --set-upstream origin $(git symbolic-ref --short HEAD)"

і у файлі ~ / .bashrc або ~ / .zshrc

alias gpo="git pushup"
alias gpof="gpo -f"
alias gf="git fetch"
alias gp="git pull"

1
Мені потрібно було лише зафіксувати .gitconfig, тоді я міг би використовувати команду, git pushupяка завжди підштовхує поточну гілку до початку. Я завжди можу просто використовувати git pushupзамість git push👍
thespacecamel

18

Якщо нижче не працює:

git config --global push.default current

Також слід оновити локальну конфігурацію вашого проекту, оскільки можливий ваш проект має локальні конфігурації git:

git config --local push.default current

2
Більше пояснень було б чудово. Що робить перший рядок?
Papillon

3
Ця відповідь є тією, що відчувається законно. Усі, хто пропонує псевдоніми, - німий обхід. А інші, що виправдовують запам'ятовування довгих командних послідовностей, є педантичними.
MarkHu

10

Ви також можете чітко сказати git pull, яку віддалену гілку вивести (як це зазначається у повідомленні про помилку):

git pull <remote-name> <remote-branch>

Однак будьте обережні з цим: якщо ви перебуваєте на іншій гілці та робите явний потяг, рефракція, яку ви будете тягнути, буде об'єднана у гілку, на якій ви перебуваєте!


10

Для чого варто, якщо ви намагаєтеся відстежити гілку, яка вже існує на віддаленому пристрої (наприклад, походження / деяка галузь), але ще не перевірила її локально, ви можете зробити:

$ git checkout --track origin/somebranch

Примітка: '-t' - це скорочена версія параметра "--track".

Це налаштовує ту саму асоціацію прямо біля кажана.


5
Ви можете фактично просто заїхати у відділення. Так git checkout somebranchрівнозначно.
Заміт

2
@Zamith Це не працює тільки після того, як git fetchзаздалегідь зателефонували ?
Вальтер Роман

1
Не одразу, але так, вам потрібно мати посилання на цю гілку у вашому місцевому репо, що відбувається щоразу, коли ви телефонуєте git fetchабо git pull. Я ніколи не вважав це проблемою.
Заміт

10
git branch --set-upstream-to=origin/master<branch_name>

9

Я використовую цей псевдонім 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"

7

Ви можете створити дійсно хороший псевдонім, який може впоратися з цим без надмірно багатослівного синтаксису.

У мене є такий псевдонім у ~/.gitconfig:

po = "!git push -u origin \"$(git rev-parse --abbrev-ref HEAD)\""

Зробивши зобов’язання над новою гілкою, ви можете натиснути нову гілку, просто ввівши команду:

git po

чому po? push origin? що трапиться, якщо це запускати кілька разів?
Арнольд Роа

Так, як у push-походженні. Нічого не відбувається, якщо його запустити кілька разів. У мене також встановлений git push -fпсевдонім git pf, тому я використовую цей раз, коли джерело вже було висунуте.
123

дивіться коментар djanowski , ви можете безпосередньо скористатисяHEAD
arhak

3

Для тих, хто шукає псевдонім, з яким працює 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

І ти добре підеш


2

Оскільки git має класну здатність просувати / тягнути різні гілки до різних сховищ "upstream". Ви навіть можете використовувати окремі сховища для натискання та перетягування - на одній гілці. Це може створити розподілений багаторівневий потік, я можу вважати, що це корисно для таких проектів, як ядро ​​Linux. Git спочатку був побудований для використання в цьому проекті.

Як наслідок, це не припускає, про яке репо слід відстежувати ваше відділення.

З іншого боку, більшість людей не використовують git таким чином, тому це може стати гарним випадком для варіанту за замовчуванням.

Git, як правило, досить низький, і це може засмучувати. Тим не менш, є графічні інтерфейси, і писати допоміжні сценарії потрібно просто, якщо ви все ще хочете використовувати його з оболонки.



0

Я щось наново відкрив legitчерез цю проблему (лише для ОС X). Тепер все, що я використовую при розгалуженні, це дві команди:

legit publish [<branch>] Публікує вказану гілку на віддалений. (Псевдонім: pub)

legit unpublish <branch> Видаляє вказану гілку з віддаленого. (Псевдонім: unp)

SublimeGit поставляється з legitпідтримкою за замовчуванням, що робить всю процедуру розгалужених простим натисканням Ctrl-B.


0

Ми використовуємо фабрикатор і не натискаємо на 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

0

Ось баш-псевдонім для git push, який можна безпечно виконувати при кожному натисканні і автоматично переключатиметься між налаштуваннями вгору за першим натисканням, а потім робити звичайні натискання після цього.

alias gpu='[[ -z $(git config "branch.$(git symbolic-ref --short HEAD).merge") ]] && git push -u origin $(git symbolic-ref --short HEAD) || git push'

Оригінальна публікація

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.