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?


Odpowiedzi:


196

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

$ git checkout staging
$ git merge -s ours email # Merge branches, but use our branch head

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.


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


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).


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.


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

10

Co powiesz na:

git branch -D email
git checkout staging
git checkout -b email
git push origin email --force-with-lease

@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)


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.


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

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)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.