Jak „nadpisać” zamiast „scalić” oddział w innym oddziale w Git?

257

Mam dwie gałęzie emaili staging. stagingjest najnowszy i nie potrzebuję już starych zmian w emailoddziale, ale nie chcę ich usuwać.

Więc po prostu chcą zrzucić całą zawartość stagingw emailtaki sposób, aby oba wskazują na ten sam popełnił. Czy to jest możliwe?

Rafid
źródło
4
Możliwy duplikat Zmień obecną gałąź na master in git
Tomas Kubes

Odpowiedzi:

196

Możesz użyć strategii scalania „naszej”:

$ git checkout staging
$ git merge -s ours email # Merge branches, but use our branch head
knittl
źródło
26
Próbowałem tego i wydaje mi się to odwrócone? Czy to nie zrzuca zawartości wiadomości e-mail do inscenizacji, a nie na odwrót?
Maks.
27
@Max Miałem to samo zamieszanie i sprawiło mi to wiele problemów. Musisz wykonać to polecenie z nowszej gałęzi (przemieszczanie), a następnie wykonać normalne scalenie / PR do starej gałęzi (e-mail).
MrGlass
7
Dlaczego ;na końcu każdego polecenia? Zrobiłem bez ;i wydaje się, że działa. Również ta odpowiedź jest niekompletna, trzecim krokiem jest sprawdzenie starej gałęzi (e-mail), a następnie ponowne scalenie z inscenizacją.
Rosdi Kasim
4
git rebase -s theirs <oldbranc> <newbranch> działa również (bez względu na to, jaką gałąź posiadasz). Zauważ, że w rebase „ich” to tak naprawdę nowa gałąź, ponieważ „nasza” jest głową, do której obecnie stosujemy zatwierdzenia.
Rolf
4
@Rolf: ale rebase pozbywa się informacji o scalaniu i spłaszcza historię. Niekoniecznie to, czego szukasz. Nie jest to również dobry pomysł, jeśli pracujesz z już opublikowaną historią.
knittl
99

Jeśli chcesz, aby oba e-maile „i” pomostowe były takie same, możesz oznaczyć gałąź „e-mail”, a następnie zresetować gałąź „e-mail” do „pomostowego”:

$ git checkout email
$ git tag old-email-branch
$ git reset --hard staging

Możesz również zmienić podstawę gałęzi „przemieszczania” w gałęzi „e-mail”. Ale wynik będzie zawierał modyfikację dwóch gałęzi.

Sylvain Defresne
źródło
1
prawdopodobnie masz na myśli git checkout, git checkże według mojej wiedzy nie istnieje
knittl
4
Masz rację, jestem tak przyzwyczajony do wypełniania polecenia git, że zawsze piszę „git check <TAB>”, aby napisać „git checkout”! Poprawione
Sylvain Defresne
16
git reset psuje repo innym osobom, które sklonowały twoje repo
Geoffrey De Smet
Uważam, że to właściwa odpowiedź. emailgłowa oddziału powinna po prostu wskazywać tę samą głowę stagingi oboje będą mieli te same zobowiązania, tę samą historię.
cicerocamargo
76

Widziałem kilka odpowiedzi i to jedyna procedura, która pozwoliła mi to naprawić bez żadnych konfliktów.

Jeśli chcesz wszystkie zmiany od branch_new w branch_old, to:

git checkout branch_new
git merge -s ours branch_old
git checkout branch_old
git merge branch_new

po zastosowaniu tych czterech poleceń możesz bez problemu przesuwać rozgałęzienie

Brugolo
źródło
5
Twoja odpowiedź najlepiej pasuje do mojego problemu, ponieważ nie chciałem resetować HEAD, po prostu podaj preferencje dla nowszych plików w nowszej gałęzi podczas łączenia rzeczy w starszą i działało bez problemu! +1
piece
Po „scaleniu naszego” zepchnąłem rozgałęzienie na zdalne i ta metoda zadziałała dla mnie. Czy musiałem naciskać? A może nie zadziałałoby? (Nie byłem pewien, czy użyje lokalnego oddziału, czy zdalnego). Dzięki!
aspergillusOryzae
Dlaczego nie możesz po prostu wykonać poniższych czynności? git kasa oddział_old git scalenie -s ich oddział_nowa Wskazówka zaczerpnięta z stackoverflow.com/questions/14275856/…
Ripu Daman
Mówi, że nie można znaleźć strategii scalania „ich”.
arango_86,
Działa idealnie dla mnie, ma tę zaletę, że niczego nie resetuje
Romain
68

Pozostałe odpowiedzi dały mi właściwe wskazówki, ale nie pomogły całkowicie.

Oto, co zadziałało dla mnie:

$ git checkout email
$ git tag old-email-branch # This is optional
$ git reset --hard staging
$
$ # Using a custom commit message for the merge below
$ git merge -m 'Merge -s our where _ours_ is the branch staging' -s ours origin/email
$ git push origin email

Bez czwartego kroku połączenia ze naszą strategią push jest uważany za aktualizację bez szybkiego przewijania do przodu i zostanie odrzucony (przez GitHub).

Shyam Habarakada
źródło
To sprawia, że ​​komunikat scalania-zatwierdzania jest zły, ale tak, działa świetnie.
cdunn2001
cdunn2001, jestem ciekawa. Jakiej wiadomości oczekujesz od zatwierdzenia korespondencji seryjnej i jak ją to popsuło?
Shyam Habarakada,
Mówi „Scal zdalne śledzenie„ źródła / e-maila ”w e-mailu”. Nie wspomina o inscenizacji. Ale nic wielkiego. Po prostu zmień zatwierdzenie lub użyj merge -m 'This is not my beautiful house.' -s ours origin/email.
cdunn2001
@ShyamHabarakada, robię, co mówisz, i pojawia się problem z aktualizacją nie do szybkiego przewijania. ponieważ nic się nie dzieje, gdy robię czwarty krok.
kommradHomer
Czwarty krok wymaga użycia źródła / e-maila, nie działa tylko z lokalnym adresem e-mail.
Travis Reeder,
45

Jeśli jesteś podobny do mnie i nie chcesz zajmować się scalaniem, możesz wykonać powyższe kroki, z wyjątkiem użycia siły zamiast scalania, ponieważ spowoduje to rozpraszający ślad dziennika papieru:

git checkout email
git reset --hard staging
git push origin email --force

Uwaga: Dzieje się tak tylko wtedy, gdy NAPRAWDĘ nigdy nie chcesz ponownie wyświetlać treści w wiadomości e-mail.

jsarma
źródło
1
e-mail git push origin - force nie działało dla mnie, ponieważ Step2 pozostawił rozbieżne gałęzie. Więc po kroku 2 to właśnie zrobiłem: git reset origin / email, a następnie git push
user3505394
2
Właśnie o to pytano - „jak nadpisać, a nie scalić”. Należy przyjąć odpowiedź.
jozols
17

Chciałem połączyć dwie gałęzie, aby cała zawartość old_branchzostała zaktualizowana o zawartość znew_branch

Dla mnie działało to jak urok:

$ git checkout new_branch
$ git merge -m 'merge message' -s ours origin/old_branch
$ git checkout old_branch
$ git merge new_branch
$ git push origin old_branch
Madhu
źródło
10

Co powiesz na:

git branch -D email
git checkout staging
git checkout -b email
git push origin email --force-with-lease
Arek S.
źródło
@emptywalls, ponieważ wymusza push bez ostrzeżenia użytkownika, że ​​może zostać odrzucony przez serwer, ani nie wyjaśnia, dlaczego jest potrzebny. To powiedziawszy, jest to opłacalna opcja dla projektu z jednym deweloperem
David Costa
@DavidCosta dlaczego serwer zostałby odrzucony? to jest proste usuwanie gałęzi e-mail i kopiowanie etapowe do wiadomości e-mail… Chcę tylko zrzucić całą zawartość „etapowego” do „e-mail”, aby oba wskazywały na to samo zatwierdzenie ”- dokładnie tak się dzieje tutaj.
Arek S
@ArekS może zostać odrzucony przez hak po stronie serwera, jeśli gałąź jest ustawiona jako „chroniona” np. W GitLab. Problem polega na tym, że jeśli ktoś inny wyprowadził swój oddział z poczty e-mail przed tą operacją, a następnie spróbuje wypchnąć, referencje już się nie zgadzają (ponieważ niektóre zatwierdzenia po prostu zniknęły)
David Costa
1
Zredagowałem oryginał z --force na --force-with-lease, który robi to w nieniszczący sposób.
frandroid
1
Jest to najlepszy sposób, jeśli chcesz po prostu zdmuchnąć gałąź i uruchomić ją czysto z gałęzi źródłowej.
Shane
6

Inne odpowiedzi wyglądały na niepełne.
Próbowałem w pełni poniżej i działało dobrze.

UWAGA:
1. Wykonaj kopię swojego repozytorium, zanim spróbujesz poniżej, aby zachować bezpieczeństwo.

Szczegóły:
1. Cały rozwój odbywa się w gałęzi
programistów
3. Od czasu do czasu kod musi zostać przeniesiony / nadpisany do gałęzi qa

więc musimy zastąpić gałąź qa z gałęzi dev

Część 1:
Za pomocą poniższych poleceń starsza qa została zaktualizowana do nowszego dev:

git checkout dev
git merge -s ours qa
git checkout qa
git merge dev
git push

Automatyczny komentarz do ostatniego push daje poniżej:

// Output:
//  *<MYNAME> Merge branch 'qa' into dev,*  

Ten komentarz wygląda odwrotnie, ponieważ powyższa sekwencja również wygląda odwrotnie

Część 2:

Poniżej znajdują się nieoczekiwane, nowe lokalne zobowiązania w dev, niepotrzebne,
więc musimy wyrzucić i uczynić dev nietkniętym.

git checkout dev

// Output:
//  Switched to branch 'dev'  
//  Your branch is ahead of 'origin/dev' by 15 commits.  
//  (use "git push" to publish your local commits)


git reset --hard origin/dev  

//  Now we threw away the unexpected commits

Część 3:
Sprawdź, czy wszystko jest zgodne z oczekiwaniami:

git status  

// Output:
//  *On branch dev  
//  Your branch is up-to-date with 'origin/dev'.  
//  nothing to commit, working tree clean*  

To wszystko.
1. stara qa jest teraz nadpisywana przez nowy kod oddziału dewelopera
2. local is clean (zdalne pochodzenie / dev jest nietknięte)

Manohar Reddy Poreddy
źródło
6

Najłatwiejszy sposób to zrobić:

//the branch you want to overwrite
git checkout email 

//reset to the new branch
git reset --hard origin/staging

// push to remote
git push -f

Teraz gałąź e-maila i inscenizacja są takie same.

B.Neo
źródło
2
Ostrzeżenie: powoduje to usunięcie wszystkich zatwierdzeń w emailoddziale. To jak usuwanie emailgałęzi i tworzenie jej od nowa na czele staginggałęzi.
Cameron Hudson,
2
git checkout email
git merge -m "Making email same as staging disregarding any conflicts from email in the process" -s recursive -X theirs staging
Willa
źródło
1
Ta odpowiedź byłaby dla mnie jaśniejsza, gdyby komentarz został oddzielony od komentarza łączącego się w poleceniu. Wyjaśnij krótko, co robi -X i jak wpływa na to scalenie. W każdym razie dzięki.
Sprawił,
@noelicus dzięki za komentarz i masz rację. Mogę edytować odpowiedź w przyszłości.
Willa
0

Ten nie zmienia oryginalnej nowszej gałęzi i daje możliwość dokonania dalszych modyfikacji przed ostatecznym zatwierdzeniem.

git checkout new -b tmp
git merge -s ours old -m 'irrelevant'
git checkout old
git merge --squash tmp
git branch -D tmp
#do any other stuff you want
git add -A; git commit -m 'foo' #commit (or however you like)
Jan Kyu Peblik
źródło