Git i „Gałąź„ x ”nie jest całkowicie scalona” Błąd


294

Oto polecenia, których użyłem z gałęzi master

git branch experiment
git checkout experiment

Następnie wprowadziłem kilka zmian w moich plikach, zatwierdziłem zmiany i przekazałem nowy oddział do GitHub.

git commit . -m 'changed files'
git push -u origin experiment

Później postanowiłem połączyć gałąź eksperymentu z gałęzią master.

git checkout master
git merge experiment

W końcu wprowadziłem zmiany do GitHub.

git push -u origin master

Wszystko poszło dobrze, dopóki nie spróbowałem usunąć mojej gałęzi eksperymentu za pomocą

git branch -d experiment

Dostałem komunikat o błędzie, error: The branch 'experiment' is not fully merged.że jestem trochę nowy w git i nie wiem, o ile więcej mógłbym połączyć te dwie gałęzie. Czego tu brakuje?



2
To pojawia się czasami, kiedy zrobiłemgit commit --amend
Arcolye

12
Ponadto - należy pamiętać, że ten komunikat pojawi się po squash: stackoverflow.com/q/41946475/109941
Jim G.

Myślę, że najczęstszym scenariuszem jest po prostu wyciągnięcie nowo scalonych zmian, zanim usuniesz oddział lokalnie.
RaisinBranCrunch

Odpowiedzi:


313

Uwaga Sformułowanie zmieniło się w odpowiedzi na przykazania. Dzięki @slekse
To nie jest błąd, to ostrzeżenie. Oznacza to, że gałąź, którą zamierzasz usunąć, zawiera zatwierdzenia, które nie są dostępne z żadnego z: jej odgałęzienia lub HEAD (obecnie sprawdzona wersja). Innymi słowy, kiedy możesz stracić zatwierdzenia¹.

W praktyce oznacza to, że prawdopodobnie poprawiłeś, przebudowałeś lub przefiltrowałeś zatwierdzenia i nie wydają się one identyczne.

Dlatego możesz uniknąć ostrzeżenia , sprawdzając gałąź, która zawiera zatwierdzenia, których nie chcesz odwoływać , usuwając ten drugi oddział .²

Będziesz chciał sprawdzić, czy w rzeczywistości nie brakuje Ci żadnych istotnych zmian:

git log --graph --left-right --cherry-pick --oneline master...experiment

To da ci listę wszelkich nieudostępnionych między oddziałami. Jeśli jesteś ciekawy, może istnieć --cherry-pickróżnica, która może być przyczyną ostrzeżenia, które otrzymasz:

--cherry-pick

Pomiń wszelkie zatwierdzenia, które wprowadzają tę samą zmianę, co inne zatwierdzenia po „drugiej stronie”, gdy zbiór zatwierdzeń jest ograniczony różnicą symetryczną. Na przykład, jeśli masz dwie gałęzie, A i B, zwykłym sposobem wylistowania wszystkich zatwierdzeń tylko po jednej stronie jest użycie opcji - w lewo, jak w powyższym przykładzie w opisie tej opcji. Pokazuje jednak zatwierdzenia, które zostały wybrane z innej gałęzi (na przykład „3 na b” może być wybrane z gałęzi A). Dzięki tej opcji takie pary zatwierdzeń są wykluczane z wyjścia.


¹ Domyślnie są to tak naprawdę śmieci po pewnym czasie. Ponadto git-branchpolecenie nie sprawdza drzewa zmian wszystkich gałęzi . Ostrzeżenie ma na celu uniknięcie oczywistych błędów.

² (W tym przypadku wolę wymusić usunięcie, ale możesz potrzebować dodatkowego zabezpieczenia).


24
Dzięki. Kluczowe zdanie brzmiało: „zawiera zatwierdzenia, które nie są osiągalne z żadnego innego nagłówka referencyjnego”. Mimo że nie potrzebowałem już gałęzi eksperymentu i już połączyłem ją w master i planowałem usunąć ją z pochodzenia, git nie będzie szczęśliwy, dopóki nie przekażę zmian eksperymentowi do źródła. Wydaje mi się, że to ostrzeżenie było pewnego rodzaju sprawdzeniem rozsądku.
mellowsoon,

35
-1 „Oznacza to, że gałąź, którą zamierzasz usunąć, zawiera zatwierdzenia, których nie można uzyskać z żadnej innej głowicy referencyjnej.” To nie jest poprawne. Ostrzeżenie oznacza, że ​​gałąź nie jest osiągalna ani z jej górnej części (jeśli ma taką), ani z bieżącej HEAD. Zobacz stronę git-branch.
sleske,

3
@TachyonVortex Nice link. Polecenie git branch -vv naprawdę wyjaśniło, co się dla mnie dzieje.
Jason Massey

11
@sleske Dzięki za komentarz - ta odpowiedź powinna być naprawdę zredagowana. Szkoda, że ​​jest wysoko oceniany, ponieważ główne zdanie wyjaśniające jest nieprawidłowe. Właśnie miałem ten problem i spędziłem denerwująco długi czas próbując dowiedzieć się, na czym polega problem, i po prostu usunięto gałąź zdalnego śledzenia w ramach żądania ściągnięcia, a od czasu, gdy wyciągnąłem zmiany z mastera w lokalnym oddziale. Jedynym „problemem” nie było znalezienie zdalnej gałęzi śledzenia, która została usunięta (i próbowałem usunąć gałąź lokalną z tego samego powodu).
ely

3
Tak, może się to zdarzyć tylko podczas próby usunięcia lokalnego oddziału, jeśli jesteś w innym oddziale, niż ten, w którym byłeś podczas jego tworzenia. „Zobowiązania, które nie są dostępne z żadnego innego źródła” są niepoprawne i niepotrzebnie przerażające!
Amalgovinus

80

Jak Drew Taylor podkreślił, usuwanie gałęzi z -d uważa tylko obecną głowę w określaniu, czy oddział jest „w pełni scalone”. Będzie narzekać, nawet jeśli oddział zostanie połączony z innym oddziałem. Komunikat o błędzie może być zdecydowanie wyraźniejszy w tym względzie ... Możesz usunąć połączoną gałąź przed usunięciem lub po prostu użyć gałęzi git -D. Wielka-D całkowicie zastąpi czek.


2
Naprawiono to dla mnie w części o aktualnej HEAD. Mój mistrz różnił się od gałęzi funkcji, dla której stworzyłem gałąź sprzeczną: D
viki.omega9

1
Dla kogoś, kto uczy się gita, słowo „prąd” wydaje się zbędne z „HEAD”? Nie ma czegoś takiego jak uncurrent HEAD - głowa z definicji jest obecny oddział. Czy coś brakuje? Przypuszczam, że można powiedzieć „obecna gałąź” lub „HEAD”, ale nie „bieżąca HEAD”.
Mark Lakata

Czy jest jakiś sposób, aby to zmienić / skonfigurować (np. Czy zawsze ma to sprawdzać origin/master?). Wydaje mi się, że origin/masternajpierw sprawdzenie nie jest zbyt uciążliwe, ale wydaje się, że to dziwny przepływ - dlaczego muszę to sprawdzić origin/masterlokalnie tylko po to, aby sprawdzić, czy moje zmiany zostały tam scalone?
Alec

15

Próbowałem sprawdzić odpowiedź i to nie zadziałało.

Aby znaleźć zatwierdzenia, które nie zostały scalone, wystarczy użyć:

git log feature-branch ^master --no-merges

14

Zdarzyło mi się to dzisiaj, kiedy połączyłem moją pierwszą gałąź funkcji z powrotem w master. Jak niektórzy powiedzieli w wątku w innym miejscu na SO, sztuczka polegała na przełączeniu się z powrotem na master przed próbą usunięcia gałęzi. Po powrocie do master git chętnie usunął gałąź bez ostrzeżeń.


7
Nie wygląda na to, że jest to konkretny problem tutaj, ale napotkałem problem, który właśnie opisujesz, więc dziękuję!
Daniel Buckmaster

4

Git ostrzega, że ​​możesz utracić historię, usuwając tę ​​gałąź. Mimo że tak naprawdę nie usuwałby od razu żadnych zatwierdzeń, niektóre lub wszystkie zatwierdzenia w oddziale stałyby się nieosiągalne, gdyby nie były również częścią innego oddziału.

Aby gałąź experimentzostała „w pełni scalona” z inną gałęzią, zatwierdzanie jej końcówki musi być przodkiem końcówki drugiej gałęzi, co powoduje, że zatwierdzenia experimentsą podzbiorem drugiej gałęzi. Dzięki temu można go bezpiecznie usunąć experiment, ponieważ wszystkie jego zatwierdzenia pozostaną częścią historii repozytorium za pośrednictwem drugiego oddziału. Musi być „całkowicie” scalony, ponieważ mógł być już kilkakrotnie scalony, ale teraz dodano zatwierdzenia od ostatniego scalenia, które nie są zawarte w drugiej gałęzi.

Git nie sprawdza jednak co drugiej gałęzi w repozytorium; tylko dwa:

  1. Obecny oddział (HEAD)
  2. Gałąź powyżej, jeśli taka istnieje

Prawdopodobnie „odgałęzienie” dla experiment, jak w twoim przypadku, jest origin/experiment. Jeśli experimentjest w pełni scalony w bieżącym oddziale, to Git usuwa go bez reklamacji. Jeśli nie jest, ale jest w pełni scalony w swoim odgałęzieniu, Git kontynuuje z ostrzeżeniem wyglądającym jak:

warning: deleting branch 'experiment' that has been merged
to 'refs/remotes/origin/experiment', but not yet merged to
HEAD.
Deleted branch experiment (was xxxxxxxx).

Gdzie xxxxxxxxwskazuje identyfikator zatwierdzenia. Bycie w pełni zintegrowanym w jego górnej części oznacza, że ​​zatwierdzenia experimentzostały wypchnięte do repozytorium źródłowego, więc nawet jeśli je zgubisz tutaj, można je przynajmniej zapisać gdzie indziej.

Ponieważ Git nie sprawdza innych gałęzi, bezpieczne może być usunięcie gałęzi, ponieważ wiesz, że jest ona w pełni połączona z inną gałęzią; możesz to zrobić z -Dopcją, jak wskazano, lub przełączyć się najpierw na ten oddział i pozwolić Gitowi potwierdzić w pełni scalony status.


1
Klucz jest „w pełni scalony w bieżącym oddziale”. Miałem gałąź X 'z X całkowicie scaloną z powrotem w X i już usunąłem origin / X'. Ale po sprawdzeniu Y dostałem to ostrzeżenie. Kiedy się wymeldowałem, XI był w stanie usunąć X '. Myślę, że to raczej głupie.
Lawrence Dol

2
Ta odpowiedź jest plagiatem stąd bez przypisania chimera.labs.oreilly.com/books/1230000000561/...
Mark Lakata

3

aby zobaczyć zmiany, które nie zostały scalone, zrobiłem to:

git checkout experiment
git merge --no-commit master

git diff --cached

Uwaga: pokazuje zmiany master, których nie ma w experiment.

Nie zapomnij:

git merge --abort

Kiedy skończysz, spójrz.


@IgorGanapolsky Dunno dokładnie, choć zwykle man git-reseti polecenia resetowania git wystarczą, aby wyjść z problemów ze stanem.
ThorSummoner,

3

Najłatwiejsze rozwiązanie z wyjaśnieniem (rozwiązanie dwukrotnie sprawdzone) (wcześniej napotkano problem)

Rzecz w tym:

1- Nie mogę usunąć gałęzi

2 - Terminal wyświetla komunikat ostrzegawczy, że niektóre zatwierdzenia nie zostały jeszcze zatwierdzone

3- wiedząc, że sprawdziłem master i oddział i są one identyczne (aktualne)

rozwiązanie:

git checkout master
git merge branch_name
git checkout branch_name
git push
git checkout master
git branch -d branch_name

Wyjaśnienie:

kiedy twoja gałąź jest połączona z odgałęzieniem zdalnym odgałęzienia (na Github, bitbucket lub cokolwiek), musisz scalić (wypchnąć) to do master, i musisz wypchnąć nowe zmiany (zatwierdzenia) do zdalnego repozytorium (Github, bitbucket lub cokolwiek) z oddziału,

w kodzie zrobiłem to, że przełączyłem się na master, a następnie scaliłem z nim gałąź (aby upewnić się, że są one identyczne na twoim komputerze lokalnym), następnie ponownie przełączyłem się na gałąź i wrzuciłem aktualizacje lub zmiany do zdalnego online repo przy użyciu „git push”.

potem ponownie przełączyłem się na master i próbowałem usunąć gałąź, a problem (komunikat ostrzegawczy) zniknął, a gałąź usunięta pomyślnie


3

Możesz po prostu dowiedzieć się:

git log --cherry master ... eksperymentalny

--cherry opcja jest synonimem --right-only --cherry-mark --no-merges

Powiedziała strona git-log

warto ograniczyć dane wyjściowe do zatwierdzeń po naszej stronie i zaznaczyć te, które zostały zastosowane po drugiej stronie rozwidlonej historii za pomocą git log --cherry upstream ... mybranch, podobnie jak git cherry up mybranch.

Do Twojej wiadomości --cherry-pickpomija równoważne zatwierdzenia, ale --cherry-marksnie robi. Przydatne jest znajdowanie bazy i wymuszanie zaktualizowanych zmian między upstream a współpracującym oddziałem publicznym


1

Nie miałem oddziału upstream na moim lokalnym git. Utworzyłem lokalny oddział z master, git checkout -b mybranch. Utworzyłem gałąź z GUI bitbucket na gitie upstream i przekazałem moją gałąź lokalną (mybranch) do tej gałęzi upstream. Kiedy zrobiłem pobieranie git na moim lokalnym git, aby pobrać gałąź upstream, mogłem zrobić gałąź git -d mybranch.


0

Wierzę, że flaga --forcejest tym, czego naprawdę szukasz. Wystarczy użyć, git branch -d --force <branch_name>aby wymusić usunięcie gałęzi.

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.