Mam gałąź o nazwie, demo
którą muszę połączyć z master
gałęzią. Mogę uzyskać pożądany efekt za pomocą następujących poleceń:
git pull origin demo
git checkout master
git pull origin master
git merge demo
git push origin master
Moim jedynym zmartwieniem jest to, że jeśli są jakieś problemy z scalaniem , chcę powiedzieć, git
aby nadpisać zmiany w master
gałęzi bez monitowania o scalenie. Więc zasadniczo zmiany w demo
gałęzi powinny automatycznie nadpisywać zmiany w master
gałęzi.
Rozejrzałem się, istnieje wiele opcji, ale nie chcę ryzykować z połączeniem.
git push -f origin master
-f
opcji zmerge
poleceniem, a nie zpush
poleceniemOdpowiedzi:
Niezupełnie związane z tą odpowiedzią, ale porzuciłbym
git pull
, co po prostu biegniegit fetch
za nimgit merge
. Wykonujesz trzy scalenia, co spowoduje, że Twój Git uruchomi trzy operacje pobierania, podczas gdy jedno pobieranie jest wszystkim, czego potrzebujesz. W związku z tym:Kontrolowanie najtrudniejszych połączeń
Najciekawsza część tutaj jest
git merge -X theirs
. Jak zauważył root545 ,-X
opcje są przekazywane do strategii scalania, a zarównorecursive
strategia domyślna , jak iresolve
strategia alternatywna przyjmują-X ours
lub-X theirs
(jedna lub druga, ale nie obie). Aby jednak zrozumieć, co robią, musisz wiedzieć, w jaki sposób Git wyszukuje i leczy konflikty .Konflikt scalania może wystąpić w pewnym pliku 1, gdy wersja podstawowa różni się zarówno od wersji bieżącej (nazywanej również
--ours
wersją lokalną, HEAD lub ), jak i innej (nazywanej również zdalną lub--theirs
) wersją tego samego pliku. Oznacza to, że podczas scalania zidentyfikowano trzy wersje (trzy zatwierdzenia): podstawową, naszą i ich. Wersja „podstawowa” pochodzi z podstawy scalania między naszym zatwierdzeniem a ich zatwierdzeniem, jak można znaleźć na wykresie zatwierdzeń (aby uzyskać więcej informacji na ten temat, zobacz inne wpisy StackOverflow). Git znalazł wtedy dwa zestawy zmian: „co zrobiliśmy” i „co zrobili”. Te zmiany są (na ogół) widoczne wiersz po wierszu, czysto tekstowe . Git nie ma prawdziwego zrozumienia zawartości plików; jest to po prostu porównanie każdego wiersza tekstu.Te zmiany są tym, co widzisz w
git diff
wynikach i jak zawsze mają również kontekst . Możliwe, że rzeczy, które zmieniliśmy, znajdują się w innych wierszach niż te, które zmieniły, więc zmiany wydają się nie kolidować, ale kontekst również się zmienił (np. Z powodu naszej zmiany znajdującej się blisko góry lub dołu pliku, aby plik skończył się w naszej wersji, ale w ich dodali też więcej tekstu na górze lub na dole).Jeśli zmiany się zdarzyć na różnych liniach, na przykład, zmieniamy
color
sięcolour
na linii 17 i zmieniająfred
siębarney
na linii 71-to nie ma konfliktu: Git prostu wykonuje zarówno zmian. Jeśli zmiany zachodzą w tych samych wierszach, ale są identyczne , Git pobiera jedną kopię zmiany. Tylko jeśli zmiany są w tych samych wierszach, ale są to różne zmiany lub ten specjalny przypadek interferencji kontekstu, pojawia się konflikt modyfikacji / modyfikacji.-X ours
I-X theirs
opcje powiedzieć Git jak rozwiązać ten konflikt, poprzez wskazanie tylko jednego z dwóch zmian: nasza, czy ich. Ponieważ powiedziałeś, że scalaszdemo
(ich) zmaster
(naszymi) i chcesz zmiany zdemo
, na pewno chcesz-X theirs
.-X
Jednak ślepe stosowanie jest niebezpieczne. Tylko dlatego, że nasze zmiany nie kolidowały z linią po linii, nie oznacza, że nasze zmiany w rzeczywistości nie powodują konfliktu! Jeden klasyczny przykład występuje w językach z deklaracjami zmiennych. Podstawowa wersja może zadeklarować nieużywaną zmienną:W naszej wersji usuwamy nieużywaną zmienną, aby ostrzeżenie kompilatora zniknęło - aw swojej wersji dodają pętlę kilka wierszy później, używając
i
jako licznika pętli. Jeśli połączymy te dwie zmiany, wynikowy kod nie będzie się już kompilować. Ta-X
opcja nie jest tutaj pomocna, ponieważ zmiany są w różnych wierszach .Jeśli masz zestaw testów automatycznych, najważniejszą rzeczą do zrobienia jest uruchomienie testów po scaleniu. Możesz to zrobić po zatwierdzeniu i naprawić później, jeśli to konieczne; lub możesz to zrobić przed
--no-commit
zatwierdzeniem , dodając dogit merge
polecenia. Szczegóły tego wszystkiego pozostawimy innym postom.1 Możesz również uzyskać konflikty w odniesieniu do operacji „całego pliku”, np. Być może poprawiamy pisownię słowa w pliku (tak, że mamy zmianę), a oni usuwają cały plik (tak, że mają usunąć). Git nie rozwiąże samodzielnie tych konfliktów, niezależnie od
-X
argumentów.Wykonywanie mniejszej liczby połączeń i / lub inteligentniejszych połączeń i / lub używanie rebase
W obu naszych sekwencjach poleceń występują trzy połączenia. Pierwszym jest przeniesienie
origin/demo
do lokalnegodemo
(twoje zastosowania,git pull
które, jeśli twój Git jest bardzo stary, nie zaktualizują się,origin/demo
ale dadzą ten sam wynik końcowy). Drugi jest doprowadzenieorigin/master
domaster
.Nie jest dla mnie jasne, kto aktualizuje
demo
i / lubmaster
. Jeśli napiszesz swój własny kod we własnejdemo
gałęzi, a inni piszą kod i wypychają go dodemo
gałęziorigin
, to scalanie w pierwszym kroku może powodować konflikty lub powodować rzeczywiste scalanie. Najczęściej lepiej jest użyć rebase niż merge, aby połączyć pracę (trzeba przyznać, że to kwestia gustu i opinii). Jeśli tak, możesz użyćgit rebase
zamiast tego. Z drugiej strony, jeśli nigdy nie zrobić żadnej z własnymi zobowiązuje ondemo
, nawet nie trzeba siędemo
oddział. Alternatywnie, jeśli chcesz zautomatyzować wiele z tych czynności, ale możesz dokładnie sprawdzić, czy są zatwierdzenia, które ty i inni zrobiliście, możesz użyćgit merge --ff-only origin/demo
: to przyspieszy, jeśli to możliwe, i po prostu zakończy się niepowodzeniem, jeśli nie (w którym to momencie możesz sprawdzić dwa zestawy zmian i wybrać rzeczywiste scalenie lub ponowne ustawienie, jeśli to konieczne).demo
aby dopasować zaktualizowany,origin/demo
Ta sama logika dotyczy
master
, choć robisz scalanie namaster
, więc na pewno nie potrzebujemymaster
. Jest jednak jeszcze bardziej prawdopodobne, że chciałbyś, aby scalanie nie powiodło się, jeśli nie można go wykonać jako szybkiego przewijania do przodu bez scalania, więc prawdopodobnie powinno tak byćgit merge --ff-only origin/master
.Powiedzmy, że nigdy nie wykonujesz własnych zatwierdzeń
demo
. W tym przypadku możemydemo
całkowicie porzucić nazwę :Jeśli są robi własne
demo
zobowiązuje gałąź, to nie jest pomocne; równie dobrze możesz zachować istniejące scalanie (ale może dodać w--ff-only
zależności od tego, jakie zachowanie chcesz) lub przełączyć na wykonanie rebase. Zwróć uwagę, że wszystkie trzy metody mogą się nie powieść: scalanie może się nie powieść z powodu konfliktu, scalanie z--ff-only
może nie być w stanie przewinąć do przodu, a ponowne bazowanie może się nie powieść z konfliktem (rebase działa w zasadzie poprzez wybieranie najlepszych zatwierdzeń, które wykorzystuje scalanie maszyneria i stąd może wystąpić konflikt scalania).źródło
Miałem podobny problem, w którym musiałem skutecznie zastąpić dowolny plik, który miał zmiany / konflikty z inną gałęzią.
Rozwiązaniem, które znalazłem, było użycie
git merge -s ours branch
.Zwróć uwagę, że opcja jest
-s
i nie-X
.-s
oznacza użycieours
jako strategii łączenia najwyższego poziomu,-X
byłoby zastosowanie tejours
opcji dorecursive
strategii łączenia, co nie jest tym, czego ja (lub my) chcemy w tym przypadku.Kroki, gdzie
oldbranch
jest gałąź, którą chcesz nadpisaćnewbranch
.git checkout newbranch
sprawdza gałąź, którą chcesz zachowaćgit merge -s ours oldbranch
scala w starej gałęzi, ale zachowuje wszystkie nasze pliki.git checkout oldbranch
sprawdza gałąź, którą chcesz nadpisaćget merge newbranch
scala się w nowej gałęzi, nadpisując starą gałąźźródło
To podejście scalające doda jedno zatwierdzenie, do
master
którego wkleja się wszystko, co jestfeature
, bez narzekania na konflikty lub inne bzdury.Zanim cokolwiek dotkniesz
git stash git status # if anything shows up here, move it to your desktop
Teraz przygotuj mistrza
git checkout master git pull # if there is a problem in this step, it is outside the scope of this answer
Ubierzcie się
feature
wszyscyIdź do zabicia
źródło
Changes from the other tree that do not conflict with our side are reflected in the merge result
. Nie zadziałało to dla mnie, ponieważ miałem czyste łączenie zatwierdzeń w mojej gałęzi, która była nadpisywana. Czy jest inny sposób?Możesz wypróbować opcję „nasza” w git merge,
źródło
demo
wersja była preferowana, mimo że się z nią łączymaster
. Jest-X theirs
też, ale nie jest jasne, czy właśnie tego chce OP.ours
robi się, gdy używasz na zapleczu z-s
opcją. Podczas używaniaours
z-X
: odrzuca wszystko, co zrobiło inne drzewo, deklarując, że nasza historia zawiera wszystko, co się w nim wydarzyło. źródłoKiedy próbowałem używać
-X theirs
i innych powiązanych przełączników poleceń, otrzymywałem zatwierdzenie scalania. Prawdopodobnie nie rozumiałem tego poprawnie. Łatwą do zrozumienia alternatywą jest po prostu usunięcie gałęzi, a następnie ponowne jej śledzenie.To nie jest dokładnie „scalanie”, ale właśnie tego szukałem, kiedy natknąłem się na to pytanie. W moim przypadku chciałem wyciągnąć zmiany ze zdalnej gałęzi, które zostały wymuszone.
źródło