Jak scalić bieżącą gałąź z inną gałęzią

182

Mam dwie gałęzie, master i dev. Zawsze pracuję nad programistą i sprawdzam kod w gałęzi master dopiero po zatwierdzeniu go do użytku produkcyjnego. Kiedy to robię, muszę wykonać następujące czynności:

git checkout master
git merge dev
git checkout dev

To okropnie gadatliwe, a ponieważ często to robię, chciałbym je zminimalizować. Czy jest jakieś polecenie git, którego mogę użyć do scalenia mojego obecnego dewelopera gałęzi z drugim głównym gałęzią bez konieczności wcześniejszego pobrania głównej gałęzi? Coś może jak:

git merge dev to master

byłoby wspaniale. Przejrzałem dokumentację git i nic nie zobaczyłem.

Chris
źródło
1
Próbowałeś do tego użyć git push?
Jay Sullivan
11
Co z sugestiami push? Służy to do aktualizacji pilotów , a nie łączenia się we własnym repozytorium.
Cascabel,
4
Jefromi ma rację, push nie jest tu przydatny. Mówię o innym oddziale lokalnym, a nie odległym.
Chris
2
Jeszcze gorzej jest, gdy masz niewykorzystane lokalnych zmian: git stash, git checkout master, git merge dev, git checkout dev, git stash pop.
Mu Mind
2
Fajne pytanie. Ja też tego chciałem, ponieważ chciałem wciągnąć do oddziału prądu. Chciałem uniknąć przełączania gałęzi, ponieważ mam proces, który uruchamia kompilację, jeśli zmienią się pliki w działającym drzewie.
Kelvin

Odpowiedzi:

94

1. Dodaj zdalny alias do lokalnego repozytorium, np .:

git remote add self file:///path/to/your/repository

(Lub w systemie Windows git remote add self C:\path\to\your\repository)

2. Wciśnij do zdalnego pilota, np .:

git push self dev:master
zerome
źródło
2
Submoduły! To nie tylko rozwiązuje problem zadanego pytania, ale także rozwiązuje problem przełączania gałęzi, gdy ma się tylko podmoduł. Świetna wskazówka!
eddiemoya
2
+1 To jest kreatywne i w ogóle nie dotyka działającego drzewa. Tylko wyjaśnienie: /path/to/your/repositoryjest to ścieżka do twojego drzewa roboczego, tzn. Nie dołączaj .gitkatalogu. Ponadto powinno to być oczywiste: pilot będzie musiał zostać zaktualizowany, jeśli przeniesiesz repo.
Kelvina
Ja nie mający szczęścia otrzymuję to do pracy w oknach ... git remote add self file:///c/projectswłaśnie wraca z notami użytkowania
Maslow
2
@ JosephK.Strauss Możesz najpierw scalić master do bieżącej gałęzi ( dev), a następnie wcisnąć zatwierdzenie scalania za pomocą git push self dev:master.
Leonid Shvechikov
4
Dlaczego zdalny alias? .działało w porządku dla mnie git push . head:master.
geon
60

Obecna najlepiej głosowana odpowiedź @zerome jest dobra, ale jest nieco niepotrzebnie gadatliwa.

W bazie repozytorium git możesz po prostu to zrobić: git push . dev:master

Bardziej uogólnionym rozwiązaniem, które działałoby w dowolnym miejscu drzewa, byłoby:

git push $(git rev-parse --show-toplevel) dev:master
Kevin Lyda
źródło
3
git push . dev:masterbardzo uprościło mi życie! Jak dotąd najlepsza odpowiedź, dziękuję
Jeremy Belolo,
czy zamierzasz wypchnąć scalony master do zdalnego repozytorium takiego jak github? zapisz krok, robiącgit push origin dev:master
Alex R
1
Czy jest możliwe odtworzenie tego merge --no-ffzachowania?
ekshuma
1
Otrzymuję nieprawidłową nazwę zdalną „”. w systemie Windows. Czy nadal muszę to zrobić git remote add self file:///myRepo?
kiewic
1
Ale tak naprawdę to nie robi scalenia ... Będzie działać, jeśli deweloper wyprzedza mistrza, ale co jeśli nie?
Thomas Levesque
44

Najlepszym rozwiązaniem byłoby użycie aliasu umieszczonego w globalnej gitconfig ( ~/.gitconfig):

[alias]
    merge-to = "!f() { git checkout $1 && git merge $2 && git checkout -; }; f"

dzięki czemu można wywołać go z dowolnego repozytorium jako

git merge-to master dev
Cascabel
źródło
3
Co by się stało, gdyby scalenie nie było automatyczne, ale wymaga rozwiązania scalenia? (W tym przypadku zakładam, że nie wykonano żadnej pracy nad mistrzem, więc by się nie wydarzyło, ale nadal) ...
Stein G. Strindhaug
@ Stein: Ponieważ użyłem &&, nie ;, nie powiedzie się scalenie i nie spróbuję wrócić. Mamy nadzieję, że użytkownik jest wystarczająco inteligentny, aby zobaczyć komunikat „scalenie nie powiodło się” i sobie z tym poradzić.
Cascabel
6
Wolę tę merge-to = "!f() { export tmp_branch=gałąź git | grep '*' | tr -d „*” ; git checkout $1 && echo git merge $tmp_branch && echo git checkout $tmp_branch; unset $tmp_branch; }; f", to niech ja nie trzeba wpisywać w branży Jestem obecnie na, więc jeśli chcę, aby scalić devdo masteri jestem w devtej chwili po prostu wpisaćgit merge-to master
Steve
2
Lepsza wersja z prawidłowymi merge-to = "!f() { export tmp_branch=`git branch | grep '* ' | tr -d '* '`; git checkout $1 && git merge $tmp_branch && git checkout $tmp_branch; unset $tmp_branch; }; f"
uderzeniami wstecznymi
2
polecenie unset jest nieprawidłowe. stałej wynosi: seryjnej do =! "f () {eksportu tmp_branch = git branch | grep '* ' | tr -d '* '; git realizacji transakcji $ 1 && git scalania --no-FF tmp_branch $ && $ tmp_branch git Zamówienie zamocowanej tmp_branch;}, f"
sassman
38

Mała modyfikacja aliasu Jefromi, która nie wymaga wpisywania w bieżącej gałęzi.

Więc go używać jak: git merge-to dev.

Spowoduje to przejście do devoddziału, scalenie go z AKTUALNYM, a następnie nastąpi powrót.

Na przykład, zakładając, że jesteś na mastergałęzi, scali on mistrza z dev i nadal będziesz na nim.

Zdecydowanie trafia do moich plików kropkowych :)

[alias]
  merge-to = "!gitmergeto() { export tmp_branch=`git branch | grep '* ' | tr -d '* '` && git checkout $1 && git merge $tmp_branch && git checkout $tmp_branch; unset tmp_branch; }; gitmergeto"
Dmytrii Nagirniak
źródło
6

To jest stare, ale ...

Łącząc rozwiązania @ kevin-lyda i @ dmytrii-nagirniak powyżej. alias ten łączy bieżącą gałąź z określoną gałęzią. Używa metody pilotów i używa poleceń git, aby uzyskać kontekst.

[alias]
    merge-to = "!gitmergeto() { git push \"`git rev-parse --show-toplevel`\" `git rev-parse --abbrev-ref HEAD`:$1; } && gitmergeto"

Do użycia jak:

git merge-to other-branch-name
tField
źródło
4

Aby scalić bieżącą gałąź z inną gałęzią bez sprawdzania innej gałęzi:

Scalanie do przodu

To jest naprawdę łatwe. Z definicji szybkie scalanie oznacza po prostu, że wskaźnik gałęzi jest przesuwany do przodu w drzewie zatwierdzeń. Wszystko, co musisz zrobić, to po prostu zasymulować, że:

git branch -f master dev

Ostrzeżenia: Zakłada to, że masterwskazuje na zatwierdzenie, które również znajduje się w devgałęzi lub innej gałęzi. Jeśli nie, ryzykujesz utratą pracy! W przeciwieństwie do tego, git mergektóry utworzy zatwierdzenie scalania (lub narzeka), gdy szybkie przewijanie do przodu nie jest możliwe, ta metoda po cichu zmusza wskaźnik gałęzi do wskazywania innego zatwierdzenia.

Zakłada to również, że jesteś jedynym, który pracuje nad repozytorium i / lub wiesz, co robisz.

Wskazówka: Jeśli zrobiłeś a git fetchi masz nowe zatwierdzenia origin/master, możesz przenieść mastergałąź bez wyewidencjonowywania za pomocą:

git branch -f master origin/master

Scal przez zatwierdzenie scalania

Nie zawsze jest to możliwe. Aby utworzyć zatwierdzenie scalania, musisz wykonać operację scalenia. Aby wykonać operację scalania, należy zatwierdzić zmiany w innym oddziale, które nie znajdują się w bieżącym oddziale.

Jeśli masz zatwierdzenia w masteroddziale, których nie ma w devoddziale, możesz:

Oświadczenie: Jest to jedynie dowód słuszności koncepcji, tylko po to, aby pokazać, że czasami możliwe jest połączenie z innym oddziałem bez sprawdzenia. Jeśli chcesz go używać codziennie, prawdopodobnie chcesz utworzyć dla niego alias za pomocą przekierowania powłoki lub utworzyć dla niego skrypt powłoki. Z drugiej strony możesz także utworzyć skrypt powłoki dla krótszego procesu pokazanego w pytaniu.

git checkout -b temp
git merge --no-ff -e master
git branch -f master temp
git checkout dev
git branch -D temp

Wyjaśnienie:

  1. Sprawdź tymczasową gałąź, która wskazuje na to samo zatwierdzenie, co bieżąca gałąź.
  2. Połącz mastersię z gałęzią tymczasową i uruchom edytor komunikatów zatwierdzania. Jeśli chcesz, aby zatwierdzenie scalania wyglądało tak , jakby scaliłeś devgałąź master, edytuj ją z tego:

    Merge branch 'master' into temp
    

    do tego:

    Merge branch 'dev'
    

    Wskazówka: Możesz użyć -m "Merge branch 'dev'"zamiast -ebyć szybszym.

  3. Zaktualizuj masterwskaźnik gałęzi, aby wskazywał na zatwierdzenie scalania.
  4. Sprawdź devoddział.
  5. Wymuś usunięcie gałęzi tymczasowej.

To wciąż dotyka twojego działającego drzewa, ale minimalnie. Nie przywraca drzewa do stanu oryginalnego, masteraby ponownie wprowadzić zmiany w rozwoju. Niektórym może to nie przeszkadzać, ale dla innych może być ważne.

ADTC
źródło
1

Wiele razy wychodzisz z gałęzi, w której chciałbyś połączyć obecną gałąź. W takim przypadku możesz zrobić:

git co - && git merge @{-1}

na przykład:

git checkout somebranch      // (while on master)

// add some commits

git co - && git merge @{-1}  // will merge somebranch into master
Zwiąż mnie
źródło
1

Moje rozwiązanie jest podobne do innych odpowiedzi, z następującymi różnicami:

  • funkcja jest podzielona na wiele wierszy dla zapewnienia czytelności
  • funkcja wywołuje, set -exwięc każde polecenie jest drukowane, a jeśli polecenie się nie powiedzie, funkcja natychmiast się kończy
  • alias przekazuje swoje argumenty oprócz pierwszego (gałąź docelowa) do git merge
  • funkcja zawiera polecenie zerowe, : git mergektóre zapewnia, że ​​uzupełnianie tabulatorami działa z niektórymi ustawieniami powłoki (np. gitfastz oh-my-zsh)
[alias]
  merge-to = "!f() { : git merge ; \
      set -ex ; \
      local this=$(git rev-parse --abbrev-ref HEAD) ; \
      local target=$1 ; \
      shift ; \
      git checkout $target ; \
      git merge $this \"$@\" ; \
      git checkout $this ; \
    } ; f"
artm
źródło