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.
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 uruchomgit 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
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
.
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.
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)
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 jestTo 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).
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
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
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
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.
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
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>
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
" istniejeOpis 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ństwoours
", 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.
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]}.
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
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.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.
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.
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łąź.
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'
!!! 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
Dokładniej:
git commit-tree -m "take theirs" -p HEAD -p 'SOURCE^{commit}' 'SOURCE^{tree}'
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