Raporty scalania Git „Już aktualne”, choć jest różnica


286

Mam repozytorium git z 2 gałęziami: master i test.

Istnieją różnice między gałęziami master i testowymi.

W obu oddziałach wprowadzono wszystkie zmiany.

Jeśli zrobię:

Git Checkout Master
test git diff

Pojawi się ekran pełen zmian pokazujący różnice. Chcę scalić zmiany w gałęzi testowej, a więc:

test scalania git

Ale dostań komunikat „Już aktualny”

Jednak przeglądanie plików w każdej gałęzi wyraźnie pokazuje różnice.

Na czym polega problem i jak go rozwiązać?


Czy masz niezatwierdzony zmodyfikowany kod?
ozma

Odpowiedzi:


146

Komunikat „Już aktualny” oznacza, że ​​wszystkie zmiany z gałęzi, którą próbujesz scalić, zostały już scalone z gałęzią, w której aktualnie się znajdujesz. Mówiąc dokładniej, oznacza to, że gałąź, którą próbujesz scalić, jest rodzicem twojej bieżącej gałęzi . Gratulacje, to najłatwiejsze połączenie, jakie kiedykolwiek wykonałeś. :)

Użyj, gitkaby przejrzeć swoje repozytorium. Etykieta gałęzi „test” powinna znajdować się gdzieś poniżej etykiety gałęzi „master”.

Twój oddział jest aktualny w stosunku do swojego rodzica. Według scalenia nie ma żadnych nowych zmian w rodzicu od ostatniego scalenia. To nie znaczy, że gałęzie są takie same, ponieważ możesz wprowadzić wiele zmian w działającej gałęzi i brzmi to tak jak Ty.

Edytuj 10/12/2019:

Według Charlesa Drake'a w komentarzu do tej odpowiedzi jednym z rozwiązań tego problemu jest:

git checkout master
git reset --hard test

Powoduje to powrót do poziomu „testowego”.

Następnie wykonaj:

git push --force origin master

w celu wymuszenia zmian z powrotem do centralnego repozytorium.


2
Holy cr * p! Masz rację! Myślę, że stało się, że inna gałąź (niestabilna wersja) została niepoprawnie połączona z master, a gałąź testowa była podzestawem niestabilnym. Scaleniem, które próbowałem wykonać, było przywrócenie mistrza do poziomu „testowego”.
Charles Darke,

2
Dobrze. Ta operacja nie miałaby sensu, więc Git nie chce nic zrobić. :)
Bombe,

24
To, co teraz zrobiłem, to: git checkout master; reset git - twardy test; Powoduje to powrót do poziomu „testowego”. Potem zrobiłem „git push - force origin master”, aby wymusić zmiany z powrotem do centralnego repozytorium.
Charles Darke,

22
Byłoby miło, gdyby git miał ostrzeżenie „próbuje połączyć się z rodzicem”.
Charles Darke,

1
Pchanie gałęzi, która nie jest potomkiem gałęzi już istniejącej po drugiej stronie, jest uważane za coś złego: Zobacz dyskusje na stronach podręcznika dla git-push i git-pull.
Bombe,

131

Zdarza mi się to często, gdy wiem, że w zdalnym systemie głównym wprowadzono zmiany, więc próbuję je scalić za pomocą git merge master. Nie łączy się to jednak ze zdalnym urządzeniem głównym, ale z lokalnym urządzeniem głównym.

Więc przed wykonaniem scalenia, sprawdź kasę, a potem git pulltam. Następnie będziesz mógł scalić nowe zmiany w swoim oddziale.


7
Czy istnieje sposób na uniknięcie przełączania gałęzi, coś w rodzaju wykonania pociągnięcia gałęzi, która ma zostać scalona, ​​gdy znajduje się jeszcze w gałęzi, która ma zostać scalona, ​​a następnie scalenia?
Japheth Ongeri - inkalimeva

Ahh, niezły. Pomyślałem, git fetchże zaktualizuje gałąź master, nawet jeśli obecnie używam innej. Okazuje się, że nie. Dzięki! Jestem prawie pewien, że istnieje opcja, fetchktóra pozwala określić, którą gałąź należy pobrać.
Raik

1
@ Raik Możesz to zrobić git fetch --all, ale to tylko pobiera gałęzie, ale ich nie ciągnie.
Ingo Bürk

6
@ JaphethOngeri-inkalimeva Możesz po prostu zrobić git fetch --all && git merge origin/master. Nie trzeba aktualizować lokalnego, masteraby scalić zdalne zmiany.
Ingo Bürk

@ IngoBürk Miałem 2 oddziały, zaktualizowałem 1 zi git merge master1 z git merge origin/master. Sprawdziłem również masteri git pullprzed aktualizacją 2 oddziałów. mimo że dzielili tę samą zawartość, utworzenie PR między 2 gałęziami pokazało kilka plików różnic. Naprawiłem git pullgałąź docelową w gałęzi funkcji, która pokazała: Already up to date! Merge made by the 'recursive' strategy.spowodowało to zatwierdzenie scalania bez zmian, ale usunąłem nieoczekiwane pliki różnic z PR. jakiś pomysł, dlaczego istnieje różnica między łączeniem „równoważnych” lokalnych i zdalnych gałęzi?
wrapperapps

45

Załóżmy, że masz oddział masterz następującą historią zatwierdzeń:

A -- B -- C -- D

Teraz tworzysz test gałęzi, pracujesz nad nim i wykonujesz 4 zatwierdzenia:


                 E -- F -- G -- H
                /
A -- B -- C -- D

mastergłowa wskazuje na D, a testgłowa wskazuje na H.

Komunikat „Już aktualne” pojawia się, gdy HEAD gałęzi, z którą się łączysz, jest rodzicem łańcucha zatwierdzeń gałęzi, którą chcesz scalić. Tak jest w tym przypadku: Djest rodzicem E.

Nie ma nic do seryjnej od testcelu master, ponieważ nic się nie zmieniło na masterodtąd. To, co chcesz tutaj zrobić, to dosłownie powiedzieć Gitowi, aby miał mastergłowę wskazującą na H, więc gałąź mistrza ma następującą historię zatwierdzeń:

A -- B -- C -- D -- E -- F -- G -- H

To jest zadanie dla polecenia Git reset. Chcesz również, aby katalog roboczy odzwierciedlał tę zmianę, więc wykonasz twardy reset:

git reset --hard H

3
W przeszłości powiedziano mi, że używanie git reset --hardjest dość drastyczne, czy może stracić zobowiązania? Czy istnieje bezpieczniejszy sposób na dokonanie tych zmian, czy też niebezpieczeństwo jest git reset --hardzawyżone?
Graham R. Armstrong,

1
To polecenie jest rozsądne, nie martw się. Powiedziałbym, że jedyną rzeczą, na którą należy zwrócić uwagę przy tej --hardopcji, jest fakt, że faktycznie modyfikuje ona katalog roboczy, w wyniku czego tracisz nieproszone zmiany. Osobiście wykonuję git statusprzed i po każdym ręcznie uruchamianym poleceniu git, aby upewnić się, że moje repo jest czyste lub w oczekiwanym stanie.
Marek Stanley

spowoduje to wyświetlenie komunikatu o stanie „Twoja gałąź i„ pochodzenie / główny ”są rozbieżne”. Jak mogę to rozwiązać?
Eido95

1
Chciałbym dać ci więcej niż jedną opinię. Dzięki!
KMC

Czy jest taka potrzeba --hard? Byłem w tej sytuacji kilka razy i zawsze resetuję bez --hard. Działało dobrze bez ryzyka utraty jakichkolwiek nieprzyjętych zmian.
Kazimierz

16

Co dla mnie działa, powiedzmy, że masz oddział1 i chcesz połączyć go w oddział2.

Otwórz wiersz polecenia git, przejdź do folderu głównego oddziału2 i wpisz:

git checkout branch1
git pull branch1
git checkout branch2
git merge branch1
git push

Jeśli masz konflikty, nie musisz wykonywać git push, ale najpierw rozwiąż konflikty, a następnie push.


6

Scalanie odbywa się zawsze między bieżącym HEAD a jednym lub kilkoma zatwierdzeniami (zwykle nagłówkiem gałęzi lub znacznikiem),
a plik indeksu musi być zgodny z drzewem zatwierdzenia HEAD (tj. Zawartością ostatniego zatwierdzenia) podczas jego uruchamiania.
Innymi słowy, nie git diff --cached HEADnależy zgłaszać żadnych zmian.

Scalone zatwierdzenie jest już zawarte w HEAD. Jest to najprostszy przypadek o nazwie „Już aktualny”.

Powinno to oznaczać, że zatwierdzenia w teście są już połączone w master, ale ponieważ inne zatwierdzenia są wykonywane w master, git diff testnadal dawałyby pewne różnice.


6

Dzieje się tak, ponieważ lokalna kopia oddziału, który chcesz scalić, jest nieaktualna. Mam swój oddział, nazywany MyBranchi chcę go połączyć ProjectMaster.

_>git status
On branch MyBranch-Issue2
Your branch is up-to-date with 'origin/MyBranch-Issue2'.

nothing to commit, working tree clean

_>git merge ProjectMaster
Already up-to-date.

Ale wiem , że są zmiany, które należy połączyć!

Oto, kiedy piszę git merge ProjectMaster, git patrzy na moją lokalną kopię tego oddziału, która może nie być aktualna . Aby zobaczyć, czy tak jest, najpierw mówię Gitowi, aby sprawdził, czy moje oddziały są nieaktualne, i jeśli to możliwe, przyjął wszelkie zmiany, używając fetch. Następnie wskakuję do gałęzi, którą chcę scalić, aby zobaczyć, co się tam dzieje ...

_>git fetch origin

_>git checkout ProjectMaster
Switched to branch ProjectMaster
**Your branch is behind 'origin/ProjectMaster' by 85 commits, and can be fast-forwarded.**
  (use "git pull" to update your local branch)

Ah-ha! Moja lokalna kopia jest nieaktualna przez 85 zatwierdzeń, co wyjaśnia wszystko! Teraz Pullzapisuję zmiany, których mi brakuje, a następnie przeskakuję do MyBranchi ponownie próbuję scalić.

_>git pull
Updating 669f825..5b49912
Fast-forward

_>git checkout MyBranch-Issue2
Switched to branch MyBranch-Issue2
Your branch is up-to-date with 'origin/MyBranch-Issue2'.

_>git merge ProjectMaster
Auto-merging Runbooks/File1.ps1
CONFLICT (content): Merge conflict in Runbooks/Runbooks/File1.ps1

Automatic merge failed; fix conflicts and then commit the result.

A teraz mam inny problem do rozwiązania ...


5

Stało się tak, ponieważ dziwnie GIT myślał, że lokalny oddział różni się od zdalnego. Było to widoczne na wykresie gałęzi: wyświetlało dwie różne gałęzie: piloty / pochodzenie / nazwę gałęzi i nazwę gałęzi.

Rozwiązaniem było po prostu usunięcie lokalnego repozytorium i ponowne sklonowanie go ze zdalnego. W ten sposób GIT zrozumiałby, że piloty / pochodzenie / nazwa_gałęzi> i nazwa_gałęzi są rzeczywiście takie same i mógłbym wydać git merge branch_name.

rm <my_repo>
git clone <my_repo>
cd <my_repo>
git checkout <branch_name>
git pull
git checkout master
git merge <branch_name>

Czy to nie jest dokładnie taka sama odpowiedź jak Acarter?
Andrew C

Wydaje mi się, że Acarter rzeczywiście nie rozumiał sensu - na pilocie nie było żadnych zmian - to wcale nie był problem. Musiałem „git checkout master”, a następnie „git merge <nazwa_gałęzi>”, aby wymusić scalenie szybkiego przewijania do przodu. Na odwrót nic nie zrobiono, ponieważ gałąź wyprzedziła mistrza. Odpowiedź Bombe jest dobrym wyjaśnieniem, ale nigdy nie odpowiedziała na pytanie „jak to rozwiązać”.
MrMas

5

git merge origin/masterzamiast tego git merge masterpracował dla mnie. Aby połączyć master z gałęzią funkcji, możesz użyć:

git checkout feature_branch
git merge origin/master

5

Pamiętaj, aby najpierw pobrać gałąź, którą chcesz scalić, a następnie ją pobrać (aby wersja lokalna pasowała do wersji zdalnej).

Następnie wróć do swojej gałęzi, na której chcesz wykonać scalanie, a scalanie git powinno działać.


1
To było dla mnie - zrobiłem to, gdy byłem mistrzem; dowiedziałem się, że dostałem nowe commity w „oddziale”. Próbowałem połączyć „gałąź” w master - „Już aktualne”. Czy git Checkout „gałąź” - dostał „Twoja gałąź jest z tyłu ... i może być szybko git pull
przewijana

3

przydarzyło mi się i zostałem wysłany na tę stronę, nie jestem pewien, czy mam ten sam scenariusz, ale to ja próbowałem „ponownie połączyć” tę gałąź „testową”.

Więc wcześniej go połączyłem, ale celowo wykluczam pewne konkretne zmiany podczas tego scalania, więc wyraźnie różni się między gałęziami. Próbowałem następnie połączyć ponownie, ponieważ zdaję sobie sprawę / zapomniałem, że powinienem i chciałem dodać konkretną zmianę / plik, który wcześniej wykluczyłem, i miałem nadzieję, że jeśli ponownie dokonam scalenia, pokażą wszystkie zmiany, które wcześniej wykluczyłem , ale się myliłem i zamiast tego pojawia się komunikat „Już aktualny”.

Po przeczytaniu komentarza / odpowiedzi @ Bombe ma rację i myślę, że tak się zachowuje, więc zrobiłem twardą kopię zapasową plików w gałęzi testowej, a następnie sprawdziłem gałąź główną i ręcznie wkleiłem do niej pliki i zatwierdziłem to tak, jakby to były nowe zmiany.

nie jestem pewien, czy jest to właściwy sposób, czy może pomóc innym, którzy mają ten sam problem, ale zapewniło rozwiązanie mojej konkretnej sprawy.


Ta sama sytuacja tutaj. Scenariusz polega na tym, że chcę podzielić gałąź „integracji” z powrotem na wiele gałęzi „funkcji”.
Yadli

2
Zamiast ręcznego pasty, można kasie plików bezpośrednio z jednego oddziału do obecnego oddziału: git checkout srcBranch -- path/to/file. Może również używać globów plików.
Todd,

Dzięki, użyłem twojej metody checkout srcBranch -- *
płatności

2

Jeśli połączenie gałęzi A z gałęzią B zgłasza komunikat „Już aktualne”, odwrotność nie zawsze jest prawdą. Jest to prawdą tylko wtedy, gdy gałąź B jest potomkiem gałęzi A, w przeciwnym razie gałąź B może po prostu mieć zmiany, których nie ma w A.

Przykład:

  1. Tworzysz gałęzie A i B poza wzorcem
  2. Wprowadzasz pewne zmiany w systemie głównym i łączysz je tylko z gałęzią B (nie aktualizując ani nie zapominając o aktualizacji gałęzi A).
  3. Wprowadzasz zmiany w gałęzi A i łączysz A z B.

W tym momencie scalanie A do B zgłasza „Już aktualne”, ale gałęzie są różne, ponieważ gałąź B ma aktualizacje od mastera, a gałąź A nie.


2

W obliczu tego scenariusza za pomocą Git Bash.

Nasze repozytorium ma wiele gałęzi, a każda gałąź ma inny cykl zatwierdzeń, a scalanie odbywa się raz na jakiś czas. Old_Branch został użyty jako element nadrzędny dla New_Branch

Old_Branch został zaktualizowany o kilka zmian, które wymagały połączenia z New_Branch

Używałem poniżej polecenia pull bez gałęzi, aby uzyskać wszystkie źródła ze wszystkich gałęzi.

git pull origin

O dziwo, nie wyciąga to wszystkich zmian z wszystkich gałęzi. Myślałem, że tak, jak wskazano pokazuje prawie wszystkie gałęzie i tagi.

Aby to naprawić, sprawdziłem, że Old_Branch ściągnął najnowszą wersję

git checkout Old_Branch

git pull origin Old_Branch

Teraz sprawdzony New_Branch

git checkout New_Branch

Wyciągnąłem to dla pewności

git pull origin New_Branch

git merge Old_Branch

I altówka dostała konflikty do rozwiązania ze Old_Branch do New_Branch :), czego oczekiwano


0

To samo mi się przydarzyło. Ale scenariusz był nieco inny, miałem gałąź master i wykułem z niej wydanie_1 (powiedzmy). Dokonałem pewnych zmian w gałęzi release_1 i połączyłem ją w pochodzenie. potem zrobiłem ssh i na zdalnym serwerze ponownie wyewidencjonowałem release_1 za pomocą polecenia git checkout -b release_1 - który faktycznie wykonuje nową gałąź release_! od głównego, zamiast sprawdzania już istniejącej gałęzi release_1 od początku. Rozwiązano problem, usuwając przełącznik „-b”


0

Miałem ten sam problem. Miałem zmiany w pilocie, który wciąż wyświetlał komunikat „Już aktualny”. Ponowne klonowanie repozytorium naprawiło problem.


0

Głupie, ale może się zdarzyć. Załóżmy, że nazwa twojej gałęzi jest poprzedzona odniesieniem do problemu (na przykład#91-fix-html-markup ), jeśli wykonasz następujące scalenie:

$ git merge #91-fix-html-markup

nie będzie działać zgodnie z przeznaczeniem, ponieważ wszystko po nim #jest ignorowane, ponieważ #rozpoczyna się wstawianie komentarza.

W tym przypadku można zmienić nazwę pominięciem oddziału #lub użyj apostrofów otoczyć nazwę oddziału: git merge '#91-fix-html-markup'.

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.