W jakiś sposób mój mistrz i mój początek / oddział master rozeszły się.
Właściwie nie chcę, żeby się rozeszli.
Jak mogę zobaczyć te różnice i „scalić” je?
W jakiś sposób mój mistrz i mój początek / oddział master rozeszły się.
Właściwie nie chcę, żeby się rozeszli.
Jak mogę zobaczyć te różnice i „scalić” je?
Odpowiedzi:
Możesz przejrzeć różnice za pomocą:
git log HEAD..origin/master
przed wyciągnięciem go (pobierz + scal) (zobacz także „Jak zdobyć Gita, aby zawsze pobierał z określonej gałęzi?” )
Gdy masz wiadomość typu:
„Twój oddział i„ origin / master ”rozeszły się, # i odpowiednio 1 i 1 inny zatwierdzenie (-a).”
, sprawdź, czy musisz zaktualizowaćorigin . Jeśli originjest aktualny, to niektóre zatwierdzenia zostały wypchnięte originz innego repozytorium, podczas gdy tworzyłeś własne zatwierdzenia lokalnie.
... o ---- o ---- A ---- B origin/master (upstream work)
\
C master (your work)
Opierałeś zatwierdzenie C na zatwierdzeniu A, ponieważ była to najnowsza praca, którą ściągnąłeś wtedy w górę.
Jednak zanim spróbowałeś cofnąć się do źródła, ktoś inny pchnął zatwierdzenie B.
Historia rozwoju rozdzieliła się na osobne ścieżki.
Następnie możesz scalić lub zmienić bazę. Zobacz Pro Git: Rozgałęzianie Git - Rebasing, aby uzyskać szczegółowe informacje.
Łączyć
Użyj polecenia git merge:
$ git merge origin/master
To mówi Gitowi, aby zintegrował zmiany z origin/mastertwojej pracy i utworzył zatwierdzenie scalania.
Wykres historii wygląda teraz tak:
... o ---- o ---- A ---- B origin/master (upstream work)
\ \
C ---- M master (your work)
Nowe scalenie, zatwierdzenie M, ma dwoje rodziców, z których każdy reprezentuje jedną ścieżkę rozwoju, która doprowadziła do zawartości zapisanej w tym zatwierdzeniu.
Zauważ, że historia za M jest teraz nieliniowa.
Rebase
Użyj polecenia git rebase:
$ git rebase origin/master
To mówi Gitowi, aby powtórzył zatwierdzenie C (twoją pracę) tak, jakbyś oparł go na zatwierdzeniu B zamiast A. Użytkownicy
CVS i Subversion rutynowo dokonują zmian swoich lokalnych zmian w stosunku do poprzedniej pracy, gdy aktualizują się przed zatwierdzeniem.
Git po prostu dodaje wyraźną separację między krokami zatwierdzenia i zmiany bazy.
Wykres historii wygląda teraz tak:
... o ---- o ---- A ---- B origin/master (upstream work)
\
C' master (your work)
Commit C 'jest nowym zatwierdzeniem utworzonym przez polecenie git rebase.
Różni się od C na dwa sposoby:
Zauważ, że historia C 'jest nadal liniowa.
Wybraliśmy (na razie), aby pozwolić tylko na historię liniową w cmake.org/cmake.git.
Takie podejście pozwala zachować wcześniej używany przepływ pracy oparty na CVS i może ułatwić przejście.
Próba wypchnięcia C 'do naszego repozytorium zadziała (zakładając, że masz uprawnienia i nikt nie pchnął cię podczas bazowania).
Polecenie git pull zapewnia skrótowy sposób pobierania z miejsca początkowego i bazowania na nim pracy lokalnej:
$ git pull --rebase
Łączy to powyższe kroki pobierania i zmiany bazy w jedno polecenie.
git reset --hard HEADusuną tylko wszelkie niezatwierdzone modyfikacje lokalne i nie zrobią nic, aby pogodzić różnice między zatwierdzeniami lokalnymi i zdalnymi . Tylko scalenie lub rebase zgromadzi dwa zestawy commits (lokalny i zdalny).
masterwskazać Bna twój przykład.
git reset --hard origin/masterjak wspomniano w odpowiedzi poniżej: stackoverflow.com/a/8476004/6309
Miałem to i jestem zdumiony, co go spowodowało, nawet po przeczytaniu powyższych odpowiedzi. Moje rozwiązanie miało zrobić
git reset --hard origin/master
Potem to po prostu resetuje moją (lokalną) kopię master (która, jak zakładam, jest spieprzona) do właściwego punktu, co reprezentuje (zdalne) origin / master.
OSTRZEŻENIE : Utracisz wszystkie zmiany, które nie zostały jeszcze wypchnięte
origin/master.
git refloglub zobaczyć gitk --all. Ale oczywiście twardy reset to coś innego niż rebase.
git pull --rebase origin/master
to pojedyncze polecenie, które może ci pomóc przez większość czasu.
Edycja: Pobiera zatwierdzenia z źródła / wzorca i stosuje zmiany do nowo pobranej historii oddziału.
Znalazłem się w tej sytuacji, kiedy próbowałem zmienić bazę gałęzi śledzącej gałąź zdalną i próbowałem zmienić jej podstawę na master. W tym scenariuszu, jeśli spróbujesz dokonać zmiany bazy, najprawdopodobniej zauważysz, że twoja gałąź jest rozbieżna i może stworzyć bałagan, który nie jest dla git nubees!
Powiedzmy, że jesteś w gałęzi my_remote_tracking_branch, która została rozgałęziona od master
$ git status# Na gałęzi my_remote_tracking_branch
nic do zatwierdzenia (czysty katalog roboczy)
A teraz próbujesz zmienić bazę na master jako:
git rebase master
ZATRZYMAJ SIĘ TERAZ i zaoszczędź sobie kłopotów! Zamiast tego użyj scalania jako:
Git Merge Master
Tak, otrzymasz dodatkowe zobowiązania w swoim oddziale. Ale jeśli nie masz ochoty na „nierozdzielanie” gałęzi, będzie to znacznie płynniejszy przepływ pracy niż ponowne bazowanie. Zobacz ten blog, aby uzyskać bardziej szczegółowe wyjaśnienia.
Z drugiej strony, jeśli twoja gałąź jest tylko gałęzią lokalną (tzn. Nie została jeszcze przekazana do żadnego zdalnego), zdecydowanie powinieneś zrobić rebase (i twoja gałąź nie będzie się rozbierać w tym przypadku).
Teraz, jeśli to czytasz, bo już są w „rozeszły” scenariusz z powodu takiego rebase, można wrócić do ostatniego zatwierdzenia od pochodzenia (czyli w stanie un-odbiegał) za pomocą:
git reset --hard origin / my_remote_tracking_branch
rebasejeśli gałąź, którą publikujesz, nie została opublikowana (i jest używana przez inne osoby). W przeciwnym razie użyj merge. Jeśli dokonujesz zmiany bazy już opublikowanych (i używanych) gałęzi, musisz koordynować spisek, aby przepisać historię dla każdego programisty, który używał twojej gałęzi.
git rebase master...
git reset --hard origin/my_remote_tracking_branchjest to, co naprawdę działało
W moim przypadku jest to, co zrobiłem, aby spowodować rozbieżną wiadomość: zrobiłem, git pushale potem git commit --amenddodałem coś do wiadomości zatwierdzenia. Potem też zrobiłem kolejne zatwierdzenie.
W moim przypadku oznaczało to po prostu, że pochodzenie / master było nieaktualne. Ponieważ wiedziałem, że nikt inny nie dotyka źródła / mistrza, poprawka była trywialna: git push -f (gdzie -foznacza siłę)
git push -faby zastąpić zmiany poprzednio zatwierdzone i przekazane do źródła. Jestem też pewien, że nikt inny nie dotknął repozytorium.
W moim przypadku wprowadziłem zmiany, origin/mastera potem zdałem sobie sprawę, że nie powinienem tego zrobić :-( Było to skomplikowane przez fakt, że zmiany lokalne były w poddrzewie. Wróciłem do ostatniego dobrego zatwierdzenia przed „złym” lokalnym zmiany (przy użyciu SourceTree), a następnie dostałem komunikat o rozbieżności.
Po naprawieniu mojego bałaganu lokalnie (tutaj szczegóły nie są ważne) chciałem „cofnąć się w czasie” do zdalnej origin/mastergałęzi, aby masterponownie zsynchronizowała się z lokalną . Rozwiązaniem w moim przypadku było:
git push origin master -f
Zwróć uwagę na -fprzełącznik (wymuszony). Spowodowało to usunięcie „złych zmian”, które zostały popchnięte origin/masterprzez pomyłkę, a teraz oddziały lokalne i zdalne są zsynchronizowane.
Pamiętaj, że jest to potencjalnie destrukcyjna operacja, więc wykonuj ją tylko wtedy, gdy masz 100% pewności, że „cofnięcie” zdalnego urządzenia nadrzędnego jest w porządku.
You are not allowed to force push code to a protected branch on this project.. Próbuję naciskać na mój widelec.
Wiem, że jest tu wiele odpowiedzi, ale myślę, że git reset --soft HEAD~1zasługuje na uwagę, ponieważ pozwala zachować zmiany w ostatnim zatwierdzeniu lokalnym (nie wypchniętym) podczas rozwiązywania rozbieżnego stanu. Myślę, że jest to bardziej uniwersalne rozwiązanie niż pull rebase, ponieważ lokalne zatwierdzenie może zostać przejrzane, a nawet przeniesione do innego oddziału.
Klawisz używa --softzamiast szorstkiego --hard. Jeśli jest więcej niż 1 zatwierdzenie, HEAD~xpowinna działać odmiana . Oto więc wszystkie kroki, które rozwiązały moją sytuację (miałem 1 zatwierdzenie lokalne i 8 zatwierdzeń w trybie zdalnym):
1) git reset --soft HEAD~1 cofnąć zatwierdzenie lokalne. Do kolejnych kroków użyłem interfejsu w SourceTree, ale myślę, że następujące polecenia powinny również działać:
2) git stash ukryć zmiany od 1). Teraz wszystkie zmiany są bezpieczne i nie ma już rozbieżności.
3) git pull aby uzyskać zdalne zmiany.
4) git stash pop lub git stash applyzastosować ostatnie ukryte zmiany, a następnie, w razie potrzeby, nowe zatwierdzenie. Ten krok jest opcjonalny, wraz z 2) , gdy chcesz usunąć zmiany w lokalnym zatwierdzeniu. Ponadto, jeśli chcesz zatwierdzić do innej gałęzi, ten krok należy wykonać po przełączeniu do żądanej gałęzi.
pull --rebasebędą się automatycznie chować. stackoverflow.com/a/30209750/6309
Aby wyświetlić różnice:
git difftool --dir-diff master origin/master
Spowoduje to wyświetlenie zmian lub różnic między dwiema gałęziami. W araxis (My favourite) wyświetla go w stylu porównywania folderów. Pokazuje każdy ze zmienionych plików. Następnie mogę kliknąć plik, aby wyświetlić szczegóły zmian w pliku.
W moim przypadku było to spowodowane brakiem rozwiązania konfliktu.
Problem został spowodowany uruchomieniem git pullpolecenia. Zmiany w źródle doprowadziły do konfliktów z moim lokalnym repozytorium, które rozwiązałem. Jednak ich nie popełniłem. Rozwiązaniem w tym momencie jest zatwierdzenie zmian ( git commitplik rozwiązany)
Jeśli zmodyfikowałeś również niektóre pliki od czasu rozwiązania konfliktu, git statuspolecenie wyświetli lokalne modyfikacje jako lokalne niestopniowe modyfikacje i scali rozwiązanie jako lokalne modyfikacje etapowe. Można to właściwie rozwiązać, najpierw zatwierdzając zmiany ze scalenia git commit, a następnie dodając i zatwierdzając zmiany niestacjonarne jak zwykle (np. Przez git commit -a).
Miałem tę samą wiadomość, gdy próbowałem edytować ostatnią wiadomość zatwierdzenia, już wypchniętego zatwierdzenia, używając: git commit --amend -m "New message"
Kiedy wypchnąłem zmiany przy użyciu, git push --force-with-lease repo_name branch_name
nie było żadnych problemów.
Napotkałem ten problem, gdy utworzyłem gałąź na podstawie gałęzi A przez
git checkout -b a
a następnie ustawiam strumień rozgałęzienia A na początek B przez
git branch -u origin/B
Następnie otrzymałem powyższy komunikat o błędzie.
Jednym ze sposobów rozwiązania tego problemu było dla mnie:
git checkout -b b origin/B