Dlaczego gałąź git status show jest aktualna, gdy zmiany występują wcześniej?

226

Zmiany istnieją powyżej w śledzonej gałęzi, ale gdy piszę git status, oznacza to, że moja lokalna gałąź jest aktualna. Czy to nowe zachowanie, czy zmieniłem ustawienie konfiguracji, czy coś jest nie tak?

Dzięki za pomoc.

ubuntu@host:/my/repo# git status
On branch master
Your branch is up-to-date with 'origin/master'.

nothing to commit, working directory clean


ubuntu@host:/my/repo# git pull
remote: Counting objects: 11, done.
remote: Compressing objects: 100% (11/11), done.
remote: Total 11 (delta 6), reused 0 (delta 0)
Unpacking objects: 100% (11/11), done.
From bitbucket.org:my/repo
   1234567..abcdefg  master     -> origin/master
Updating 1234567..abcdefg
Fast-forward
 file1        |  1 -
 file2        | 43 +++++++++++++++++++++++++++++++++++++++++++
 file3        | 21 ++++++++++++---------
 file4        | 21 ++++++++++++---------
 4 files changed, 67 insertions(+), 19 deletions(-)
 create mode 100644 file5
GregB
źródło

Odpowiedzi:

274

Status mówi ci, że jesteś za wywołanym ref, origin/master który jest lokalnym ref w twoim lokalnym repozytorium . W takim przypadku ref ma miejsce śledzenie gałęzi w jakimś zdalnym, zwanym origin, ale status nie mówi ci nic o gałęzi na pilocie. Mówi ci o ref, który jest tylko identyfikatorem zatwierdzenia przechowywanym w twoim lokalnym systemie plików (w tym przypadku zazwyczaj jest to plik zwany .git/refs/remotes/origin/masterw twoim lokalnym repozytorium).

git pullwykonuje dwie operacje; najpierw wykonuje git fetchaktualizację zatwierdzeń w zdalnym repozytorium (które aktualizuje origin/masterref w lokalnym repozytorium), a następnie git mergełączy te zatwierdzenia z bieżącym oddziałem.

Dopóki nie zrobisz tego fetchkroku (samodzielnie lub za pośrednictwem git pull), twoje lokalne repozytorium nie ma sposobu, aby wiedzieć, że istnieją dodatkowe zatwierdzenia w górę, i git statuspatrzy tylko na twój lokalny origin/masterref.

Kiedy git statusmówi „na bieżąco”, oznacza „na bieżąco z odgałęzieniem śledzonym przez bieżący oddział”, co w tym przypadku oznacza „na bieżąco z lokalnym refaktorem o nazwie origin/master”. To tylko równoznaczne jest z „aktualnym statusem nadrzędnym, który został pobrany po raz ostatni fetch”, który nie jest tym samym, co „aktualny z aktualnym stanem nadrzędnym”.

Dlaczego to działa w ten sposób? Dobrze fetchkrokiem jest potencjalnie powolna i kosztowna operacja sieciowa. Projekt Git (i innych rozproszonych systemów kontroli wersji ) ma na celu uniknięcie operacji sieciowych, gdy jest to niepotrzebne, i jest zupełnie innym modelem niż typowy system klient-serwer, do którego przywykło wielu ludzi (chociaż, jak wskazano w komentarzach poniżej, koncepcja Gita „zdalnej gałęzi śledzenia”, która powoduje zamieszanie, nie są wspólne dla wszystkich DVCS). Korzystanie z Git w trybie offline jest całkowicie możliwe, bez połączenia ze scentralizowanym serwerem, a wynik działania git statusodzwierciedla to.

Tworzenie i przełączanie gałęzi (i sprawdzanie ich statusu) w Git powinno być lekkie, a nie czymś, co wykonuje powolne operacje sieciowe na scentralizowanym systemie. Założeniem przy projektowaniu Gita i danych git statuswyjściowych było to, że użytkownicy to rozumieją (zbyt wiele funkcji Git ma sens tylko wtedy, gdy wiesz już, jak działa Git). Wraz z przyjęciem Git przez wielu użytkowników, którzy nie znają DVCS, to założenie nie zawsze jest aktualne.

Jonathan Wakely
źródło
79
Późny komentarz, ale spotkałem się z tą samą sytuacją. Rozumiem, dlaczego git nie może wiedzieć o zmianach przed pobraniem. Ale wtedy nie powinno się mówić „na bieżąco”, co po prostu nie jest prawdą. Lepiej powiedzieć „nie mam pojęcia, co mogło się zdarzyć zdalnie”.
Droidum,
31
Może jest to ściśle logiczne, ale w ogóle nie jest rozsądne dla człowieka. Dlaczego nie zaprojektowałbyś go tak, by ZROBIĆ pobieranie, A NASTĘPNIE zadeklarować, czy jest aktualny? Lub zmień wiadomość, aby powiedzieć, co naprawdę zrobiła, np. „Twój oddział był aktualny przy użyciu„ origin / master ”, kiedy ostatnio sprawdzono o {timestamp}”? A może po prostu powiedz: „Pobierz, aby dowiedzieć się, czy Twój oddział jest aktualny”?
Colin,
25
po co w ogóle wyświetlać komunikat „Twój oddział jest aktualny”? Nie widzę sensu w poznawaniu statusu origin / master, a jeśli ma reprezentować rzeczywistą gałąź master na zdalnym źródle, to i tak wyraźnie nie ma pojęcia.
whiterook6
2
@pastullo, więc utwórz alias.
Jonathan Wakely
23
To doskonały przykład przerażającej użyteczności Gita. Uwielbiam jego moc i elastyczność, ale po prostu zmieniam komunikat na coś takiego: „Twoja gałąź jest na bieżąco z lokalną wersją„ origin / master ”. byłaby ogromna poprawa. Zamieszanie polega na tym, że lokalne źródło / master gałęzi (wzór pasuje do dowolnych pilotów / gałęzi, których używasz), który śledzi gałąź zdalną.
matthewcummings516
35

Jest tak, ponieważ Twoje lokalne repozytorium nie zalogowało się za pomocą pilotów. Aby ta praca działała zgodnie z oczekiwaniami, użyj, git fetcha następnie uruchom git statusponownie.

Ryan
źródło
7

Chociaż są to realne odpowiedzi, postanowiłem sprawdzić, czy lokalne repozytorium jest zgodne ze zdalnym, bez pobierania lub ciągnięcia. Aby zobaczyć, gdzie są moje gałęzie, używam po prostu:

git remote show origin

Zwraca wszystkie bieżące śledzone gałęzie, a co najważniejsze - informacje, czy są one aktualne, przed nimi czy za odległymi źródłami. Po powyższym poleceniu jest to przykład tego, co jest zwracane:

  * remote origin
  Fetch URL: https://github.com/xxxx/xxxx.git
  Push  URL: https://github.com/xxxx/xxxx.git
  HEAD branch: master
  Remote branches:
    master      tracked
    no-payments tracked
  Local branches configured for 'git pull':
    master      merges with remote master
    no-payments merges with remote no-payments
  Local refs configured for 'git push':
    master      pushes to master      (local out of date)
    no-payments pushes to no-payments (local out of date)

Mam nadzieję, że to komuś pomoże.

Skycube
źródło
0

„origin / master” odnosi się do poitingu do zatwierdzenia HEAD oddziału „origin / master”. Odwołanie to przyjazny dla człowieka alias do obiektu Git, zwykle obiektu zatwierdzenia. Odniesienie do „origin / master” jest aktualizowane tylko wtedy, gdy użytkownik korzysta git pushz pilota ( http://git-scm.com/book/en/v2/Git-Internals-Git-References#Remotes ).

Z poziomu katalogu głównego projektu uruchom:

cat .git/refs/remotes/origin/master

Porównaj wyświetlony identyfikator zatwierdzenia z:

cat .git/refs/heads/master

Powinny być takie same i dlatego Git twierdzi, że masterjest na bieżąco origin/master.

Kiedy biegniesz

git fetch origin master

To pobiera nowe obiekty Git lokalnie w folderze .git / objects. A Git aktualizuje .git / FETCH_HEAD, aby teraz wskazywał na ostatnie zatwierdzenie pobranej gałęzi.

Aby zobaczyć różnice między bieżącym oddziałem lokalnym a oddziałem pobranym z góry, możesz uruchomić

git diff HEAD FETCH_HEAD
Marek Stanley
źródło
1
Nie powinieneś umieszczać przedmiotów w katalogu .git, nie będzie to działać z zapakowanymi poleceniami. Opisane zachowanie pobierania dotyczy również starszych wersji git.
Andrew C,
czy origin/masterreferencje również nie są aktualizowane przez pobieranie, a także przez wypychanie?
Jonathan Wakely
Poprawny. Do tej pory korzystałem z Git 1.8.3. Mogę zauważyć, że w wersji 2.2.1 FETCH_HEAD jest aktualizowany również podczas pobierania. Również jeśli chodzi o komunikat „Twoja gałąź jest na bieżąco z…” lub „Twoja gałąź jest za… przez X zatwierdza”, pojawia się tylko wtedy, gdy lokalna gałąź śledzi daną gałąź zdalną. Aby master mógł śledzić origin / master, należy uruchomić git branch -u origin / master z master master. Jeśli nie ma śledzenia, nadal musisz uruchomić git diff.
Marek Stanley
Dobrze, więc sugeruję poprawienie stwierdzenia, że ​​odniesienie do „pochodzenia / mistrza” jest aktualizowane tylko wtedy, gdy naciskasz na pilota ”
Jonathan Wakely
0

Przyjrzyjmy się przykładowemu repozytorium git, aby sprawdzić, czy your branch (master)jest up to datez origin/master.

Sprawdź, czy lokalny master śledzi pochodzenie / master:

$ git branch -vv
* master a357df1eb [origin/master] This is a commit message

Więcej informacji o lokalnym oddziale głównym:

$ git show --summary
commit a357df1eb941beb5cac3601153f063dae7faf5a8 (HEAD -> master, tag: 2.8.0, origin/master, origin/HEAD)
Author: ...
Date:   Tue Dec 11 14:25:52 2018 +0100

    Another commit message

Sprawdź, czy origin / master jest na tym samym zatwierdzeniu:

$ cat .git/packed-refs | grep origin/master
a357df1eb941beb5cac3601153f063dae7faf5a8 refs/remotes/origin/master

Widzimy wokół siebie ten sam skrót i można śmiało powiedzieć, że gałąź jest spójna ze zdalnym, przynajmniej w bieżącym repozytorium git.

temat
źródło
0

spróbuj git add .wcześniejgit commit

Dejan Baric llevo3
źródło
0

Trywialna odpowiedź, ale w niektórych przypadkach trafna, na przykład ta, która mnie tu sprowadziła. Pracowałem w repozytorium, które było dla mnie nowe i dodałem plik, który nie był postrzegany jako nowy przez status.

W rezultacie plik pasuje do wzorca w pliku .gitignore.

krustyengineer
źródło
0

w takim przypadku użyj git add i zintegruj wszystkie oczekujące pliki, a następnie użyj git commit, a następnie git push

git add - zintegruj wszystkie pliki pedentów

git commit - zapisz commit

git push - zapisz w repozytorium

Airton Silveira
źródło