Чому викликати гіт гілку - unset-upstream для встановлення?


161

Я більше новачок, коли мова йде про вдосконалені операції в git. Я підтримую свій блог, використовуючи структуру блогу Octopress . Хоча Octopress не розроблений з 2011 року, він добре відповідає моїм цілям, і я поки що не думав нічого змінювати.

FYI, мій блог розміщений на сторінках Github.

Сьогодні, працюючи над новою посадою, git statusпоказав таке повідомлення:

On branch source
Your branch is based on 'origin/master', but the upstream is gone.
  (use "git branch --unset-upstream" to fixup)

Це ж повідомлення повторюється для всіх наступних команд, таких як git add ., git commit -m 'message'і git push origin source.

  • Що означає повідомлення?
  • Щось зламане?
  • Якщо так, то що?
  • Чи потрібно це виправити?

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

Детальніше:

bash-3.2$ git branch -a
* source
  remotes/octopress/2.1
  remotes/octopress/HEAD -> octopress/master
  remotes/octopress/gh-pages
  remotes/octopress/linklog
  remotes/octopress/master
  remotes/octopress/refactor_with_tests
  remotes/octopress/rubygemcli
  remotes/octopress/site
  remotes/origin/source

Будь ласка, повідомте мене, якщо вам потрібна додаткова інформація. Дякую.

Відповіді:


197

Версія TL; DR: гілка дистанційного відстеження origin/masterіснувала раніше, але не існує, тому місцева гілка sourceвідстежує щось, чого не існує, що в кращому випадку є підозрілим - це означає, що інша функція Git не може нічого зробити для вас - і Git попереджає вас про це. Ви добре ладнали, не працюючи за призначенням функції "стеження за потоком", тож вирішувати, чи щось змінити.

Щоб дізнатися про інші налаштування вище, читайте в розділі Чому я повинен "git push --set-upstream origin <branch>"?


Це попередження - це нова річ у Git, яка з’являється першою у Git 1.8.5. Примітки до випуску містять лише один короткий пункт про це:

  • "git гілка -v -v" (і "статус git") не розрізняла гілку, яка не базується на будь-якій іншій гілці, гілку, яка синхронізується з її гілкою вище за течією, і гілку, налаштовану з висхідним потоком галузь, якої більше не існує.

Щоб описати, що це означає, спочатку потрібно знати про "віддалені", "гілки дистанційного відстеження" та як Git обробляє "відстеження вгору за течією". ( Гілки віддаленого відстеження - це жахливо хибний термін. Натомість я почав використовувати назви віддаленого відстеження , що, на мою думку, є незначним вдосконаленням. Нижче, однак, я буду використовувати "відділення віддаленого відстеження" для узгодження з документацією Git. )

Кожен "дистанційний" - це просто ім'я, як, наприклад, originабо octopressв цьому випадку. Їх мета - записати такі речі, як повна URL-адреса місць, з яких ви git fetchабо git pullоновлення. Під час використання 1 Git переходить до цього віддаленого пристрою (використовуючи збережену URL-адресу) та передає відповідний набір оновлень. Він також записує оновлення, використовуючи "гілки дистанційного відстеження".git fetch remote,

"Гілка віддаленого відстеження" (або ім'я віддаленого відстеження) - це просто запис назви гілки як останнього, яку бачили на деякому "віддаленому". Кожен пульт є самим сховищем Git, тому він має гілки. Гілки віддаленого "походження" записуються у вашому локальному сховищі під remotes/origin/. Текст , який ви показали , каже , що є філія імені sourceна origin, і гілки по імені 2.1, linklogі так далі на octopress.

(Звичайно, "звичайна" або "локальна" гілка - це лише назва гілки, яку ви створили у власному сховищі.)

Нарешті, ви можете встановити (локальну) гілку, щоб "відстежувати" "гілку віддаленого відстеження". Після встановлення локальної гілки Lдля відстеження гілки віддаленого відстеження R, Git зателефонує Rїї "вище за течією" та скаже вам, чи ви "вперед" та / або "позаду" за верхнім потоком (з точки зору комітетів). Це нормально (навіть рекомендую-стан) для місцевого відділення і дистанційного відстеження гілок використовувати той же ім'я (для віддаленої приставки частини), як sourceі origin/source, але це на самому справі не потрібно.

І в цьому випадку цього не відбувається. У вас є місцева гілка, яка sourceвідстежує гілку дистанційного відстеження origin/master.

Вам не потрібно знати точну механіку того, як Git встановлює локальну гілку для відстеження віддаленої, але вони є релевантними нижче, тому я покажу, як це працює. Ми почнемо з вашим локальним ім'ям філії, source. Існує дві записи конфігурації, що використовують це ім'я, написані branch.source.remoteта branch.source.merge. З результату, який ви показали, зрозуміло, що вони обидва встановлені, так що ви побачили б наступне, якщо виконували дані команди:

$ git config --get branch.source.remote
origin
$ git config --get branch.source.merge
refs/heads/master

Збираємо їх разом, 2 це говорить про те, що Git ваша гілка sourceвідстежує «віддаленого відстеження гілки», origin/master.

Але тепер подивіться на результат git branch -a, який показує всі локальні і віддалені відстеження імен гілок у вашому сховищі. Імена віддаленого відстеження перелічені під remotes/... і немаєremotes/origin/master . Імовірно, був свого часу, але зараз він пропав.

Git повідомляє, що можна видалити інформацію відстеження за допомогою --unset-upstream. Це очистить branch.source.originі те branch.source.merge, і припинить попередження.

Здається, досить ймовірно, що те, що ви хочете, - це перейти від відстеження origin/masterдо відстеження чогось іншого: можливо origin/source, але, можливо, одне з octopress/назв.

Ви можете зробити це з git branch --set-upstream-to, 3 , наприклад:

$ git branch --set-upstream-to=origin/source

(якщо припустити, що ви все ще знаходитесь у відділенні "джерело", і origin/sourceце те, що ви хочете - немає способу мені сказати, який з них, якщо такий є, ви хочете, хоча).

(Див. Також Як зробити існуючу гілку Git віддаленою гілкою? )

Я думаю, що ти потрапив сюди, це те, що коли ти вперше робив git clone, річ, з якої клонували, мала гілку master. У вас також була гілка master, яку було встановлено для відстеження origin/master(це нормальна, стандартна настройка для git). Це означало, що ви мали branch.master.remoteі branch.master.mergeвстановили, щоб originі refs/heads/master. Але потім ваш originпульт змінив назву з masterна source. Я вважаю, що ви також змінили місцеву назву з masterна source. Це змінило імена ваших налаштувань, від branch.master.remoteдо branch.source.remoteі від branch.master.mergeдо branch.source.merge... але він залишив старі значення , так branch.source.mergeтепер не так.

Саме в цей момент "вгору" посилання зірвалася, але у версіях Git, старших за 1.8.5, Git ніколи не помічав порушеної настройки. Тепер, коли у вас є 1.8.5, це вказує на це.


Це охоплює більшість питань, але не те, "чи потрібно це виправляти". Цілком ймовірно, що ви вже багато років працюєте навколо розбитості, роблячи (наприклад, ). Якщо ви будете продовжувати це робити, вона продовжуватиме вирішувати проблему - так, ні, вам не потрібно її виправляти. Якщо ви хочете, ви можете використовувати , щоб видалити вгору і припинити скарги і не має місцеве відділення відзначено як такі, що будь - яких вгору по течії на всіх.git pull remote branchgit pull origin source--unset-upstreamsource

Сенс вгору за течією - зробити різні операції зручнішими. Наприклад, git fetchпісля цього git merge, як правило, "зробить правильно", якщо параметр вище за течією встановлений правильно, а git statusпісля git fetchскаже, чи відповідає ваше репо рейтингу для цієї гілки.

Якщо ви хочете зручності, встановіть її за течією.


1git pull використовує git fetch, а станом на Git 1.8.4, ця (нарешті!) Також оновлює інформацію про "відділення дистанційного відстеження". У старих версіях Git оновлення не записувались у відділеннях віддаленого відстеження git pull, лише за допомогою git fetch. Оскільки ваш Git повинен мати принаймні версію 1.8.5, це не є проблемою для вас.

2 Ну, це плюс лінія конфігурації, яку я навмисно ігнорую, що знаходиться під remote.origin.fetch. Git має зіставити ім'я "злиття", щоб зрозуміти, що повна локальна назва віддаленої гілки refs/remotes/origin/master. Відображення майже завжди працює точно так само , як це, хоча, так що це передбачувано , що masterйде в origin/master.

3 Або, с git config. Якщо ви просто хочете встановити верхній потік на origin/sourceєдину частину, яка має змінитись branch.source.merge, і git config branch.source.merge refs/heads/source це зробить. Але --set-upstream-toговорить те, що ви хочете зробити, а не змушувати вас робити це самостійно вручну, тож це "кращий спосіб".


3
+1 для "Якщо вам подобається, ви можете використовувати --unset-upstream, щоб локальна гілка була позначена як такою, що взагалі не має верхнього потоку".
BeatriceThalo

157

Відповідь Торека, ймовірно, ідеальна, але я просто хотів, щоб запис записав ще один випадок, який відрізняється від описаного в оригінальному запитанні, але може з’явитися та сама помилка (оскільки це може допомогти іншим із подібною проблемою):

Я створив порожнє (нове) репо, використовуючи git init --bareна одному зі своїх серверів. Тоді я git cloneпереніс це в локальну робочу область на своєму ПК.

Після введення єдиної версії на місцевому репо я отримав цю помилку після дзвінка git status.

Після відповіді Торека я розумію, що трапилось те, що першим комітетом у місцевому робочому каталозі репо створено "головну" гілку. Але на віддаленому репо (на сервері) ніколи нічого не було, тому навіть не було навіть "ведучої" (віддаленої / вихідної / мастерської) гілки.

Після запуску git push origin masterз місцевого репо, віддалений репо нарешті мав гілку. Це зупинило появу помилки.

Отже, підсумовуючи - можна отримати таку помилку для нового нового віддаленого репо з нульовими комітами, оскільки він не має гілки, включаючи "master".


6
Наразі це результат № 1 для цього повідомлення про помилку, On branch source Your branch is based on 'origin/master', but the upstream is gone. (use "git branch --unset-upstream" to fixup)і, хоча суб'єктивне, швидше це буде викликано клонуванням порожнього сховища настільки великим, що тут є альтернативна відповідь.
Белла

2
Я думаю, що тому завжди корисно ініціалізувати ваше нове сховище файлом README.md, навіть якщо це порожній файл
Ахмед Хуссейн

8

Це може вирішити вашу проблему.

після внесення змін ви можете зробити це і потім

git remote add origin https://(address of your repo) it can be https or ssh
then
git push -u origin master

сподіваюся, що це працює для вас.

Дякую


1
Це дійсно допомогло б - причина детально описана у моїй відповіді (Коротше кажучи - це створює відсутню головну гілку у віддаленому репо).
ElazarR

7

За мене .git/refs/origin/masterкорумповано.

Я зробив наступне, що вирішило проблему для мене.

rm .git/refs/remotes/origin/master
git fetch
git branch --set-upstream-to=origin/master

0

Насправді Торек уже розповідав, як використовувати інструменти набагато краще, ніж я міг би зробити. Однак у цьому випадку я думаю, що важливо зазначити щось особливе, якщо дотримуватися вказівок на веб-сторінці http://octopress.org/docs/deploying/github/ . А саме, у вас буде кілька сховищ github у вашому налаштуванні. Перш за все той, який має всі вихідні коди вашого веб-сайту, скажімо, у каталозі $WEBSITE, а потім той, у якому лише статичні файли, що генеруються у $WEBSITE/_deploy. Найсмішніше в налаштуванні - це те, що .gitignoreв $WEBSITEкаталозі є файл, щоб ця програма фактично працювала.

Досить вступу. У цьому випадку помилка може також з’явитися із сховища в _deploy.

cd _deploy

git branch -a
* master
remotes/origin/master
remotes/origin/source

У .git/configвас зазвичай потрібно знайти щось подібне:

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[remote "origin"]
    url = git@github.com:yourname/yourname.github.io.git
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
    remote = origin
    merge = refs/heads/master

Але у вашому випадку майстер відділення не має дистанційного керування.

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[remote "origin"]
    url = git@github.com:yourname/yourname.github.io.git
    fetch = +refs/heads/*:refs/remotes/origin/*

Що ви можете вирішити:

cd _deploy
git branch --set-upstream-to=origin/master

Отже, все так, як вам сказав Торек, але може бути важливо зазначити, що це дуже добре стосується _deployкаталогу, а не кореня вашого веб-сайту.

PS: Може бути , варто використовувати оболонки , такі як zshз gitплагіном , щоб не бути укушеним цієї речі в майбутньому. Це відразу покаже, що _deployстосується іншого сховища.


0

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

cat .git/refs/remotes/origin/feature/mybranch \
echo 1edf9668426de67ab764af138a98342787dc87fe \
>> .git/refs/remotes/origin/feature/mybranch

0

Проблема: Ваша філія заснована на "origin / master", але вище по течії немає.

Рішення: гілка git - unset-upstream


3
Ласкаво просимо в stackoverflow. Питання не в тому, як можна виправити помилку, він хоче знати, чому ця помилка виникає і чи повинен він щось з цим робити. Будь ласка, зверніться до цього у своїй відповіді.
кронойк

0

видаліть локальну гілку, виконавши наступну команду

git branch -d branch_name

ви також можете зробити

git branch -D branch_name 

які в основному змушують видалити (навіть якщо локальне не злилося з джерелом)

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