jak wciągać do wielu gałęzi jednocześnie za pomocą git?


13

W repozytorium mam wiele gałęzi, w tym „master” i „develop”, które są skonfigurowane do śledzenia zdalnych gałęzi „origin / master” i „origin / develop”.

Czy można określić, że chcę, aby zarówno master, jak i developerskie były jednocześnie łączone (szybkie przekazywanie)?

Kiedy to robię git pull, dostaję coś takiego:

remote: Counting objects: 92, done.
remote: Compressing objects: 100% (56/56), done.
remote: Total 70 (delta 29), reused 28 (delta 8)
Unpacking objects: 100% (70/70), done.
From scm.my-site.com:my-repo
   5386563..902fb45  develop    -> origin/develop
   d637d67..ba81fb2  master     -> origin/master
Updating 5386563..902fb45
Fast-forward

wszystkie zdalne gałęzie są pobierane, ale tylko gałąź, na której aktualnie się znajduję, jest scalana z odpowiadającą jej gałęzią zdalną.

Więc muszę zrobić git checkout master...

Switched to branch 'master'
Your branch is behind 'origin/master' by 106 commits, and can be fast-forwarded.

... i git pulljeszcze raz, a następnie wróć do rozwijania, aby uzyskać pożądany efekt.

Wiem, że mogę tworzyć aliasy / skrypty, które wykonują te kroki. Ale chcę tego uniknąć, jeśli to możliwe, ponieważ jest to podatne na błędy i niezbyt wydajne .
Edycja: ok, pozwól mi to przeformułować. Moim celem nie było zniechęcanie ani marszczenie brwi podczas dostosowywania skryptu / aliasu do git. Wolałbym tylko wbudowane rozwiązanie, jeśli istnieje :)


Próbowałem, git pull origin refs/heads/develop:refs/remotes/origin/develop refs/heads/master:refs/remotes/origin/masterale spowodowało to połączenie zdalnego mistrza w
programowanie

1
Dlaczego miałoby być podatne na błędy lub nieefektywne? Git ma być dostosowywany w ten sposób. BTW, aby uniknąć konieczności sprawdzania każdej gałęzi, możesz podzielić ją pullna fetchnastępującą po niej mergena każdą gałąź.
jjlin

@jjlin dobrze, jeśli mogę to zrobić bez sprawdzania każdego oddziału, który może pomóc w wydajności. Jest podatny na błędy, ponieważ matryca rzeczy, które mogą pójść nie tak, a skutki, jakie może wywierać na resztę skryptu, są dość złożone. Nie twierdzę, że zapewnienie bezpieczeństwa jest nierealne, ale byłby to kompromis. Wolałbym więc wbudowane rozwiązanie, jeśli istnieje :)
Superole

Odpowiedzi:


11

Możesz ustawić alias, który będzie używany git fetchz parametrami refspecs, aby szybko połączyć gałęzie za pomocą jednego polecenia. Ustaw jako alias w .gitconfigpliku użytkownika :

[alias]
    sync = "!sh -c 'git checkout --quiet --detach HEAD && \
                    git fetch origin master:master develop:develop ; \
                    git checkout --quiet -'"

Zastosowanie: git sync.

Oto dlaczego to działa:

  1. git checkout --quiet HEADbezpośrednio sprawdza bieżące zatwierdzenie, wprowadzając cię w stan odłączonej głowy . W ten sposób, jeśli jesteś włączony masterlub developodłączysz kopię roboczą od tych wskaźników gałęzi, umożliwiając ich przeniesienie (Git nie pozwoli ci przenieść odniesień do gałęzi, gdy kopia robocza ma je wyewidencjonowane).

  2. git fetch origin master:master develop:developużywa refspecs z w fetchcelu szybkiego przewijania gałęzi masteri developw lokalnym repozytorium. Składnia w zasadzie mówi Gitowi „tutaj jest refspec formularza <source>:<destination>, weź go <destination>i przewiń do przodu w tym samym punkcie co <source>”. Tak więc źródłami w aliasie są gałęzie origin, a miejscami docelowymi są lokalne wersje repo tych gałęzi.

  3. Na koniec git checkout --quiet -sprawdź gałąź, w której byłeś ostatnio, niezależnie od tego, czy w poprzednich poleceniach wystąpił błąd. Więc jeśli byłeś włączony, mastergdy biegałeś git synci wszystko się powiedzie, pozostawisz odłączony stan głowy i przejrzysz nowo zaktualizowaną wersję master.

Zobacz także moją odpowiedź na git: zaktualizować lokalny oddział bez sprawdzania go? .


Nie do końca rozumiem oddzielną magię tutaj, dlaczego wskaźnik do opanowania nie może zostać przesunięty, gdy program jest sprawdzany? ... zresztą próbowałem tego i wydaje się, że działa, ale teraz otrzymuję komunikat: „Twój oddział wyprzedza„ pochodzenie / rozwój ”o 1 zatwierdzenie.”
Superole,

... co zostało rozwiązane przy następnym pociągnięciu
Superole

@Superole, która gałąź wyprzedza origin/developużycie aliasu? Nie miałoby to sensu, gdyby był to lokalny developoddział. Wskaźnik master można również przenieść, jeśli developjest wyrejestrowany, chodzi o to, że jeśli masterjest wyrejestrowany, nie można przewinąć do przodu, masterponieważ wpłynęłoby to na kopię roboczą, dlatego odłącza się kopię roboczą od niego za pomocą git checkout head. Widziałem inną odpowiedź, która opisywała to jako „stanie na skale”, musisz zejść ze skały, zanim będziesz mógł ją przenieść.
40XUserNotFound

to rzeczywiście był mój lokalny rozwój. Powodem musi być to, że to pobieranie nie aktualizuje gałęzi śledzenia. Tak jak rozumiem; ściągnięcie zostanie pobrane do źródła / rozwinięcia, a następnie scalone do rozwinięcia.
Superole,

Bardzo ważne jest, aby ta odpowiedź spowodowała fatal: bad config line xx in file xxx. który jest spowodowany średnikiem. musisz zawinąć całe polecenie w podwójny cudzysłów, aby uniknąć tego problemu.
William Leung

1

Zainstaluj git-up . Daje ci polecenie, git-upktóre wyciągnie wszystkie lokalne oddziały z twojego repozytorium.


Słodkie! Na pewno to sprawdzę.
Superole,

2
heh: P Stwierdzenia, że obsługa systemu Windows jest przewidywalnie nieobecna. i jeszcze nie sformułowano rygorystycznego dowodu, że na pewno nie zadziała z twoją konfiguracją gita, nie usunie danych ani nie opublikuje szalonego napędu w Hacker News w twoim imieniu. , w połączeniu z potrzebą Ruby, odwiodło mnie. Jednak podoba mi się ta koncepcja.
Superole,

Cieszę się, że nie jest to metoda w ogóle ... trochę sucky, mimo że każda metoda wymaga trochę narzędzia innej firmy. Takich jak ten i te z niektórymi „recepturami” poleceń powłoki lub aliasami korzystającymi z konkretnej powłoki (specyficznej dla platformy).
0xC0000022L

0

Wygląda na to, że git nie ma wbudowanej opcji przyciągania do wielu gałęzi. Przynajmniej nie w wersji 1.8.0. chociaż odpowiedź @ Cupcake jest bliska.

Jednak komentarz @ jjlin uświadomił mi, że przynajmniej nie muszę ciągnąć dwa razy.

Tak więc nieco bardziej wydajna sekwencja to:

git pull
git checkout master
git merge origin/master
git checkout -

Nieuchronnie skończyłem z tworzeniem aliasu, ale postanowiłem zrezygnować z tego i skupiłem się na szybkim przewijaniu innej gałęzi.

[alias]
ffwd = "!_() { git checkout $1 && git merge --ff-only origin/$1 && git checkout -; }; _"

Oczywiście bez testowania ten alias zakłada, że ​​podam poprawną nazwę gałęzi ff'able jako pierwszy argument, a poza tym zachowuje się niezdefiniowane. Nie jest również optymalny dla przypadków użycia z więcej niż dwoma gałęziami, ale dostanie to, czego teraz potrzebuję.

git pull
git ffwd master
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.