Czy istnieje "ich" wersja "git merge-s ours"?

Podczas łączenia gałęzi tematycznej " B "W" A "za pomocą git merge, dostaję kilka konfliktów. Wiem, że wszystkie konflikty można rozwiązać używając wersji "B".

Wiem o git merge -s ours. Ale chcę czegoś w rodzaju git merge -s theirs.

Dlaczego nie istnieje? Jak mogę osiągnąć ten sam wynik po połączeniu kolidującym z istniejącymi poleceniami git? (git checkout każdy niezaangażowany Plik z B)

UPDATE: "rozwiązanie" polegające na odrzuceniu czegokolwiek z gałęzi a (commit merge point to B version of drzewo) nie jest tym, czego szukam.

 688
Author: elmarco, 2008-10-06

18 answers

Dodaj opcję -X do theirs. Na przykład:

git checkout branchA
git merge -X theirs branchB

Wszystko połączy się w pożądany sposób.

Jedyne, co widziałem, powoduje problemy, jeśli pliki zostały usunięte z branchB. Pojawiają się jako konflikty, jeśli coś innego niż git zrobił usunięcie.

Naprawa jest łatwa. Po prostu uruchom git rm z nazwą usuniętych plików:
git rm {DELETED-FILE-NAME}

Po tym, -X theirs powinny działać zgodnie z oczekiwaniami.

Oczywiście, robiąc rzeczywiste usunięcie z git rm Komenda zapobiegnie w pierwszej kolejności wystąpieniu konfliktu.


Uwaga : istnieje również dłuższa opcja formularza. Aby go użyć, zastąp:

-X theirs

Z:

--strategy-option=theirs
 801
Author: Alan W. Smith,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-01 22:08:21

Możliwe i sprawdzone rozwiązanie do połączenia branchB z naszą sprawdzoną gałęzią:

# in case branchA is not our current branch
git checkout branchA

# make merge commit but without conflicts!!
# the contents of 'ours' will be discarded later
git merge -s ours branchB    

# make temporary branch to merged commit
git branch branchTEMP         

# get contents of working tree and index to the one of branchB
git reset --hard branchB

# reset to our merged commit but 
# keep contents of working tree and index
git reset --soft branchTEMP

# change the contents of the merged commit
# with the contents of branchB
git commit --amend

# get rid off our temporary branch
git branch -D branchTEMP

# verify that the merge commit contains only contents of branchB
git diff HEAD branchB

Aby go zautomatyzować, możesz owinąć go w skrypt używając branchA i branchB jako argumentów.

To rozwiązanie zachowuje pierwszy i drugi rodzic commitu merge, tak jak można się spodziewać po git merge -s theirs branchB.

 184
Author: Paul Pladijs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-25 03:22:44

Starsze wersje Gita pozwoliły na użycie" ich " strategii scalania:

git pull --strategy=theirs remote_branch

Ale to zostało usunięte, jak wyjaśniono w tej wiadomości przez Junio Hamano (opiekuna Gita). Jak zaznaczono w linku, zamiast tego zrobiłbyś to:

git fetch origin
git reset --hard origin

Uważaj jednak, że to coś innego niż rzeczywiste połączenie. Twoje rozwiązanie jest prawdopodobnie rozwiązaniem, którego naprawdę szukasz.

 79
Author: Pat Notz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-06 01:53:03

Od tej pory korzystałem z odpowiedzi Paula Pladijsa. Dowiedziałem się, że można zrobić "normalne" połączenie, konflikty występują, więc robisz

git checkout --theirs <file>

Aby rozwiązać konflikt za pomocą rewizji z drugiej gałęzi. Jeśli robisz to dla każdego pliku, zachowujesz się tak samo, jak oczekujesz od

git merge <branch> -s theirs

W każdym razie, wysiłek jest większy niż w przypadku strategii scalania! (To było testowane z git w wersji 1.8.0)

 53
Author: musicmatze,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-03 12:51:12

Nie jest do końca jasne, jaki jest Twój pożądany wynik, więc istnieje pewne zamieszanie co do "poprawnego" sposobu robienia tego w odpowiedziach i ich komentarzach. Staram się dać przegląd i zobaczyć następujące trzy opcje:

Spróbuj połączyć i użyj B do konfliktów

To jest

To jest nie " ich wersja dla git merge -s ours", ale" ich wersja dla git merge -X ours " (co jest skrótem od git merge -s recursive -X ours):

git checkout branchA
# also uses -s recursive implicitly
git merge -X theirs branchB

Oto odpowiedź Alana W. Smitha tak.

Użyj zawartości tylko z B

Tworzy commit scalający dla obu gałęzi, ale odrzuca wszystkie zmiany z {[6] } i zachowuje tylko zawartość z branchB.

# Get the content you want to keep.
# If you want to keep branchB at the current commit, you can add --detached,
# else it will be advanced to the merge commit in the next step.
git checkout branchB

# Do the merge an keep current (our) content from branchB we just checked out.
git merge -s ours branchA

# Set branchA to current commit and check it out.
git checkout -B branchA

Zauważ, że pierwszy rodzic merge commits jest teraz z branchB, a tylko drugi z branchA. Tak robi np. odpowiedź Gandalf458.

Używaj tylko treści z B i zachowaj poprawną kolejność rodzica

To jest prawdziwa " ich wersja dla git merge -s ours". Ma taką samą treść jak w opcji wcześniej (tzn. tylko ta z branchB), ale kolejność rodziców jest prawidłowa, tzn. pierwszy rodzic pochodzi z branchA, a drugi z branchB.

git checkout branchA

# Do a merge commit. The content of this commit does not matter,
# so use a strategy that never fails.
# Note: This advances branchA.
git merge -s ours branchB

# Change working tree and index to desired content.
# --detach ensures branchB will not move when doing the reset in the next step.
git checkout --detach branchB

# Move HEAD to branchA without changing contents of working tree and index.
git reset --soft branchA

# 'attach' HEAD to branchA.
# This ensures branchA will move when doing 'commit --amend'.
git checkout branchA

# Change content of merge commit to current index (i.e. content of branchB).
git commit --amend -C HEAD

Tak robi odpowiedź Paula Pladijsa (nie wymagając tymczasowego oddziału).

 47
Author: siegi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:33:26

Rozwiązałem swój problem używając

git checkout -m old
git checkout -b new B
git merge -s ours old
 21
Author: elmarco,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-06 11:34:59

Jeśli jesteś na gałęzi a do:

git merge -s recursive -X theirs B

Testowane na git w wersji 1.7.8

 13
Author: rafalmag,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-12 19:17:23

Podczas scalania gałęzi tematycznej " B "W" A "używając Git merge, dostaję pewne konflikty. I > Wiem, że wszystkie konflikty można rozwiązać używając wersji w "B".

Wiem, że git merge-S jest nasz. Ale chcę czegoś takiego jak git merge > - S ich.

Zakładam, że stworzyłeś gałąź od master i teraz chcesz połączyć się z powrotem do master, nadpisując wszystkie stare rzeczy w master. Dokładnie to chciałem zrobić, gdy natknąłem się na ten post.

Do dokładnie to, co chcesz zrobić, z wyjątkiem scalenia jednej gałęzi do drugiej. Właśnie to zrobiłem i zadziałało świetnie.

git checkout Branch
git merge master -s ours

Następnie checkOut master i połącz w nim swoją gałąź (teraz pójdzie gładko):

git checkout master
git merge Branch
 8
Author: Gandalf458,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-27 08:36:53

Aby naprawdę poprawnie wykonać merge, które zajmuje tylko Wejście z gałęzi, którą łączysz, możesz zrobić

git merge --strategy=ours ref-to-be-merged

git diff --binary ref-to-be-merged | git apply --reverse --index

git commit --amend

Nie będzie konfliktów w żadnym scenariuszu, który znam, nie musisz tworzyć dodatkowych gałęzi, a to działa jak normalny commit scalający.

To jednak nie gra przyjemnie z podmodułami.

 6
Author: thoutbeckers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-20 23:16:59

Zobacz często cytowaną odpowiedź Junio Hamano : Jeśli zamierzasz odrzucić zatwierdzoną zawartość, po prostu Odrzuć commity lub w każdym razie trzymaj ją z dala od głównej historii. Po co zawracać sobie głowę czytaniem komunikatów commitów z commitów, które nie mają nic do zaoferowania?

Ale czasami są wymagania administracyjne, a może z jakiegoś innego powodu. W sytuacjach, w których naprawdę musisz nagrać commity, które nic nie wniosą, chcesz:

(edit: wow, czy ja / align = "left" / Ten działa.)

git update-ref HEAD $(
        git commit-tree -m 'completely superseding with branchB content' \
                        -p HEAD -p branchB    branchB:
)
git reset --hard
 4
Author: jthill,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-15 14:47:08

Ten używa drzewa odczytu komendy Git plumbing, ale sprawia, że ogólny przepływ pracy jest krótszy.

git checkout <base-branch>

git merge --no-commit -s ours <their-branch>
git read-tree -u --reset <their-branch>
git commit

# Check your work!
git diff <their-branch>
 1
Author: Michael R,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-22 19:18:40

Dlaczego nie istnieje?

Podczas gdy wspominam w "polecenie git do tworzenia jednej gałęzi jak drugiej " jak symulować git merge -s theirs, zauważ, że Git 2.15 (Q4 2017) jest teraz jaśniejszy:

Dokumentacja dla "-X<option> " dla połączeń była mylnie napisane, aby zasugerować, że" -s theirs " istnieje, co nie jest prawdą.

Zobacz commit c25d98b (25 września 2017) by Junio C Hamano (gitster).
(dodany przez Junio C Hamano -- gitster -- in commit 4da3e23, 28 Sep 2017)

Merge-strategie: unikaj sugerowania, że "-s theirs" istnieje

Opis opcji -Xours merge posiada notatkę w nawiasie to mówi czytelnikom, że bardzo różni się od -s ours, co jest poprawne, ale opis -Xtheirs, który za nim podąża beztrosko mówi " to jest przeciwieństwo ours", dając fałszywy wrażenie, że czytelnikom należy też ostrzec, że jest to bardzo różne z -s theirs, która w rzeczywistości nawet nie istnieje.

-Xtheirs jest opcją strategii zastosowaną do strategii rekurencyjnej. Oznacza to, że strategia rekurencyjna będzie nadal scalać wszystko, co może, i powróci tylko do logiki "{13]}" W przypadku konfliktów.

[[20]} ta debata na temat ważności strategii scalania lub nie została przywrócona niedawno W tym wrześniu. 2017 wątek .
Uznaje starsze (2008) wątki

W krótko mówiąc, poprzednią dyskusję można podsumować następująco: "nie chcemy '-s theirs', ponieważ zachęca to do niewłaściwego przepływu pracy".

Wymienia pseudonim:

mtheirs = !sh -c 'git merge -s ours --no-commit $1 && git read-tree -m -u $1' -
Yaroslav Halchenko po raz kolejny opowiada się za tą strategią, ale Junio C. Hamano dodaje: :
Powodem, dla którego nasze i ich nie są symetryczne, jest to, że ty jesteś sobą, a nie oni-kontrola i własność naszej historii i ich historii nie jest symetryczna.

Once you zdecyduj, że ich historia jest główną linią, wolisz traktować swoją linię rozwoju jako gałąź poboczną i dokonać scalenia w tym kierunku, tzn. pierwszy rodzic wynikającego scalenia jest zatwierdzeniem ich historii, a drugi rodzic jest ostatnim złym z twojej historii. Więc skończyłbyś używając "checkout their-history && merge -s ours your-history " do zachowaj rozsądek pierwszego rodzicielstwa.

I w tym momencie użycie "-s ours "nie jest już obejściem braku" -s theirs".
jest to właściwa część pożądana semantyka, tzn. z punktu widzenia przetrwałej linii historii kanonicznej, chcesz zachować to, co zrobiła, unieważniając to, co zrobiła druga linia historii {79]}.

 1
Author: VonC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-14 06:19:37

To połączy Twój nowy branch z istniejącym baseBranch

git checkout <baseBranch> // this will checkout baseBranch
git merge -s ours <newBranch> // this will simple merge newBranch in baseBranch
git rm -rf . // this will remove all non references files from baseBranch (deleted in newBranch)
git checkout newBranch -- . //this will replace all conflicted files in baseBranch
 0
Author: Pawan Maheshwari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-28 12:35:03

Myślę, że tak naprawdę chcesz:

git checkout -B mergeBranch branchB
git merge -s ours branchA
git checkout branchA
git merge mergeBranch
git branch -D mergeBranch
To wydaje się niezdarne, ale powinno zadziałać. Jedyne, co myślę, że naprawdę nie lubię tego rozwiązania, to historia Gita będzie myląca... Ale przynajmniej historia zostanie całkowicie zachowana i nie będziesz musiał robić czegoś specjalnego dla usuniętych plików.
 0
Author: briemers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-31 13:41:17

UPDATE

Podczas gdy druga odpowiedź odpowiada na pierwotne pytanie OP, nie odzwierciedla zaktualizowanej intencji pytania OP.


To czego szukasz nie jest przeciwieństwem git merge -s ours polecenia szukasz przeciwieństwem git merge -s recursive -X ours polecenia, którym jest git merge -s recursive -X theirs


Oryginalna Odpowiedź

Podane oryginalne gałęzie

*    0123456 (HEAD->A, origin/A)
| *  1234556 (origin/B, B)
|/
*    ??????? (common root)

Aby scalić gałąź B Do a ignorując stan gałęzi a, najpierw wykonaj zwykły merge

git merge -s ours B    (this is the opposite of what we want)

To daje

*    2345678 (HEAD->A) Merge branch 'B' into A    (all wrong)
|\
* |  0123456 (origin/A)
| *  1234567 (origin/B, B)
|/
*    ??????? (common root)

Nie naciskaj tego scalania, ponieważ zmieni się identyfikator zatwierdzenia (i tak jest źle) teraz możemy zmienić, po fakcie, strategię ours w strategię theirs

nie zapomnij zapisać ID zatwierdzenia połączenia, ponieważ będzie ono niedostępne po następnym resecie twardym. (Jeśli zapomnisz, że żadne obrażenia nie zostaną zadane, ale będziesz musiał wykonać twardy reset z powrotem do A i zacząć wszystko od nowa).

git reset --hard B    (this is what we want the merge to look like (the merge can now only be referenced by the commit id `2345678`))
git reset --soft 2345678    (without changing any files go back to the merge)
git commit --amend    (branch B is now the final version of the merge)

Teraz my have

*    3456789 (HEAD->A) Merge branch 'B' into A    (correctly ignores changes from 0123456)
|\
* |  0123456 (origin/A)
| *  1234567 (origin/B, B)
|/
*    ??????? (common root)

$ diff HEAD B
[... no changes ...]
git push

Zrobione

Musiałem to zrobić, gdy współpracownik zastosował moje zmiany A do swojej niezależnej gałęzi B bez scalania, co pozwala mi zaakceptować jego modyfikacje na mojej gałęzi.

 0
Author: user3338098,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-01 22:56:21

Prosty i intuicyjny (moim zdaniem) dwuetapowy sposób to

git checkout branchB .
git commit -m "Picked up the content from branchB"

Po którym następuje

git merge -s ours branchB

(który oznacza dwie gałęzie jako połączone)

Jedyną wadą jest to, że nie usuwa plików, które zostały usunięte w branchB z bieżącej gałęzi. Proste rozróżnienie pomiędzy tymi dwoma gałęziami pokaże, czy istnieją takie pliki.

To podejście wyjaśnia również z dziennika wersji później, co zostało zrobione - i co było zamierzony.

 0
Author: Ruben,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-05 07:17:11

Niedawno musiałem to zrobić dla dwóch oddzielnych repozytoriów, które mają wspólną historię. Zacząłem od:

  • Org/repository1 master
  • Org/repository2 master

Chciałem, aby wszystkie zmiany z repository2 master zostały zastosowane do repository1 master, akceptując wszystkie zmiany, które wprowadzi repository2. W Warunkach Gita, ta powinna być strategią o nazwie -s theirs, ale nie istnieje. Bądź ostrożny, ponieważ {[5] } nazywa się tak, jak chcesz, ale to jest , a nie to samo (nawet mówi tak na stronie man).

Rozwiązałem to tak, aby przejść do repository2 i stworzyć nową gałąź repo1-merge. W tej gałęzi, uruchomiłem git pull [email protected]:Org/repository1 -s ours i łączy się dobrze bez problemów. Następnie wciskam go do pilota.

Potem wracam do repository1 i tworzę nową gałąź repo2-merge. W tej gałęzi uruchamiam git pull [email protected]:Org/repository2 repo1-merge, który będzie uzupełniał o problemy.

Na koniec, musisz albo wysłać żądanie scalenia w repository1, aby uczynić z niego nowy master, albo po prostu zachować go jako gałąź.

 -1
Author: Trann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-27 14:31:26

Odpowiednik (który zachowuje kolejność nadrzędną) do'git merge-s'

Przed scaleniem:Tutaj wpisz opis obrazka

!!! Upewnij się, że jesteś w czystym stanie !!!

Połącz:

git commit-tree -m "take theirs" -p HEAD -p branchB 'branchB^{tree}'
git reset --hard 36daf519952 # is the output of the prev command
Co zrobiliśmy ? Stworzyliśmy nowy commit, który rodzicom naszym i ich oraz kontentem commita jest branchB-im

Po połączeniu:Tutaj wpisz opis obrazka

Dokładniej:

git commit-tree -m "take theirs" -p HEAD -p 'SOURCE^{commit}' 'SOURCE^{tree}'
 -1
Author: Boaz Nahum,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-29 06:21:36