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 i keepTheirs
skrypt:
mv -f $3 $2
exit 0
git merge --strategy=theirs
Symulacja nr 1
Pokazuje 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:
git checkout -b tmp origin/upstream
git merge -s ours downstream # ignoring all changes from downstream
git checkout downstream
git merge tmp # fast-forward to tmp HEAD
git branch -D tmp # deleting tmp
Ma to tę zaletę, że rejestruje górnego przodka jako pierwszego rodzica, więc scalanie oznacza „wchłonąć tę nieaktualną gałąź tematu” zamiast „zniszczyć tę gałąź tematu i zastąpić ją upstream” .
(Edycja 2011):
Ten przepływ pracy został zgłoszony w tym poście na blogu przez OP :
Dlaczego chcę tego ponownie?
O ile moje repozytorium nie miało nic wspólnego z wersją publiczną, wszystko było w porządku, ale ponieważ teraz chciałbym mieć możliwość porównywania WIP z innymi członkami zespołu i współpracownikami zewnętrznymi, chcę się upewnić, że moje publiczne oddziały są niezawodny dla innych do rozgałęziania się i ściągania, tj. koniec z ponownym bazowaniem i resetowaniem rzeczy, które wypchnąłem do zdalnej kopii zapasowej, ponieważ jest teraz na GitHub i publicznie.
Więc zostaję z tym, jak mam postępować.
W 99% przypadków moja kopia trafia do nadrzędnego mastera, więc chcę pracować z moim masterem i przez większość czasu przesyłać do nadrzędnego.
Ale od czasu do czasu to, co mam w wip
sobie, zostanie unieważnione przez to, co trafi do górnego strumienia i porzucę jakąś część mojego wip
.
W tym momencie chcę zsynchronizować mojego mastera z nadrzędnym, ale nie niszczyć żadnych punktów commita na moim publicznie wypchniętym masterze. To znaczy, chcę scalić z nadrzędnym, który kończy się zestawem zmian, który sprawi, że moja kopia będzie identyczna z nadrzędną .
I to właśnie git merge --strategy=theirs
powinno zrobić.
git merge --strategy=theirs
Symulacja nr 2
Pokazuje jako połączenie, z naszym jako pierwszym rodzicem.
(zaproponowane przez jcwenger )
git checkout -b tmp upstream
git merge -s ours thebranch # ignoring all changes from downstream
git checkout downstream
git merge --squash tmp # apply changes from tmp but not as merge.
git rev-parse upstream > .git/MERGE_HEAD #record upstream 2nd merge head
git commit -m "rebaselined thebranch from upstream" # make the commit.
git branch -D tmp # deleting tmp
git merge --strategy=theirs
Symulacja nr 3
W tym poście na blogu wspomniano :
git merge -s ours ref-to-be-merged
git diff --binary ref-to-be-merged | git apply -R --index
git commit -F .git/COMMIT_EDITMSG --amend
czasami chcesz to zrobić i nie dlatego, że masz „bzdury” w swojej historii, ale być może dlatego, że chcesz zmienić podstawę rozwoju w repozytorium publicznym, w którym należy unikać ponownego bazowania .
git merge --strategy=theirs
Symulacja nr 4
(ten sam post na blogu)
Alternatywnie, jeśli chcesz, aby lokalne gałęzie upstream były szybkie do przodu, potencjalnym kompromisem jest praca ze zrozumieniem, że w przypadku sid / unstable gałąź nadrzędna może od czasu do czasu zostać zresetowana / zmieniona (na podstawie zdarzeń, które ostatecznie nie istnieją kontroli po stronie projektu).
To nie jest wielka sprawa, a praca z tym założeniem oznacza, że łatwo jest utrzymać lokalną gałąź nadrzędną w stanie, w którym pobiera tylko szybkie aktualizacje.
git branch -m upstream-unstable upstream-unstable-save
git branch upstream-unstable upstream-remote/master
git merge -s ours upstream-unstable
git diff --binary ref-to-be-merged | git apply -R --index --exclude="debian/*"
git commit -F .git/COMMIT_EDITMSG --amend
git merge --strategy=theirs
Symulacja nr 5
(zaproponowane przez Baraka A. Pearlmuttera ):
git checkout MINE
git merge --no-commit -s ours HERS
git rm -rf .
git checkout HERS -- .
git checkout MINE -- debian # or whatever, as appropriate
git gui # edit commit message & click commit button
git merge --strategy=theirs
Symulacja # 6
(zaproponowane przez tego samego Michaela Gebetsroithera ):
Michael Gebetsroither włączył się, twierdząc, że „oszukuję”;) i podał inne rozwiązanie z komendami niższego poziomu:
(nie byłoby to git, gdyby nie było to możliwe za pomocą poleceń tylko git, wszystko w git z diff / patch / apply nie jest prawdziwym rozwiązaniem;).
# get the contents of another branch
git read-tree -u --reset <ID>
# selectivly merge subdirectories
# e.g superseed upstream source with that from another branch
git merge -s ours --no-commit other_upstream
git read-tree --reset -u other_upstream # or use --prefix=foo/
git checkout HEAD -- debian/
git checkout HEAD -- .gitignore
git commit -m 'superseed upstream source' -a
git merge --strategy=theirs
Symulacja # 7
Niezbędne kroki można opisać jako:
- Zastąp swoje drzewo robocze usługą upstream
- Zastosuj zmiany do indeksu
- Dodaj powyżej jako drugiego rodzica
- Popełnić
Polecenie git read-tree
zastępuje indeks innym drzewem, wykonując drugi krok , i zawiera flagi do aktualizacji drzewa roboczego, wykonując pierwszy krok . Podczas zatwierdzania git używa SHA1 w .git / MERGE_HEAD jako drugiego rodzica, więc możemy go wypełnić, aby utworzyć zatwierdzenie scalające. Dlatego można to osiągnąć za pomocą:
git read-tree -u --reset upstream # update files and stage changes
git rev-parse upstream > .git/MERGE_HEAD # setup merge commit
git commit -m "Merge branch 'upstream' into mine" # commit