Jak sprawdzić, czy zdalne repozytorium uległo zmianie i czy muszę je pobrać?
Teraz używam tego prostego skryptu:
git pull --dry-run | grep -q -v 'Already up-to-date.' && changed=1
Ale jest raczej ciężki.
Czy jest lepszy sposób? Idealne rozwiązanie sprawdzi wszystkie odległe gałęzie i zwróci nazwy zmienionych gałęzi oraz liczbę nowych zatwierdzeń w każdej z nich.
git fetch -v --dry-run
tego potrzebujesz.Odpowiedzi:
Pierwsze użycie
git remote update
, aby zaktualizować swoje zdalne referencje. Następnie możesz zrobić jedną z kilku rzeczy, takich jak:git status -uno
poinformuje Cię, czy gałąź, którą śledzisz, znajduje się przed, za czy może się rozdzieliła. Jeśli nic nie mówi, lokalne i zdalne są takie same.git show-branch *master
pokaże zatwierdzenia we wszystkich gałęziach, których nazwy kończą się na „master” (np. master i origin / master ).Jeśli używasz
-v
zgit remote update
(git remote -v update
), możesz zobaczyć, które gałęzie zostały zaktualizowane, więc tak naprawdę nie potrzebujesz żadnych dalszych poleceń.Wygląda jednak na to, że chcesz to zrobić w skrypcie lub programie i uzyskać wartość prawda / fałsz. Jeśli tak, istnieją sposoby na sprawdzenie związku między twoim bieżącym zatwierdzeniem HEAD a szefem śledzonego oddziału, chociaż ponieważ są cztery możliwe wyniki, nie możesz zredukować go do odpowiedzi tak / nie. Jeśli jednak jesteś gotowy, aby to zrobić
pull --rebase
tego, możesz traktować „lokalny jest za”, a „lokalny jest rozbieżny” jako „trzeba ciągnąć”, a pozostałe dwa jako „nie trzeba ciągnąć”.Możesz uzyskać identyfikator zatwierdzenia dowolnego używanego ref
git rev-parse <ref>
, więc możesz to zrobić dla master i origin / master i porównać je. Jeśli są równe, gałęzie są takie same. Jeśli są nierówne, chcesz wiedzieć, co jest przed sobą. Użyciegit merge-base master origin/master
powie ci wspólnego przodka obu gałęzi, a jeśli się nie rozejdą, będzie to to samo, co jedno lub drugie. Jeśli otrzymasz trzy różne identyfikatory, gałęzie się rozeszły.Aby to zrobić poprawnie, np. W skrypcie, musisz mieć możliwość odniesienia do bieżącej gałęzi, a gałąź zdalna śledzi ją. Funkcja ustawiania znaku zachęty w bash
/etc/bash_completion.d
zawiera użyteczny kod do pobierania nazw oddziałów. Jednak prawdopodobnie nie potrzebujesz nazwisk. Git ma kilka schludnych skrótów do odwoływania się do gałęzi i zatwierdzeń (jak udokumentowano wgit rev-parse --help
). W szczególności możesz użyć@
dla bieżącej gałęzi (zakładając, że nie jesteś w stanie odłączonym) i@{u}
dla jej gałęzi upstream (nporigin/master
.). Zwróci więcgit merge-base @ @{u}
(mieszanie) zatwierdzenie, w którym rozbieżność obecnego odgałęzienia i jego górnego biegu,git rev-parse @
igit rev-parse @{u}
da ci skróty dwóch wskazówek. Można to streścić w następującym skrypcie:Uwaga: starsze wersje git nie pozwalały
@
same, więc może być konieczne użycie@{0}
zamiast tego.Linia
UPSTREAM=${1:-'@{u}'}
pozwala opcjonalnie przekazać jawnie gałąź nadrzędną, na wypadek, gdybyś chciał sprawdzić inną gałąź zdalną niż ta skonfigurowana dla bieżącej gałęzi. Zwykle ma to postać remotename / branchname . Jeśli nie podano żadnego parametru, wartością domyślną jest@{u}
.Skrypt zakłada, że zrobiłeś pierwszy
git fetch
lubgit remote update
pierwszy, aby zaktualizować gałęzie śledzące. Nie wbudowałem tego w skrypt, ponieważ jest bardziej elastyczne, aby móc pobierać i porównywać jako osobne operacje, na przykład jeśli chcesz porównać bez pobierania, ponieważ ostatnio został pobrany.źródło
git status -s -u no
, co daje krótszy wynik niżgit status -u no
.git remote -v update
. Spójrz na wynikgit remote --help
pełnego wyjaśnienia.@{u}
działa z git 1.8.3.2, ale@
nie działa. Jednak@
współpracuje z1.8.5.4
. Morał tej historii: git ciągle się poprawia i warto mieć najnowszą wersję, jaką możesz.Jeśli masz oddział upstream
Jeśli nie masz oddziału upstream
Porównaj dwie gałęzie:
Na przykład:
(Zakładam, że
origin/master
jest to Twój oddział zdalnego śledzenia)Jeśli jakieś zatwierdzenia są wymienione w wynikach powyżej, oznacza to, że masz nadchodzące zmiany - musisz je scalić. Jeśli do tej
git log
pory nie wymieniono żadnych zatwierdzeń, nie ma nic do scalenia.Zauważ, że to zadziała, nawet jeśli jesteś na gałęzi funkcji - która nie ma zdalnego śledzenia, ponieważ jeśli jest to jawne odniesienie
origin/master
zamiast domyślnego użycia odgałęzienia zapamiętanego przez Git.źródło
git fetch; git log HEAD.. --oneline
można użyć, jeśli istnieje domyślna gałąź zdalna dla gałęzi lokalnej.git rev-list HEAD...origin/master --count
da ci całkowitą liczbę „różnych” zatwierdzeń między nimi.Jeśli dotyczy to skryptu, możesz użyć:
(Uwaga: zaletą tej i poprzednich odpowiedzi jest to, że nie potrzebujesz osobnego polecenia, aby uzyskać nazwę bieżącej gałęzi. Zajmij się nią „HEAD” i „@ {u}” (poprzednia gałąź obecnego). Zobacz „git rev-parse --help”, aby uzyskać więcej informacji.)
źródło
git rev-parse @{u}
faktycznie pokaże ostatnie zatwierdzenie bezgit fetch
?==
co oznacza „jeśli nie ma żadnych zmian w stosunku do wcześniejszego”. Kiedyś!=
sprawdzałem, czy w mojej aplikacji nie ma „zmian w górę”. Nie zapomnijgit fetch
najpierw!@
jest skrótem odHEAD
btw.@{u}
przykład np.git rev-parse '@{u}'
Komenda
wyświetli aktualną pozycję na pilocie - możesz porównać ją z poprzednią wartością lub sprawdzić, czy masz SHA w lokalnym repozytorium.
źródło
git rev-list HEAD...origin/master --count
da ci całkowitą liczbę „różnych” zatwierdzeń między nimi.git fetch
lubgit remote update
pierwszy.git status
pokazuje również liczbę, btw...
to „ commits in origin / master, odejmując HEAD” (tzn. Liczba commits za). Natomiast...
jest symetryczna różnica (tj. Przód i tył)fetch
.Oto linijka Bash, która porównuje hash zatwierdzenia HEAD z bieżącej gałęzi z jego zdalnym odgałęzieniem, nie wymaga ciężkich operacji
git fetch
anigit pull --dry-run
operacji:Oto jak rozkłada się ta nieco gęsta linia:
$(x)
Bash -podstawiania poleceń .git rev-parse --abbrev-ref @{u}
zwraca skrócone odwołanie zwrotne (np.origin/master
), które jest następnie konwertowane na pola rozdzielone spacjami za pomocąsed
polecenia potokowego , nporigin master
.git ls-remote
który zwraca zatwierdzenie głowy zdalnej gałęzi. To polecenie komunikuje się ze zdalnym repozytorium. Polecenie potokowecut
wyodrębnia tylko pierwsze pole (skrót zatwierdzenia), usuwając ciąg odwołania oddzielony tabulatorami.git rev-parse HEAD
zwraca lokalny skrót zatwierdzenia.[ a = b ] && x || y
uzupełnia jednowierszową: jest to porównanie=
ciągu Bash w konstrukcie testowym[ test ]
, a następnie konstrukcje and-list i or-list&& true || false
.źródło
Radzę zobaczyć skrypt https://github.com/badele/gitcheck . Zakodowałem ten skrypt do sprawdzenia w jednym przejściu wszystkich repozytoriów Git i pokazuje, kto nie popełnił, a kto nie wypchnął / nie wyciągnął.
Oto przykładowy wynik:
źródło
git mrepo -c
spowoduje to wyświetlenie wszystkich oczekujących zmian.Oparłem to rozwiązanie na komentarzach @jberger.
źródło
...
wydaje się być prawidłową częścią twojego rozwiązania.Istnieje już wiele bardzo bogatych w funkcje i genialnych odpowiedzi. Aby zapewnić pewien kontrast, mógłbym zadowolić się bardzo prostą linią.
źródło
Myślę, że najlepszym sposobem na to byłoby:
Zakładając, że masz ten refspec zarejestrowany. Powinieneś, jeśli sklonowałeś repozytorium, w przeciwnym razie (tj. Jeśli repo zostało utworzone de novo lokalnie i przekazane do zdalnego), musisz wyraźnie dodać refspec.
źródło
Poniższy skrypt działa idealnie.
źródło
Zrobiłbym sposób sugerowany przez Bro. Poniższy skrypt jednowierszowy pobiera SHA1 ostatniej zatwierdzonej wersji i porównuje go ze zdalnym źródłem i pobiera zmiany tylko wtedy, gdy się różnią. I to jeszcze bardziej lekkie rozwiązania oparte na
git pull
lubgit fetch
.źródło
git rev-parse --verify HEAD
git log --pretty=%H ...refs/heads/master^
aby uzyskać SHA1 ostatniej zatwierdzonej wersji, a następnie uruchom,git ls-remote origin -h refs/heads/master |cut -f1
aby uzyskać SHA1 zdalnego pochodzenia. Te dwa są poleceniami git i nie mają nic wspólnego z bash. Bash wewnątrz nawiasów kwadratowych polega na porównaniu danych wyjściowych z pierwszego polecenia z drugim, a jeśli są równe, zwraca wartość true i uruchamia sięgit pull
.git pull
". Wiem, że jestem podejrzany, ale żeby uratować kogoś od zamieszania, powinno to być „a jeśli nie równe”. Ponadto, z jakiegokolwiek powodu, pierwsze polecenie git nie działa dla mnie. (Jestem na git2.4.1
.) Więc używamgit log --pretty=%H master | head -n1
zamiast tego. Ale nie jestem pewien, czy to dokładnie to samo.Jeśli uruchomisz ten skrypt, sprawdzi, czy bieżąca gałąź potrzebuje
git pull
:Jest to bardzo wygodne, aby umieścić go jako wstępny zatwierdzenie haka Git, aby uniknąć
kiedy ty
commit
wcześniejpulling
.Aby użyć tego kodu jako haka, po prostu skopiuj / wklej skrypt
i
źródło
Chcę tylko opublikować ten post jako rzeczywisty, ponieważ łatwo go przeoczyć w komentarzach.
Prawidłowa i najlepsza odpowiedź na to pytanie została udzielona przez @Jake Berger, Dziękuję bardzo, wszyscy tego potrzebują i wszyscy tęsknią w komentarzach. Więc dla wszystkich, którzy zmagają się z tym, tutaj jest poprawna odpowiedź, wystarczy użyć danych wyjściowych tego polecenia, aby wiedzieć, czy musisz wykonać polecenie git pull. jeśli wyjście ma wartość 0, to oczywiście nie ma nic do zaktualizowania.
@stackoverflow, daj temu facetowi dzwonki. Dzięki @ Jake Berger
źródło
Uruchom,
git fetch (remote)
aby zaktualizować swoje zdalne referencje, pokaże ci, co nowego. Następnie, gdy kasujesz swój lokalny oddział, pokaże ci, czy jest on z tyłu.źródło
git status
to pokaże.git pull --dry-run
, ale myślę, że jest to zbyt trudne do uruchomienia skryptu cron co minutę.fetch
, nie zrobisz nic poza sprawdzeniem statusu. Jeśli potrzebujesz bardzo szybkiej i lekkiej reakcji na zdalne aktualizacje, możesz zajrzeć do przechwytywania pewnego rodzaju powiadomień do zdalnego repozytorium.Wszystkie takie złożone sugestie, podczas gdy rozwiązanie jest tak krótkie i łatwe:
źródło
git remote update
wykonania przed kodem, aby uzyskać najnowsze informacje o zatwierdzeniu pochodzeniagit remote update
Nie powinien dołączać przedgit show
poleceniami?Oto moja wersja skryptu Bash, który sprawdza wszystkie repozytoria w predefiniowanym folderze:
https://gist.github.com/henryiii/5841984
Może rozróżniać typowe sytuacje, takie jak potrzeba ściągania i potrzeba push, i jest wielowątkowy, więc pobieranie odbywa się od razu. Ma kilka poleceń, takich jak pull i status.
Umieść dowiązanie symboliczne (lub skrypt) w folderze na swojej ścieżce, a następnie działa jako
git all status
(itp.). Obsługuje tylko origin / master, ale można go edytować lub łączyć z inną metodą.źródło
wyświetli listę wszystkich odnośników w dowolnym pilocie, którego nie ma w repozytorium. Aby przechwycić zmiany zdalnych zmian w rzeczach, które już miałeś (np. Resetuje poprzednie zatwierdzenia), potrzebujesz trochę więcej:
źródło
Może to, jeśli chcesz dodać zadanie jako crontab:
źródło
Za pomocą prostego wyrażenia regularnego:
źródło
Używam wersji skryptu opartej na odpowiedzi Stephena Habermana:
Zakładając, że ten skrypt jest wywoływany
git-fetch-and-rebase
, można go wywołać z opcjonalnym argumentemdirectory name
lokalnego repozytorium Git w celu wykonania operacji. Jeśli skrypt jest wywoływany bez argumentów, zakłada, że bieżący katalog jest częścią repozytorium Git.Przykłady:
Jest on również dostępny tutaj .
źródło
Po przeczytaniu wielu odpowiedzi i wielu postów i spędzeniu pół dnia na próbach różnych permutacji, właśnie to wymyśliłem.
Jeśli korzystasz z systemu Windows, możesz uruchomić ten skrypt w systemie Windows przy użyciu Git Bash dostarczonego przez Git dla Windows (instalacyjny lub przenośny).
Ten skrypt wymaga argumentów
Skrypt będzie
Jeśli pojawi się zmiana wydrukowana przez skrypt, możesz przystąpić do pobierania lub pobierania. Skrypt może nie być wydajny, ale wykonuje zadanie za mnie.
Aktualizacja - 30.10.2015: stderr na dev null, aby zapobiec drukowaniu adresu URL z hasłem do konsoli.
źródło
Dla użytkowników systemu Windows, którzy szukają tego pytania, zmodyfikowałem część odpowiedzi w skrypcie PowerShell. Dostosuj w razie potrzeby, zapisz do
.ps1
pliku i uruchom na żądanie lub zaplanuj, jeśli chcesz.źródło
Ponieważ odpowiedź Neilsa bardzo mi pomogła, oto tłumaczenie Pythona bez żadnych zależności:
hth
źródło
Możesz także znaleźć skrypt Phing, który teraz to robi.
Potrzebowałem rozwiązania do automatycznej aktualizacji środowisk produkcyjnych i jesteśmy bardzo zadowoleni z tego skryptu, który udostępniam.
Skrypt jest napisany w formacie XML i wymaga phing .
źródło