Po co wywoływać git branch --unset-upstream, aby naprawić?

161

Jestem bardziej nowicjuszem, jeśli chodzi o zaawansowane operacje w git. I utrzymać mój blog za pomocą blogów ramy Octopress . Chociaż Octopress nie jest rozwijany od 2011 roku, dobrze spełnia moje zadanie, więc do tej pory nie myślałem o zmianie niczego.

FYI, mój blog jest hostowany na Github Pages.

Dzisiaj podczas pracy nad nowym postem git statuspokazała się następująca wiadomość:

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

Ten sam komunikat powtórzony dla wszystkich kolejnych poleceń, takich jak git add ., git commit -m 'message'i git push origin source.

  • Co oznacza ta wiadomość?
  • Czy coś jest zepsute?
  • Jeśli tak, to co?
  • Czy muszę to naprawić?

Jeśli to możliwe, wskaż mi artykuł w formacie PDF / internetowym, w którym mogę przeczytać o tym i zrozumieć na przyszłość.

Więcej szczegółów:

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

Daj mi znać, jeśli potrzebujesz więcej informacji. Dzięki.

Jatin Ganhotra
źródło

Odpowiedzi:

197

Wersja TL; DR: gałąź zdalnego śledzenia origin/masterkiedyś istniała, ale teraz jej nie ma, więc lokalna gałąź sourceśledzi coś, co nie istnieje, co jest w najlepszym przypadku podejrzane - oznacza to, że inna funkcja Git nie jest w stanie nic dla Ciebie zrobić - i Git ostrzega Cię przed tym. Dobrze sobie radziłeś bez funkcji „śledzenia nadrzędnego” działającej zgodnie z przeznaczeniem, więc od Ciebie zależy, czy cokolwiek zmienisz.

Aby zapoznać się z innymi ustawieniami nadrzędnymi, zobacz Dlaczego muszę używać polecenia „git push --set-upstream origin <branch>”?


To ostrzeżenie to nowa rzecz w Git, pojawiająca się jako pierwsza w Git 1.8.5. Uwagi do wydania zawierają tylko jeden krótki punkt na ten temat:

  • „git branch -v -v” (i „git status”) nie rozróżnia gałęzi, która nie jest oparta na żadnej innej gałęzi, gałęzi, która jest zsynchronizowana z gałęzią upstream i gałęzi skonfigurowanej z odgałęzieniem upstream gałąź, która już nie istnieje.

Aby opisać, co to znaczy, musisz najpierw wiedzieć o „zdalnych zdalnych lokalizacjach”, „zdalnych gałęziach śledzenia” oraz o tym, jak Git obsługuje „śledzenie nadrzędnych”. ( Gałęzie zdalnego śledzenia to strasznie wadliwy termin - zamiast tego zacząłem używać nazw zdalnego śledzenia , co moim zdaniem jest niewielkim ulepszeniem. Poniżej jednak użyję „gałęzi zdalnego śledzenia”, aby zachować spójność z dokumentacją Gita. )

Każdy „remote” to po prostu nazwa, jak origini octopressw tym przypadku. Ich celem jest rejestrowanie takich rzeczy, jak pełne adresy URL miejsc, z których korzystasz git fetchlub git pullaktualizacje. Gdy używasz 1, Git przechodzi do tego pilota (używając zapisanego adresu URL) i przynosi odpowiedni zestaw aktualizacji. Rejestruje również aktualizacje przy użyciu „gałęzi zdalnego śledzenia”.git fetch remote,

„Gałąź zdalnego śledzenia” (lub nazwa zdalnego śledzenia) to po prostu zapis nazwy gałęzi, tak jak ostatnio widziano na „zdalnym”. Każdy pilot jest sam w sobie repozytorium Git, więc ma gałęzie. Gałęzie na zdalnym „źródle” są zapisywane w lokalnym repozytorium pod remotes/origin/. Tekst, który pokazał mówi, że tam jest oddział nazwany sourcena origin, a gałęzie nazwie 2.1, linklogi tak dalej na octopress.

(„Normalna” lub „lokalna” gałąź to oczywiście tylko nazwa gałęzi, którą utworzyłeś we własnym repozytorium).

Na koniec możesz skonfigurować gałąź (lokalną), aby „śledzić” „gałąź zdalnego śledzenia”. Gdy gałąź lokalna Ljest ustawiona na śledzenie gałęzi ze zdalnym śledzeniem R, Git wywoła Rjej „upstream” i powie ci, czy jesteś „przed” i / lub „za” nadrzędnym (pod względem zatwierdzeń). To normalne (nawet godne polecenia), że lokalny oddział i gałęzie zdalnego śledzenia używają tej samej nazwy (z wyjątkiem zdalnej części prefiksu), jak sourcei origin/source, ale nie jest to w rzeczywistości konieczne.

W tym przypadku tak się nie dzieje. Masz oddział lokalny, który sourceśledzi oddział ze zdalnym śledzeniem origin/master.

Nie musisz znać dokładnej mechaniki, jak Git konfiguruje lokalną gałąź do śledzenia zdalnego, ale są one istotne poniżej, więc pokażę, jak to działa. Zaczynamy od lokalnej nazwy oddziału, source. Istnieją dwa wpisy konfiguracji używające tej nazwy, pisane branch.source.remotei branch.source.merge. Z danych wyjściowych, które pokazałeś, jasno wynika, że ​​oba są ustawione, więc po uruchomieniu podanych poleceń zobaczysz następujące informacje:

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

Kładzenie to razem, 2 to mówi Git że oddział sourceśledzi „zdalnego śledzenia oddział” origin/master.

Ale teraz spójrz na wynik programu git branch -a, który pokazuje wszystkie nazwy gałęzi śledzenia lokalnego i zdalnego w twoim repozytorium. Nazwy zdalnego śledzenia są wymienione pod remotes/... i nie maremotes/origin/master . Prawdopodobnie był kiedyś, ale teraz go nie ma.

Git informuje Cię, że możesz usunąć informacje o śledzeniu za pomocą --unset-upstream. Spowoduje to usunięcie zarówno branch.source.origini branch.source.merge, jak i zatrzymanie ostrzeżenia.

Wydaje się dość prawdopodobne, że to, czego chcesz, to jednak przejście od śledzenia origin/masterdo śledzenia czegoś innego: prawdopodobnie origin/source, ale może jedna z octopress/nazw.

Można to zrobić z git branch --set-upstream-to, 3 , np:

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

(zakładając, że nadal znajdujesz się w „źródle” gałęzi, a to origin/sourcejest żądane źródło - nie ma sposobu, abym mógł stwierdzić, który z nich, jeśli w ogóle, chcesz.

(Zobacz także: Jak zmienić istniejącą ścieżkę gałęzi Git na gałąź zdalną? )

Myślę, że sposób, w jaki tu trafiłeś, jest taki, że kiedy pierwszy raz zrobiłeś coś git clone, z czego sklonowałeś, miało gałąź master. Miałeś również gałąź master, która była ustawiona na śledzenie origin/master(jest to normalna, standardowa konfiguracja dla gita). Oznaczało to, że miałeś branch.master.remotei branch.master.mergeustawiłeś, na origini refs/heads/master. Ale potem twój originpilot zmienił nazwę z masterna source. Wydaje mi się, że zmieniłeś również lokalną nazwę z masterna source. Zmieniło to nazwy twoich ustawień, od branch.master.remotedo branch.source.remotei od branch.master.mergedo branch.source.merge... ale pozostawiło stare wartości , więc branch.source.mergeteraz było błędne.

W tym momencie zepsuło się połączenie „upstream”, ale w wersjach Gita starszych niż 1.8.5 Git nigdy nie zauważył zepsutego ustawienia. Teraz, gdy masz 1.8.5, wskazuje to na to.


To obejmuje większość pytań, ale nie dotyczy pytania „czy muszę to naprawić”. Jest prawdopodobne, że od lat zajmujesz się załamaniem, robiąc (np .). Jeśli będziesz to robić dalej, problem będzie nadal działać - więc nie, nie musisz tego naprawiać. Jeśli chcesz, możesz użyć do usunięcia upstream i zatrzymania skarg, ale nie oznaczaj lokalnego oddziału jako posiadającego w ogóle żadnego upstream.git pull remote branchgit pull origin source--unset-upstreamsource

Celem posiadania upstream jest uczynienie różnych operacji wygodniejszymi. Na przykład, git fetchpo którym następuje git mergegeneralnie „zrobi to, co należy”, jeśli pierwszeństwo jest ustawione poprawnie, a git statuspo nim git fetchpowie Ci, czy twoje repozytorium pasuje do tego głównego dla tej gałęzi.

Jeśli chcesz wygody, zresetuj upstream.


1git pull zastosowań git fetch, a od Git 1.8.4, to (wreszcie!) Aktualizuje również „zdalnego śledzenia oddział” informacji. W starszych wersjach Git, aktualizacje nie nagrane na zdalne śledzenie oddziałów z git pulltylko z git fetch. Ponieważ Twój Git musi być w wersji co najmniej 1.8.5, nie stanowi to dla Ciebie problemu.

2 Cóż, to plus linia konfiguracji, którą celowo ignoruję, a która znajduje się pod remote.origin.fetch. Git musi zmapować nazwę „merge”, aby dowiedzieć się, że pełna nazwa lokalna zdalnego oddziału to refs/remotes/origin/master. Jednak mapowanie prawie zawsze działa właśnie w ten sposób, więc można przewidzieć, że tak mastersię stanie origin/master.

3 Lub za pomocą git config. Jeśli chcesz tylko ustawić nadrzędny kanał origin/sourcena jedyną część, która musi się zmienić, to branch.source.mergei git config branch.source.merge refs/heads/source zrobiłbyś to. Ale --set-upstream-tomówi, co chcesz zrobić, zamiast zmuszać cię do robienia tego ręcznie, więc to jest „lepszy sposób”.

torek
źródło
3
+1 dla „Jeśli chcesz, możesz użyć --unset-upstream, aby lokalna gałąź była oznaczona jako nie posiadająca żadnego upstream”.
BeatriceThalo
157

Odpowiedź Tarka jest prawdopodobnie idealna, ale chciałem tylko, aby w rekordzie wspomniano o innym przypadku, który jest inny niż ten opisany w pierwotnym pytaniu, ale może pojawić się ten sam błąd (może pomóc innym z podobnym problemem):

Utworzyłem puste (nowe) repozytorium git init --barena jednym z moich serwerów. Następnie git cloneumieściłem go w lokalnym obszarze roboczym na moim komputerze.

Po zatwierdzeniu pojedynczej wersji w lokalnym repozytorium otrzymałem ten błąd po wywołaniu git status.

Idąc za odpowiedzią Torka, rozumiem, że stało się tak, że pierwsze zatwierdzenie repozytorium lokalnego katalogu roboczego utworzyło gałąź „master”. Ale na zdalnym repozytorium (na serwerze) nigdy nic nie było, więc nie było nawet gałęzi „master” (zdalne / źródło / master).

Po uruchomieniu git push origin masterz lokalnego repozytorium zdalne repozytorium miało wreszcie gałąź główną. To powstrzymało pojawianie się błędu.

Podsumowując - można otrzymać taki błąd dla nowego zdalnego repozytorium z zerową liczbą zatwierdzeń, ponieważ nie ma ono żadnej gałęzi, w tym „master”.

ElazarR
źródło
6
Jest to obecnie wynik nr 1 dla tego komunikatu o błędzie On branch source Your branch is based on 'origin/master', but the upstream is gone. (use "git branch --unset-upstream" to fixup)i chociaż subiektywny, jest bardziej prawdopodobne, że jest to spowodowane sklonowaniem pustego repozytorium, tak świetnego, że można tu znaleźć alternatywną odpowiedź.
Bella
2
Myślę, że to dlatego, że jest zawsze dobry pomysł, aby zainicjować nowe repozytorium z plikiem README.md, nawet jeśli jest to pusty plik
Ahmed Hussein
8

To może rozwiązać twój problem.

po wprowadzeniu zmian możesz to zatwierdzić, a następnie

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

mam nadzieję, że to działa dla Ciebie.

dzięki

Ajay Kotnala
źródło
1
To rzeczywiście by pomogło - powód jest szczegółowo opisany w mojej odpowiedzi (w skrócie - tworzy to brakującą gałąź główną w zdalnym repozytorium).
ElazarR
7

Dla mnie .git/refs/origin/mastersię skorumpował.

Wykonałem następujące czynności, które rozwiązały problem.

rm .git/refs/remotes/origin/master
git fetch
git branch --set-upstream-to=origin/master
smremde
źródło
0

Właściwie torek powiedział ci już, jak używać narzędzi znacznie lepiej, niż ja byłbym w stanie zrobić. Jednak w tym przypadku myślę, że ważne jest, aby zwrócić uwagę na coś szczególnego, jeśli będziesz postępować zgodnie z wytycznymi na http://octopress.org/docs/deploying/github/ . Mianowicie, będziesz mieć wiele repozytoriów github w swojej konfiguracji. Przede wszystkim ten, w którym cały kod źródłowy Twojej witryny internetowej znajduje się powiedzmy w katalogu $WEBSITE, a następnie ten, w którym znajdują się tylko statyczne pliki generowane $WEBSITE/_deploy. Zabawne w instalacji jest to, że .gitignorew $WEBSITEkatalogu znajduje się plik, dzięki czemu ta konfiguracja faktycznie działa.

Wystarczające wprowadzenie. W takim przypadku błąd może również pochodzić z repozytorium w _deploy.

cd _deploy

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

W .git/confignormalnie będziesz musiał znaleźć coś takiego:

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

Ale w twoim przypadku master oddziału nie ma pilota.

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

Które możesz rozwiązać poprzez:

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

Więc wszystko jest tak, jak powiedział ci torek, ale może być ważne, aby zwrócić uwagę, że to bardzo dobrze może dotyczyć _deploykatalogu, a nie katalogu głównego twojej witryny.

PS: Może warto byłoby użyć powłoki takiej jak zshz gitwtyczką, aby w przyszłości nie zostać ugryzionym przez tę rzecz. Natychmiast pokaże, że _deploydotyczy innego repozytorium.

Anne van Rossum
źródło
0

Miałem to pytanie dwukrotnie i zawsze było to spowodowane uszkodzeniem pliku pamięci podręcznej git w moim lokalnym oddziale. Naprawiłem to, zapisując brakujący skrót zatwierdzenia w tym pliku. Otrzymałem właściwy hash commita z serwera i uruchomiłem lokalnie następujące polecenie:

cat .git/refs/remotes/origin/feature/mybranch \
echo 1edf9668426de67ab764af138a98342787dc87fe \
>> .git/refs/remotes/origin/feature/mybranch
user1106400
źródło
0

Problem: Twoja gałąź jest oparta na `` źródle / wzorcu '', ale upstream zniknął.

Rozwiązanie: git branch --unset-upstream

reecha soni
źródło
3
Witamy w stackoverflow. Nie chodzi o to, jak można naprawić błąd, chce wiedzieć, dlaczego ten błąd jest podnoszony i czy powinien coś z tym zrobić. Proszę odnieść się do tego w swojej odpowiedzi.
cronoik
0

usuń swój lokalny oddział, wykonując następujące polecenie

git branch -d branch_name

możesz też zrobić

git branch -D branch_name 

który w zasadzie wymusza usunięcie (nawet jeśli lokalny nie jest scalony ze źródłem)

Pravin
źródło