Kiedy łączę gałąź tematu „B” z „A” za pomocą git merge
, mam pewne konflikty. Wiem, że wszystkie konflikty można rozwiązać za pomocą wersji w „B”.
Jestem tego świadomy git merge -s ours
. Ale chcę czegoś takiego git merge -s theirs
.
Dlaczego to nie istnieje? Jak mogę osiągnąć ten sam wynik po konflikcie scalania z istniejącymi git
poleceniami? ( git checkout
każdy niepołączony plik z B)
AKTUALIZACJA: „Rozwiązanie” polegające na odrzuceniu czegokolwiek z gałęzi A (punkt zatwierdzenia scalania do wersji B drzewa) nie jest tym, czego szukam.
git merge -s their
.git merge -s theirs
(można to łatwo osiągnąćgit merge -s ours
i tymczasowej gałęzi), ponieważ - nasz całkowicie ignoruje zmiany połączenia z gałęzi ...theirs
opróczours
??? Jest to objaw jednego z problemów inżynieryjnych i projektowych wysokiego poziomu w Git: niespójności.Odpowiedzi:
Dodaj
-X
opcję dotheirs
. Na przykład:Wszystko połączy się w pożądany sposób.
Jedyne, co widziałem, powoduje problemy, jeśli pliki zostały usunięte z oddziału B. Pojawiają się jako konflikty, jeśli coś innego niż git usunęło.
Poprawka jest łatwa. Po prostu uruchom
git rm
z nazwą wszystkich plików, które zostały usunięte:Następnie
-X theirs
powinno działać zgodnie z oczekiwaniami.Oczywiście, faktyczne usunięcie za pomocą
git rm
polecenia zapobiegnie wystąpieniu konfliktu.Uwaga : istnieje również dłuższa opcja formularza.
Aby z niego skorzystać, zamień:
z:
źródło
theirs
”. -Xtheirs to opcja strategii zastosowana do strategii rekurencyjnej . Oznacza to, że strategia rekurencyjna nadal scali wszystko, co może, i powróci do logiki „swojej” tylko w przypadku konfliktów. Chociaż w większości przypadków jest to potrzebne, nie jest to to samo, co „po prostu weź wszystko z gałęzi B w takiej postaci, w jakiej jest”. I tak zamiast tego dokonuje prawdziwego scalenia.Możliwe i przetestowane rozwiązanie do połączenia oddziału B w naszym wyewidencjonowanym oddziale A:
Aby go zautomatyzować, możesz owinąć go w skrypt, używając argumentów branchA i branchB.
To rozwiązanie zachowuje pierwszy i drugi element nadrzędny zatwierdzenia scalania, tak jak można się spodziewać
git merge -s theirs branchB
.źródło
git reset --soft branchA
?git reset --hard
zmiany, które zatwierdzają,branchA
wskazują.Starsze wersje git pozwoliły na użycie „ich” strategii scalania:
Ale od tego czasu zostało to usunięte, jak wyjaśniono w tym komunikacie Junio Hamano (opiekun Git). Jak wspomniano w linku, zamiast tego zrobiłbyś to:
Uważaj jednak, że jest to coś innego niż faktyczne scalenie. Twoje rozwiązanie jest prawdopodobnie opcją, której naprawdę szukasz.
źródło
git reset --hard origin
sposób rozwiązanie ich scalenia stylu? Gdybym chciał połączyć BranchB z BranchA (jak w odpowiedzi Alana W. Smitha), jak miałbym to zrobić przy użyciu tejreset
metody?git reset --hard
łączy się w stylu „ich”. Oczywiściegit reset --hard
nie tworzy żadnego zatwierdzenia scalania ani żadnego zatwierdzenia w tej sprawie. Chodzi o to, że nie powinniśmy używać scalania, aby zastąpić cokolwiek w HEAD czymś innym. Jednak niekoniecznie się zgadzam.theirs
zostały usunięte, ponieważ uzasadnienie było niepełne. Nie uwzględnił przypadków, w których kod jest dobry, po prostu to, że upstream jest utrzymywany na innej podstawie filozoficznej, więc w tym sensie jest „zły”, więc zarówno chcemy być na bieżąco z upstreamem, ale jednocześnie zachowują dobre „poprawki” kodu [git i msysgit mają ten „konflikt” z powodu filozofii różnych platform docelowych]theirs
ponieważ przypadkowo zmieniłem niektóre pliki w dwóch oddzielnych gałęziach i chciałem odrzucić zmiany jednego bez konieczności ręcznego wykonywania tego dla każdego pliku.Nie jest do końca jasne, jaki jest twój pożądany wynik, więc istnieje pewne zamieszanie dotyczące „prawidłowego” sposobu robienia tego w odpowiedziach i komentarzach. Staram się dać przegląd i widzę następujące trzy opcje:
Spróbuj połączyć i użyj B w przypadku konfliktów
To nie jest „ich wersja dla
git merge -s ours
”, ale „ich wersja dlagit merge -X ours
” (co jest skrótem odgit merge -s recursive -X ours
):Tak właśnie robi odpowiedź Alana W. Smitha .
Używaj treści tylko z B.
Tworzy to zatwierdzenie scalania dla obu gałęzi, ale odrzuca wszystkie zmiany
branchA
i tylko zatrzymuje zawartośćbranchB
.Zauważ, że scalanie zatwierdza pierwszego rodzica, teraz jest to od
branchB
i tylko drugie pochodzi odbranchA
. Tak właśnie działa odpowiedź Gandalf458 .Używaj tylko treści z B i zachowaj prawidłową kolejność nadrzędną
To jest prawdziwa „ich wersja dla
git merge -s ours
”. Ma taką samą treść jak w poprzedniej opcji (tj. Tylko tę zbranchB
), ale kolejność rodziców jest prawidłowa, tzn. Pierwszy rodzic pochodzi z,branchA
a drugi zbranchB
.Tak właśnie robi odpowiedź Paula Pladijsa (bez konieczności tymczasowego odgałęzienia).
źródło
git checkout branchA; git merge -s ours --no-commit branchB; git read-tree -um @ branchB; git commit
read-tree
, do której przeciętny użytkownik git może nie być przyzwyczajony (przynajmniej ja nie ;-)). Rozwiązania zawarte w odpowiedzi używają tylko poleceń wysokiego poziomu („porcelany”), które większość użytkowników gita powinna wiedzieć. Wolę je, ale mimo wszystko dziękuję za twoją wersję!…commit --amend…
) zostanie „utracone”.Odtąd korzystałem z odpowiedzi Paula Pladijsa. Dowiedziałem się, że możesz wykonać „normalne” scalenie, zdarzają się konflikty, więc tak
aby rozwiązać konflikt przy użyciu wersji z drugiego oddziału. Jeśli zrobisz to dla każdego pliku, zachowujesz się tak, jak można się spodziewać
W każdym razie wysiłek jest większy niż w przypadku strategii łączenia! (Zostało to przetestowane w wersji git 1.8.0)
źródło
git ls-files --modified | xargs git add
chciałem to zrobić dla dodanego po obu stronach scalenia: /git ls-files --modified
więc myślę, że jest to również realne rozwiązanie.git config --global alias.unresolved '!git status --short|egrep "^([DAU])\1"'
-X
i jaka jest różnica między-X
i-s
? nie mogę znaleźć żadnego dokumentu.Rozwiązałem problem za pomocą
źródło
Zakładam, że utworzyłeś gałąź master i teraz chcesz z powrotem połączyć się w master, zastępując wszystkie stare rzeczy w master. Właśnie to chciałem zrobić, kiedy natknąłem się na ten post.
Rób dokładnie to, co chcesz, z wyjątkiem pierwszego połączenia jednej gałęzi z drugą. Właśnie to zrobiłem i działało świetnie.
Następnie sprawdź master i scal w nim swój oddział (teraz pójdzie gładko):
źródło
Jeśli jesteś w oddziale A:
Testowane na wersji git 1.7.8
źródło
Aby naprawdę poprawnie wykonać scalenie, które pobiera tylko dane wejściowe z gałęzi, którą scalasz, możesz to zrobić
git merge --strategy=ours ref-to-be-merged
git diff --binary ref-to-be-merged | git apply --reverse --index
git commit --amend
W żadnym znanym mi scenariuszu nie będzie konfliktów, nie musisz tworzyć dodatkowych rozgałęzień, a to działa jak normalne zatwierdzenie scalania.
Nie działa to jednak dobrze z submodułami.
źródło
Chociaż wspominam w „ poleceniu git, aby uczynić jedną gałąź podobną do drugiej ”, jak symulować
git merge -s theirs
, zauważcie , że Git 2.15 (IV kwartał 2017) jest teraz jaśniejszy:Zobacz zatwierdzenie c25d98b (25 września 2017 r.) Autor: Junio C Hamano (
gitster
) .(Połączone przez Junio C Hamano -
gitster
- w commit 4da3e23 , 28 września 2017)-Xtheirs
jest opcją strategiczną stosowaną do strategii rekurencyjnej. Oznacza to, że strategia rekurencyjna będzie nadal łączyć wszystko, co może, i powróci dotheirs
logiki tylko w przypadku konfliktu.Ta debata na temat znaczenia lub braku
theirs
strategii scalania została niedawno przywołana w tym wątku z września 2017 r .Uznaje starsze (2008) wątki
Wspomina o aliasie:
Jarosław Halczenko próbuje raz jeszcze opowiedzieć się za tą strategią, ale Junio C. Hamano dodaje :
Junio dodaje, jak komentuje Mike Beaton :
źródło
git merge -s ours <their-ref>
skutecznie mówi „znak commits złożony do <their-ref> w swojej gałęzi jako zobowiązanie do trwałego zignorowania „; i to ma znaczenie, ponieważ jeśli następnie scalisz z późniejszych stanów ich gałęzi, ich późniejsze zmiany zostaną wprowadzone bez wprowadzania ignorowanych zmian.Zobacz szeroko cytowaną odpowiedź Junio Hamano : jeśli zamierzasz odrzucić popełnione treści, po prostu odrzuć zatwierdzenia lub przynajmniej trzymaj je poza główną historią. Po co przeszkadzać wszystkim w przyszłości, czytając komunikaty zatwierdzeń z zatwierdzeń, które nie mają nic do zaoferowania?
Ale czasami są wymagania administracyjne, a może z innego powodu. W sytuacjach, w których naprawdę musisz rejestrować zatwierdzenia, które nic nie wnoszą, potrzebujesz:
(edytuj: wow, czy udało mi się wcześniej to zrobić źle. Ten działa.)
źródło
Ten używa drzewa poleceń git, ale skraca ogólny przepływ pracy.
źródło
Spowoduje to scalenie Twojego newBranch w istniejącym BaseBranch
źródło
git commit --amend
na końcu twojego przykładu, w przeciwnym razie użytkownicy mogą zobaczyć zatwierdzenie scalaniagit log
i założyć, że operacja została zakończona.Myślę, że tak naprawdę chcesz:
To wydaje się niezdarne, ale powinno działać. Jedyne, co naprawdę nie podoba mi się w tym rozwiązaniu, to to, że historia gita będzie myląca ... Ale przynajmniej historia zostanie całkowicie zachowana i nie będziesz musiał robić nic specjalnego dla usuniętych plików.
źródło
Odpowiednik (który utrzymuje porządek nadrzędny) „git merge -s ich oddział B”
Przed scaleniem:
!!! Upewnij się, że jesteś w czystości !!!
Wykonaj scalenie:
Co zrobiliśmy ? Stworzyliśmy nowy zatwierdzenie, którego dwoje rodziców, nasi i ich, a siecią zatwierdzeń jest oddział B - ich
Po scaleniu:
Dokładniej:
źródło
Odpowiedzi udzielił Paul Pladijs. Właśnie wziąłem jego polecenia i dla wygody utworzyłem alias git.
Edytuj swój .gitconfig i dodaj następujące elementy:
Następnie możesz „git merge -s theirs A”, uruchamiając:
źródło
Niedawno musiałem to zrobić dla dwóch osobnych repozytoriów, które mają wspólną historię. Zacząłem od:
Org/repository1 master
Org/repository2 master
Chciałem, aby wszystkie zmiany
repository2 master
zostały zastosowanerepository1 master
, akceptując wszystkie zmiany, które wprowadziłoby repozytorium2. Mówiąc git, powinna to być strategia zwana-s theirs
ALE nie istnieje. Bądź ostrożny, ponieważ-X theirs
jest tak nazwany, jakbyś tego chciał, ale to NIE jest to samo (nawet tak mówi na stronie podręcznika).Sposób, w jaki to rozwiązałem, to udanie się
repository2
i utworzenie nowego oddziałurepo1-merge
. W tym oddziale prowadziłemgit pull [email protected]:Org/repository1 -s ours
i wszystko w porządku, bez żadnych problemów. Następnie pcham go do pilota.Potem wracam do
repository1
i tworzę nowy oddziałrepo2-merge
. W tej gałęzi działam,git pull [email protected]:Org/repository2 repo1-merge
co zakończy się problemami.Na koniec musisz albo wysłać żądanie scalenia,
repository1
aby uczynić go nowym wzorcem, albo po prostu zachować jako gałąź.źródło
Prostym i intuicyjnym (moim zdaniem) dwuetapowym sposobem na zrobienie tego jest
śledzony przez
(co oznacza dwie gałęzie jako połączone)
Jedyną wadą jest to, że nie usuwa plików, które zostały usunięte w oddziale B z bieżącego oddziału. Prosta różnica między dwiema gałęziami pokaże później, czy istnieją takie pliki.
Podejście to wyjaśnia również później z dziennika zmian, co zostało zrobione - i co było zamierzone.
źródło