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 origin
jest aktualny, to niektóre zatwierdzenia zostały wypchnięte origin
z 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/master
twojej 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 HEAD
usuną 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).
master
wskazać B
na twój przykład.
git reset --hard origin/master
jak 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 reflog
lub 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
rebase
jeś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_branch
jest to, co naprawdę działało
W moim przypadku jest to, co zrobiłem, aby spowodować rozbieżną wiadomość: zrobiłem, git push
ale potem git commit --amend
dodał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 -f
oznacza siłę)
git push -f
aby 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/master
a 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/master
gałęzi, aby master
ponownie zsynchronizowała się z lokalną . Rozwiązaniem w moim przypadku było:
git push origin master -f
Zwróć uwagę na -f
przełącznik (wymuszony). Spowodowało to usunięcie „złych zmian”, które zostały popchnięte origin/master
przez 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~1
zasł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 --soft
zamiast szorstkiego --hard
. Jeśli jest więcej niż 1 zatwierdzenie, HEAD~x
powinna 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 apply
zastosować 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 --rebase
bę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 pull
polecenia. 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 commit
plik rozwiązany)
Jeśli zmodyfikowałeś również niektóre pliki od czasu rozwiązania konfliktu, git status
polecenie 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