Próbuję wziąć gałąź ze zmianami i przywrócić ją, aby była identyczna z wyższą wersją, od której się odbiegła. Zmiany są zarówno lokalne, jak i zostały zepchnięte na github, więc żadne z nich git reset
lub nie git rebase
są naprawdę wykonalne, ponieważ zmieniają historię, co jest złe w przypadku gałęzi, która została już wypchnięta.
Próbowałem również git merge
z różnymi strategiami, ale żadna z nich nie cofnęła lokalnych zmian, tj. Gdybym dodał plik, scalenie może przywrócić inne pliki, ale nadal będę mieć ten plik, którego nie ma nadrzędny mieć.
Mógłbym po prostu utworzyć nową gałąź poza upstreamem, ale naprawdę chciałbym scalić, które pod względem historii zmian zastosuje wszystkie zmiany, aby wziąć moją gałąź i uczynić ją identyczną z nadrzędną, aby móc bezpiecznie wprowadzić tę zmianę bez bijącej historii. Czy jest takie polecenie lub seria poleceń?
źródło
Odpowiedzi:
Mógłbyś połączyć swoją gałąź nadrzędną ze swoją
dev
gałęzią, z niestandardowym sterownikiem scalającym „keepTheirs” :Zobacz „ ”
git merge -s theirs
”potrzebny - ale wiem, że nie istnieje ”.W twoim przypadku
.gitattributes
potrzebny byłby tylko jeden ikeepTheirs
skrypt:git merge --strategy=theirs
Symulacja nr 1Pokazuje jako scalenie, z nadrzędnym jako pierwszym rodzicem.
Jefromi wspomina (w komentarzach) o
merge -s ours
, scalając twoją pracę na nadrzędnym (lub tymczasowej gałęzi zaczynającej się od wyższego szczebla), a następnie przewijając twoją gałąź do wyniku tego scalenia:(Edycja 2011):
Ten przepływ pracy został zgłoszony w tym poście na blogu przez OP :
git merge --strategy=theirs
Symulacja nr 2Pokazuje jako połączenie, z naszym jako pierwszym rodzicem.
(zaproponowane przez jcwenger )
git merge --strategy=theirs
Symulacja nr 3W tym poście na blogu wspomniano :
git merge --strategy=theirs
Symulacja nr 4(ten sam post na blogu)
git merge --strategy=theirs
Symulacja nr 5(zaproponowane przez Baraka A. Pearlmuttera ):
git merge --strategy=theirs
Symulacja # 6(zaproponowane przez tego samego Michaela Gebetsroithera ):
git merge --strategy=theirs
Symulacja # 7źródło
git checkout upstream; git merge -s ours downstream; git checkout downstream; git merge upstream
. (W razie potrzeby użyj tymczasowej gałęzi u góry strumienia). Ma to tę zaletę, że zapisuje przodka z wyższego poziomu jako pierwszego rodzica, dzięki czemu scalanie oznacza „wchłonąć tę nieaktualną gałąź tematu” zamiast „zniszczyć tę gałąź tematu i zastąpić z upstreamem ”.Wydaje mi się, że po prostu musisz to zrobić:
Jeśli nie ma żadnej zmiany do wypychania w górę i po prostu chcesz, aby gałąź upstream była twoją bieżącą gałęzią, zrobi to. Robienie tego lokalnie nie jest szkodliwe, ale utracisz wszelkie lokalne zmiany **, które nie zostały wprowadzone do perfekcji.
** Właściwie zmiany są nadal dostępne, jeśli zatwierdziłeś je lokalnie, ponieważ zatwierdzenia będą nadal dostępne w Twoim
git reflog
, zwykle przez co najmniej 30 dni.źródło
Możesz to zrobić teraz dość łatwo:
Dzięki temu lokalne repozytorium jest zsynchronizowane z pochodzeniem i zachowuje historię.
źródło
git merge -s recursive -Xtheirs
nie łączy automatycznie plików binarnych, więc znajdujesz się w sytuacji konfliktu, którą musisz rozwiązać ręcznie. Przepływy pracy oparte nagit merge -s ours
tym nie cierpią.git show
przy zatwierdzaniu scalającym pokazuje tylko rozwiązania konfliktów i-Xtheirs
oczywiście nie ma rozwiązań konfliktów, jeśli są używane.Kolejna symulacja dla
git merge -s theirs ref-to-be-merged
:Alternatywą dla podwójnego resetu byłoby zastosowanie odwróconej łatki:
źródło
HEAD^2
) Metoda łatki zadziałała.^
poprawnie. Czasami inne naciśnięcia klawiszy, takie jak „ctrl-c”, są wyświetlane jako „^ C”. - Jeśli naprawdę wpisałeś poprawne "^", znalazłeś poważny błąd w swojej wersji git.git reset --hard HEAD^^2; git reset --soft HEAD@{1}
Jest też sposób z niewielką pomocą polecenia hydraulicznego - IMHO najprostszy. Załóżmy, że chcesz emulować „ich” w przypadku dwóch gałęzi:
Łączy to dowolną liczbę głowic (2 w powyższym przykładzie) przy użyciu drzewa jednej z nich (pasek w powyższym przykładzie, dostarczający drzewo `` ich ''), pomijając wszelkie problemy z różnicami / plikami (drzewo zatwierdzeń jest poleceniem niskiego poziomu, więc nie dba o to). Zauważ, że głowa może mieć tylko 1 (czyli odpowiednik „cherry-pick” z „ich”).
Zauważ, że to, która głowa rodzica jest określona jako pierwsza, może wpłynąć na niektóre rzeczy (zobacz np. --First-parent polecenia git-log) - więc miej to na uwadze.
Zamiast git-show można użyć wszystkiego, co jest w stanie wyprowadzić skróty drzewa i zatwierdzenia - cokolwiek jest używane do analizowania (plik-cat, lista-obrotów, ...). Możesz śledzić wszystko za pomocą git commit --amend do interaktywnego upiększania wiadomości o zatwierdzeniu.
źródło
Ciężka ręka, ale do diabła, co może się nie udać?
cp -r .git /tmp
git checkout y
rm -rf .git && cp -r /tmp/.git
.źródło
przejdź do zdalnej gałęzi nadrzędnej i wykonaj
git merge
ze strategią scalania ustawioną naours
.Cała historia będzie nadal obecna, ale będziesz mieć dodatkowe zatwierdzenie scalenia. Ważne jest, aby zacząć od wersji, w której chcesz być, i połączyć się
ours
z gałęzią, w której aktualnie znajduje się github.źródło
--strategy=theirs
, ale najbliżsi--strategy=recursive -X=theirs
tego nie robią.--strategy=theirs
jest przeciwieństwem--strategy=ours
. Zaczynasz od przeciwnego końca (więc zacznij od github i połącz w drugą stronę).--strategy=theirs
, co jest problemem. Najbliższe jest to,--strategy=recursive -X theirs
co nie jest zupełnie odwrotne, ponieważ nie usunie obcych zmian lokalnych, jeśli nie będą kolidować.git checkout dev; git merge origin/master --strategy=ours
igit checkout origin/master; git merge dev --strategy=ours
ours
strategii całkowicie umożliwia wykonanietheirs
strategii.Użyj git reset BACKWARDS!
Możesz sprawić, że gałąź będzie wyglądać jak każdy inny commit z
git reset
, ale musisz to zrobić w sposób okrężny.Aby gałąź po zatwierdzeniu
<old>
wyglądała jak zatwierdzenie<new>
, możesz to zrobićżeby zrobić
<new>
zawartości drzewa roboczego.Więc zrób
aby zmienić gałąź z powrotem na oryginalne zatwierdzenie, ale pozostawiając drzewo robocze w
<new>
stanie .Następnie możesz dodać i zatwierdzić zmiany, aby Twoja gałąź dokładnie pasowała do zawartości pliku
<new>
zatwierdzenia.To sprzeczne z intuicją, że aby przejść ze
<old>
stanu do stanu<new>
, należy wykonaćgit reset
od<new>
do<old>
. Jednak w przypadku opcji--mixed
drzewo robocze jest pozostawione na,<new>
a wskaźnik gałęzi ustawiony na<old>
, więc po zatwierdzeniu zmian gałąź wygląda tak, jak chcemy.Ostrzeżenie
Nie trać z oczu swoich zatwierdzeń, np. Zapomnij o tym, co
<old>
robiszgit reset --hard <new>
.źródło
Podążałem za tymi rolami:
Pobierając źródło, resetuj mocno z gałęzi, a następnie rekurencyjnie z ich gałęzi, a następnie wymuszaj wypychanie na gałąź
NA WŁASNE RYZYKO
źródło