Często mam co najmniej 3 odległe gałęzie: master, inscenizację i produkcję. Mam 3 lokalne oddziały, które śledzą te odległe gałęzie.
Aktualizacja wszystkich moich lokalnych oddziałów jest żmudna:
git fetch --all
git rebase origin/master
git checkout staging
git rebase origin/staging
git checkout production
git rebase origin/production
Chciałbym móc po prostu wykonać „git pull-all”, ale nie byłem w stanie zmusić go do działania. Wygląda na to, że wykonuje „pobieranie - wszystko”, a następnie aktualizuje (przewija do przodu lub łączy) bieżącą działającą gałąź, ale nie inne lokalne gałęzie.
Nadal utknąłem ręcznie, przełączając się do każdego lokalnego oddziału i aktualizując.
Odpowiedzi:
Opisane zachowanie
pull --all
jest dokładnie zgodne z oczekiwaniami, choć niekoniecznie przydatne. Przekazywana jest opcja git fetch, która następnie pobiera wszystkie referencje ze wszystkich pilotów, zamiast tylko potrzebnej;pull
następnie scala (lub w twoim przypadku zmienia bazę) odpowiedni pojedynczy oddział.Jeśli chcesz sprawdzić inne oddziały, musisz je sprawdzić. I tak, łączenie (i przekształcanie) absolutnie wymaga drzewa roboczego, więc nie można tego zrobić bez sprawdzenia innych gałęzi. Jeśli chcesz, możesz zawinąć opisane kroki w skrypt / alias, chociaż sugeruję łączenie poleceń z nimi
&&
, aby w razie niepowodzenia jednego z nich nie próbowało się przeorać.źródło
Używam
sync
komendy z piastą zautomatyzować ten. Mamalias git=hub
w sobie.bash_profile
, więc polecenie, które wpisuję to:To aktualizuje wszystkie lokalne gałęzie, które mają pasującą gałąź nadrzędną. Ze strony podręcznika:
Obsługuje również ukrywanie / odblokowywanie niezatwierdzonych zmian w bieżącym oddziale.
Kiedyś korzystałem z podobnego narzędzia o nazwie git-up , ale nie jest ono już utrzymywane i
git sync
robi prawie dokładnie to samo.źródło
git config --global git-up.rebase.auto false
.Wiem, że to pytanie ma prawie 3 lata, ale zadałem sobie to samo pytanie i nie znalazłem gotowego rozwiązania. Więc stworzyłem własny skrypt powłoki poleceń git.
Oto
git-ffwd-update
skrypt:git remote update
aby pobrać ostatnie obrotygit remote show
aby uzyskać listę lokalnych gałęzi, które śledzą gałąź zdalną (np. gałęzie, których można używaćgit pull
)git rev-list --count <REMOTE_BRANCH>..<LOCAL_BRANCH>
ile zatwierdzeń oddział lokalny znajduje się za pilotem (i na odwrót)git branch -f <LOCAL_BRANCH> -t <REMOTE_BRANCH>
skrypt można wywołać w następujący sposób:
Pełny skrypt powinien zostać zapisany
git-ffwd-update
i musi być włączonyPATH
.źródło
git branch
wywołania. Usunąłem opcję -l, aby zmienić wywołanie na,git branch -f $LB -t $ARB >/dev/null;
a teraz skrypt działa tak, jak powinien.Zautomatyzowanie nie jest takie trudne:
źródło
git rebase origin/$branch
nagit pull
, aby pobierał z odpowiedniej gałęzi śledzenia (przypuszczalnie na początku) i łączył lub rebase zgodnie z konfiguracją.fetch
. Edytowałem; dodatkowe funkcje / poprawki, cokolwiek zależy od OP.pull
(lub sprawdzićbranch.<branch>.rebase
), aby przypadkowo nie zmienić podstawy gałęzi skonfigurowanej do normalnego ściągania (scalania).set -e
zamiast,|| exit 1
aby interpreter zakończył działanie po pierwszym błędzie.To wciąż nie jest automatyczne, ponieważ chciałbym, aby istniała opcja - i powinna być pewna kontrola, aby upewnić się, że może się to zdarzyć tylko w przypadku aktualizacji do przodu (dlatego ręczne wykonanie ściągania jest znacznie bezpieczniejsze !!), ale poza tym możesz:
zaktualizować pozycję lokalnego oddziału bez konieczności sprawdzania go.
Uwaga: stracisz aktualną pozycję oddziału i przeniesiesz ją do miejsca, w którym znajduje się gałąź pochodzenia, co oznacza, że jeśli chcesz połączyć, stracisz dane!
źródło
git fetch origin other-branch:other-branch
Istnieje wiele odpowiedzi tutaj, ale żadna z nich nie służy
git-fetch
do bezpośredniej aktualizacji lokalnego ref, co jest o wiele prostsze niż sprawdzanie oddziałów i bezpieczniejsze niżgit-update-ref
.Tutaj używamy
git-fetch
do aktualizacji oddziałów nieprądowych igit pull --ff-only
dla bieżącego oddziału. To:a oto:
Z strony podręcznika dla
git-fetch
:Określając
git fetch <remote> <ref>:<ref>
(bez żadnego+
) otrzymujemy pobranie, które aktualizuje referencję lokalną tylko wtedy, gdy można ją szybko przesłać dalej.Uwaga : zakłada się, że lokalne i zdalne gałęzie mają takie same nazwy (i że chcesz śledzić wszystkie gałęzie), to naprawdę powinno używać informacji o tym, jakie lokalne gałęzie masz i jakie są skonfigurowane do śledzenia.
źródło
c*n
kroki (zamiast 1), gdziec
jest pewna liczba powtarzanych poleceń in
liczba gałęzi.git branch -r | grep -v ' -> ' | while read remotebranch
abygit branch -r | grep -v ' -> ' | grep -f <(git branch | cut -c 3- | awk '{print "\\S*/"$0"$"}') | while read remotebranch
ograniczyć je do oddziałów, które już posiadam lokalnie. Dodałem teżgit fetch --prune
na początku, aby zaktualizować listę zdalnych gałęzi przed zrobieniem czegokolwiek, co pozwala uniknąć ostrzeżeń.Ten problem nie został (jeszcze) rozwiązany, przynajmniej nie łatwo / bez skryptów: zobacz ten post na liście mailowej git autorstwa Junio C. Hamano, wyjaśniając sytuację i podając wezwanie do prostego rozwiązania.
Głównym powodem jest to, że nie powinieneś tego potrzebować:
Zaproszenie do rozwiązania polegało na wybraniu opcji lub zewnętrznego skryptu do przycinania lokalnych oddziałów, które następują teraz po oddziałach zdalnego śledzenia, zamiast utrzymywania ich na bieżąco poprzez szybkie przekazywanie, tak jak zażądano oryginalnego plakatu.
Uwaga: od wersji 2.10 takiego rozwiązania nie ma. Zauważ, że
git remote prune
podkomendagit fetch --prune
dotyczy usuwania gałęzi zdalnego śledzenia dla gałęzi, która już nie istnieje na pilocie, a nie usuwania lokalnej gałęzi, która śledzi gałąź zdalnego śledzenia (dla której gałąź zdalnego śledzenia jest odgałęzieniem powyżej).źródło
Istnieje wiele akceptowalnych odpowiedzi, ale niektóre instalacje mogą być nieco nieprzejrzyste dla niewtajemniczonych. Oto znacznie prostszy przykład, który można łatwo dostosować:
Jeśli dodasz
~/bin/git
doPATH
(zakładając, że plik jest~/bin/git/git-update-all
), możesz po prostu uruchomić:źródło
Dodaj ten skrypt do
.profile
systemu Mac OS X:źródło
Oto dobra odpowiedź: Jak pobrać wszystkie gałęzie git
źródło
git fetch
agit pull
nie tylkogit pull
?origin/
prefiksemSkrypt, który napisałem dla mojego GitBash . Wykonuje następujące czynności:
git checkout branch
git pull origin
** Używam tego, ale nie przetestowałem dokładnie, używam na własne ryzyko. Zobacz przykład tego skryptu w pliku .bash_alias tutaj .
źródło
Jeśli korzystasz z systemu Windows, możesz użyć PyGitUp, który jest klonem
git-up
Pythona. Możesz zainstalować go za pomocą pip zpip install --user git-up
lub za pomocą Scoop za pomocąscoop install git-up
[
źródło
Po prostu opublikowałem zaktualizowaną odpowiedź.
git-up
nie jest już utrzymywany, a jeśli czytasz dokumentację, wspominają, że funkcjonalność jest teraz dostępna w git .Możesz również ustawić to dla każdego
git pull
Gita 2.9 (dzięki @VonC proszę zobaczyć jego odpowiedź tutaj )źródło
git-up
dokumentacji, ponieważ nie wspomnieć, żegit-up
.git-up
:)Natknąłem się na ten sam numer tego pytania ...
Zastanawiając się nad tym, zrobiłem małą funkcję aliasu w moim
.bashrc
pliku:Pracował dla mnie (:
źródło
Jeśli refs / heads / master można szybko przewinąć do refs / remotes / foo / master , wyjście z
powinien zwrócić identyfikator SHA1, który odnosi się do / heads / master points. Dzięki temu możesz utworzyć skrypt, który automatycznie aktualizuje wszystkie lokalne oddziały, które nie miały przypisanych poleceń przekierowania.
Ten mały skrypt powłoki (nazwałem go git-can-ff ) ilustruje, jak można to zrobić.
źródło
Aby uzupełnić odpowiedź Matta Connolly'ego, jest to bezpieczniejszy sposób aktualizowania odniesień do lokalnego oddziału, który można szybko przesłać bez konieczności sprawdzania oddziału. Nie aktualizuje gałęzi, których nie można szybko przesłać (tj. Które się rozeszły), i nie aktualizuje gałęzi, która jest obecnie wyewidencjonowana (ponieważ wtedy kopia robocza również powinna zostać zaktualizowana).
źródło
Nieco inny skrypt, który tylko przewija gałęzie, których nazwy pasują do ich gałęzi upstream. Aktualizuje również bieżący oddział, jeśli możliwe jest szybkie przewijanie do przodu.
Upewnij się, że wszystkie odgałęzienia gałęzi są ustawione poprawnie, uruchamiając
git branch -vv
. Ustaw gałąź upstream za pomocągit branch -u origin/yourbanchname
Skopiuj-wklej do pliku i chmod 755:
źródło
Następujący jednowierszowy przesyła dalej wszystkie gałęzie, które mają gałąź nadrzędną, jeśli to możliwe, aw przeciwnym razie drukuje błąd:
Jak to działa?
Korzysta z niestandardowego formatu
git branch
polecenia. Dla każdej gałęzi, która ma gałąź wyższą, drukuje linię o następującym wzorze:Można to przesłać bezpośrednio
sh
(zakładając, że nazwy gałęzi są dobrze uformowane). Pomiń| sh
aby zobaczyć, co robi.Ostrzeżenia
One-liner nie skontaktuje się z Twoimi pilotami. Wydaj a
git fetch
lubgit fetch --all
przed jego uruchomieniem.Aktualnie wyewidencjonowany oddział nie zostanie zaktualizowany komunikatem typu
W tym celu możesz skorzystać z regularnego
git pull --ff-only
.Alias
Dodaj następującą do
.gitconfig
tak, żegit fft
wykonuje tę komendę:Zobacz także moje
.gitconfig
. Alias to skrót od „szybkiego przewijania do przodu (gałęzie)”.źródło
hub
soluction propsed przez @John za to lepsze wyjście.git push
że jest całkowicie przeciwne do tego, czego można się spodziewać. Jaki jest sekret?git push
?git push
ma semantykę przesyłania - mam pewne zatwierdzenia lokalnie, które chcę wysłać w górę.git pull
ma semantykę pobierania - chcę uzyskać jakieś zdalne polecenia zatwierdzające w moim lokalnym oddziale. Ponieważ mówimy o pobieraniu nowych zatwierdzeń ze zdalnego do lokalnego,git pull
jest oczywistym wyborem. Ale nie, ta sztuczka wykorzystujegit push
. W jaki sposóbgit push
powodują zdalne zmiany w moim oddziale lokalnym ?!git push
może być również użyty do aktualizacji lokalnych oddziałów, o ile jest to aktualizacja do przodu.Skrypt z @larsmans, nieco ulepszony:
To po zakończeniu pozostawia kopię roboczą wypisaną z tego samego oddziału co przed wywołaniem skryptu.
git pull
Wersja:źródło
Wygląda na to, że wiele innych wniosło podobne rozwiązania, ale pomyślałem, że podzielę się tym, co wymyśliłem i zaprosię innych do współpracy. To rozwiązanie ma ładne kolorowe wyjście, z wdziękiem obsługuje bieżący katalog roboczy i jest szybkie, ponieważ nie wykonuje żadnych transakcji i pozostawia katalog roboczy w takcie. Jest to również skrypt powłoki bez żadnych zależności innych niż git. (do tej pory testowane tylko na OSX)
https://github.com/davestimpert/gitup
Niestety wydaje mi się, że wymyśliłem tę samą nazwę, co inne narzędzie powyżej.
źródło
Można to zrobić za pomocą poniższego skryptu ... Najpierw pobierze wszystkie gałęzie i pobierze je pojedynczo, a następnie zaktualizuje samo.
źródło
Nie możesz tego zrobić za pomocą jednego polecenia git, ale możesz zautomatyzować to za pomocą jednej linii bash.
Aby bezpiecznie zaktualizować wszystkie gałęzie za pomocą jednej linii, oto co robię:
Jeśli nie może przewinąć do przodu jednej gałęzi lub napotka błąd, zatrzyma się i pozostawi cię w tej gałęzi, abyś mógł odzyskać kontrolę i scalić ręcznie.
Jeśli wszystkie gałęzie mogą być przewijane do przodu, zakończy się na gałęzi, w której się znajdowałeś, pozostawiając cię tam, gdzie byłeś przed aktualizacją.
Objaśnienia:
Dla lepszej czytelności można go podzielić na kilka wierszy:
git fetch --all && ...
=> Pobiera wszystkie referencje ze wszystkich pilotów i kontynuuje następną komendę, jeśli nie wystąpił błąd.git branch | sed '/*/{$q;h;d};$G' | tr -d '*'
=> Z wyjściagit branch
,sed
podejmuje linii z*
i przenieść go do końca (tak, że obecny oddział będzie aktualizowana na końcu). Następnietr
po prostu usuń*
.for branch in $(...) ; do git checkout $branch && git merge --ff-only || break ; done
=> Dla każdej nazwy gałęzi uzyskanej z poprzedniego polecenia, sprawdź tę gałąź i spróbuj połączyć się z przewijaniem do przodu. Jeśli się nie powiedzie,break
jest wywoływane, a polecenie zatrzymuje się tutaj.Oczywiście, można zastąpić
git merge --ff-only
zegit rebase
jeśli to, co chcesz.Wreszcie możesz umieścić go w swoim bashrc jako alias:
Lub jeśli boisz się zepsuć „i” lub po prostu wolisz zachować czytelność składniową w swoim edytorze, możesz zadeklarować to jako funkcję:
Premia:
Dla tych, którzy chcieliby wyjaśnienia ze
sed '/*/{$q;h;d};$G'
strony:/*/
=> Wyszukaj linię za pomocą*
.{$q
=> Jeśli znajduje się w ostatnim wierszu, wyjdź (nie musimy nic robić, ponieważ bieżąca gałąź jest już ostatnią na liście).;h;d}
=> W przeciwnym razie zapisz linię w buforze wstrzymania i usuń ją w bieżącej pozycji na liście.;$G
=> Gdy dojdzie do ostatniego wiersza, dodaj zawartość bufora wstrzymania.źródło
&&
ustawiając sięset -e
w górnej części skryptu.Nie, nie może. Do szybkiego przewijania napisałem tylko małe narzędzie do tego. https://github.com/changyuheng/git-fast-forward-all
Zalety tego narzędzia:
hub sync
obecnie nie obsługuje wielu pilotów).źródło
git fetch . refspec
..
Mówi się pobrać z aktualnego repozytorium zamiast z jednego pilota.Od wersji 2.9:
git pull --rebase --autostash
Zobacz https://git-scm.com/docs/git-rebase
źródło
W rzeczywistości z git
version 1.8.3.1
działa:W gałęzi głównej możesz zaktualizować wszystkie inne gałęzie. @Cascabel
Nie wiem, która wersja go zepsuje / naprawi, w 2.17 (której używam) może działać.
źródło