Podstawowy problem
Właśnie usunąłem CAŁY kod z pliku w moim projekcie i zatwierdziłem zmianę w moim lokalnym gicie (celowo). Zrobiłem
git pull upstream master
aby pobrać i scalić z upstream (więc teoretycznie ten usunięty kod powinien wrócić).
Git mówi mi, że wszystko jest aktualne.
Wszystko zdecydowanie NIE jest aktualne - cały ten usunięty kod jest nadal usuwany.
Inne istotne informacje
Mam tylko jedną gałąź zwaną „master”.
Niedawno skonfigurowałem „master”, aby śledzić nadawanie w następujący sposób:
Branch master skonfigurowany do śledzenia zdalnego branch mastera z upstream.
Polecenie git branch -vv
daje:
* master 7cfcb29 [upstream/master: ahead 9] deletion test
Dlaczego dlaczego tak się dzieje? Jestem bliski wysłania e-mailem do mojego kierownika projektu wszelkich zmian, które wprowadzę w naszym kodzie.
Aktualizacja
Myślałem, że to oczywiste, ale taki jest mój cel:
Pobierz najnowszy kod w moim systemie.
Przepraszam za moją złość, ale dlaczego tak proste zadanie musi być takie trudne?
Odpowiedzi:
Myślę, że Twoim podstawowym problemem jest to, że źle interpretujesz i / lub nie rozumiesz, co robi git i dlaczego to robi.
Kiedy klonujesz inne repozytorium, git tworzy kopię tego, co jest „tam”. Bierze ona także „ich” oddział etykiety, takie jak
master
, i tworzy kopię tej etykiecie którego „imię i nazwisko” w swoim drzewie git jest (zazwyczaj)remotes/origin/master
(ale w twoim przypadkuremotes/upstream/master
). W większości przypadków możesz również pominąćremotes/
część, więc możesz odnieść się do tej oryginalnej kopii jakoupstream/master
.Jeśli teraz dokonasz i zatwierdzisz jakieś zmiany w jakimś pliku (plikach), jesteś jedyną osobą z tymi zmianami. W międzyczasie inne osoby mogą używać oryginalnego repozytorium (z którego utworzyłeś swój klon), aby tworzyć inne klony i zmieniać te klony. Oczywiście tylko oni mają swoje zmiany. Ostatecznie jednak ktoś może mieć zmiany, które odsyła do pierwotnego właściciela (przez „wypychanie”, poprawki lub cokolwiek innego).
git pull
Komenda jest przeważnie tylko skrótemgit fetch
następujegit merge
. Jest to ważne, ponieważ oznacza, że musisz zrozumieć, co faktycznie robią te dwie operacje.git fetch
Komenda mówi wrócić do gdziekolwiek sklonowany z (lub inaczej skonfigurować jako miejsce do pobrania z) i znaleźć „nowe rzeczy ktoś jeszcze dodane lub zmienione lub usunięte”. Te zmiany są kopiowane i stosowane do kopii tego, co otrzymałeś wcześniej . Są one nie stosuje się do swojej pracy, tylko do nich.git merge
Polecenie jest bardziej skomplikowane i gdzie idziesz krzywo. To, co robi, nieco uproszczone, to porównanie „tego, co zmieniłeś w swojej kopii”, z „zmianami, które pobrałeś od kogoś innego, a tym samym dodano do Twojej kopii-cudzej-pracy”. Jeśli twoje zmiany i ich zmiany nie wydają się ze sobą kolidować,merge
operacja łączy je razem i daje ci "zobowiązanie scalające", które wiąże twój rozwój i ich rozwój razem (chociaż istnieje bardzo powszechny "łatwy" przypadek, w którym nie masz zmienia się i pojawia się „szybkie przewijanie do przodu”).Sytuacja, z którą się teraz spotykasz, to taka, w której dokonałeś zmian i zobowiązałeś się do ich wykonania - w rzeczywistości dziewięć razy, stąd „naprzód 9” - i nie dokonali żadnych zmian. Więc
fetch
posłusznie nic nie pobiera, a potemmerge
bierze ich brak zmian i również nic nie robi.To, czego chcesz, to przyjrzeć się, a może nawet „zresetować”, „ich” wersję kodu.
Jeśli chcesz tylko na to spojrzeć, możesz po prostu sprawdzić tę wersję:
To mówi gitowi, że chcesz przenieść bieżący katalog do gałęzi, której pełna nazwa to faktycznie
remotes/upstream/master
. Zobaczysz ich kod od czasu ostatniego uruchomieniagit fetch
i uzyskania najnowszego kodu.Jeśli chcesz zrezygnować ze wszystkich własnych zmian, to co musisz zrobić, to zmienić pomysł gita na to, którą wersję
master
powinna nazwać Twoja etykieta . Obecnie nazywa twoje ostatnie zatwierdzenie. Jeśli wrócisz do tej gałęzi:to
git reset
polecenie pozwoli ci „przenieść etykietę”, tak jak było. Jedynym pozostałym problemem (zakładając, że naprawdę jesteś gotowy porzucić wszystko, co zrobiłeś) jest znalezienie miejsca, w którym powinna wskazywać etykieta.git log
pozwoli ci znaleźć nazwy numeryczne - takie jak7cfcb29
- które są trwałe (nigdy się nie zmieniają), i istnieje absurdalna liczba innych sposobów ich nazwania, ale w tym przypadku potrzebujesz tylko nazwyupstream/master
.Aby przenieść etykietę, wycierając swoje własne zmiany (dowolny, które zostały popełnione w rzeczywistości odzyskania przez jakiś czas, ale jest to o wiele trudniejsze po to więc być bardzo pewny):
--hard
Opowiada git wymazać tego, co robiłeś, przesunąć bieżącą etykietę gałęzi, a następnie sprawdzić dany popełnić.To nie jest zbyt częste, aby naprawdę chcieć
git reset --hard
i zniszczyć mnóstwo pracy. Bezpieczniejszą metodą (co znacznie ułatwia odzyskanie tej pracy, jeśli zdecydujesz, że część z nich była jednak warta zachodu) jest zmiana nazwy istniejącej gałęzi:a następnie utwórz nową lokalną gałąź o nazwie
master
„ścieżki” (nie podoba mi się ten termin, ponieważ wydaje mi się, że dezorientuje ludzi, ale to jest termin git :-)) wzorzec pochodzenia (lub nadrzędnego):z którym możesz się potem zabrać:
To, co robią ostatnie trzy polecenia (są skróty, które sprawiają, że są to tylko dwa polecenia), to zmiana nazwy wklejonej na istniejącej etykiecie, a następnie utworzenie nowej etykiety, a następnie przełączenie się na nią:
zanim cokolwiek zrobisz:
po
git branch -m
:po
git branch -t master upstream/master
:Oto
C0
najnowsze zatwierdzenie (pełne drzewo źródeł), które otrzymałeś, kiedy po raz pierwszy wykonałeś swojegit clone
. Twoje zatwierdzenia od C1 do C9.Zwróć uwagę, że gdybyś to zrobił,
git checkout bunchofhacks
agit reset --hard HEAD^^
to zmieniłoby ostatnie zdjęcie na:Powodem jest to, że
HEAD^^
nazywa wersję drugą w górę od nagłówka bieżącej gałęzi (która byłaby tuż przed resetowaniembunchofhacks
), areset --hard
następnie przenosi etykietę. Commity C8 i C9 są teraz w większości niewidoczne (możesz użyć takich rzeczy jak reflog igit fsck
je znaleźć, ale nie jest to już trywialne). Twoje etykiety mogą się poruszać, jak chcesz.fetch
Komenda dba o tych, które zaczynająremotes/
. Konwencjonalne jest dopasowanie „twoje” do „ich” (więc jeśli oni mająremotes/origin/mauve
, nazwałbyśmauve
też swoje ), ale możesz wpisać „ich”, kiedy chcesz nazwać / zobaczyć zmiany, które otrzymałeś „od nich”. (Pamiętaj, że „jedno zatwierdzenie” to całe drzewo źródłowe. Możesz wybrać jeden konkretny plik z jednego zatwierdzenia,git show
na przykładźródło
git merge
jako polecenie wiersza poleceń (co robię sam, to rozsądna metoda). Zwróć jednak uwagę, żegit pull
zaczyna się to od pierwszego uruchomieniagit fetch
, a następnie uruchomieniagit merge
(lubgit rebase
jeśli zamiast tego powiesz mu, aby to zrobił). Jest to krok pobierania, który faktycznie przenosi nowe zatwierdzenia do scalenia (lub tylko do zmiany bazy).git status
, którego mogę użyć, aby sprawdzić, czy repozytorium nadrzędne wyprzedza moje obecne repozytorium? Komunikat, który otrzymujęgit status
, mówiący, że „Twoja gałąź jest aktualna pod względem„ pochodzenia / wzorca ””, myli mnie, myśląc, że mam najnowsze zmiany, podczas gdy nie mam. Czasami dostaję komunikat, który mówi coś w rodzaju „origin / master to 5 commits before your branch” (parafrazując). Ale to nie jest spójne.git status
wyjaśnia, dlaczego mówi "Twoja gałąź jest aktualna", gdy natychmiastgit fetch
potem ściąga ponad sto obiektów i rozwiązuje prawie sto delt, wymienia kilka nowych gałęzi i kilka nowych tagów i zmienia główny (zdalny tracking), zatwierdzenie nagłówka gałęzi - a potem kolejny status gita wesoło i nieszczerze, wciąż mówi „Twoja gałąź jest aktualna”. Najwyraźniej wiele spadło z pochodzenia, ale branża była „na bieżąco z pochodzeniem” zarówno przed, jak i po?git pull
uruchamia się wtedy jakogit fetch
pierwszagit merge
(lub inne wybrane polecenie).git fetch
Krok aktualizuje swojej pamięci git dotyczącą ich stanu git'S, wywołując ich Git i uzyskanie od nich czegoś nowego. Twójgit status
tylko sprawdza pamięci git za ich Git.Miałem ten sam problem co Ty.
Zrobiłem to
git status
git fetch
git pull
, ale moja gałąź wciąż była w tyle. Miałem foldery i pliki przesłane do zdalnego komputera i widziałem pliki w Internecie, ale w moim lokalnym ich brakowało.Na koniec te polecenia zaktualizowały wszystkie pliki i foldery w moim lokalnym:
lub jeśli chcesz oddział
źródło
Wszelkie zatwierdzone zmiany, takie jak usunięcie wszystkich plików projektu, będą nadal obowiązywać po ściągnięciu. Wszystko, co robi pull, to scalenie najnowszych zmian z innego miejsca do własnej gałęzi, a jeśli twoja gałąź usunęła wszystko, to w najlepszym przypadku wystąpią konflikty scalania, gdy zmiany zewnętrzne wpłyną na pliki, które usunąłeś. Krótko mówiąc, tak, wszystko jest aktualne.
Jeśli opiszesz, jaki wynik chciałbyś, aby zamiast „wszystkie pliki zostały usunięte”, może ktoś zasugeruje odpowiednie postępowanie.
Aktualizacja:
Wydaje się, że nie rozumiesz, że masz już najnowszy kod, który należy do Ciebie. Jeśli naprawdę chcesz zobaczyć najnowszą pracę innej osoby znajdującą się w gałęzi głównej, po prostu zrób:
Należy pamiętać, że nie pozostawi to możliwości natychmiastowego (ponownego) rozpoczęcia własnej pracy. Jeśli chcesz wiedzieć, jak cofnąć coś, co zrobiłeś lub w inny sposób cofnąć zmiany wprowadzone przez Ciebie lub kogoś innego, podaj szczegóły. Zastanów się również nad tym, do czego służy kontrola wersji, ponieważ wydaje się, że nie rozumiesz jej podstawowego celu.
źródło
upstream/master
. Zaktualizowałem moją odpowiedź.Jak mówią inni plakaty, pull scala zmiany z górnego źródła do repozytorium. Jeśli chcesz zastąpić to, co jest w twoim repozytorium, tym, co jest w źródle, masz kilka opcji. Bez mankietu, pójdę z
źródło
Najlepsza odpowiedź jest znacznie lepsza pod względem zakresu i szczegółowości podanych informacji, ale wydaje się, że gdybyś chciał rozwiązać swój problem niemal natychmiast i nie przeszkadzało ci sięganie po niektóre z podstawowych zasad kontroli wersji, możesz ...
Przełącz na master
Usuń niechcianą gałąź. (Uwaga: musi mieć opcję -D, zamiast zwykłej flagi -d, ponieważ twoja gałąź ma wiele zatwierdzeń przed masterem.)
Utwórz nowy oddział
źródło
Chociaż żadna z tych odpowiedzi nie zadziałała dla mnie, udało mi się rozwiązać problem za pomocą następującego polecenia.
git fetch origin
To dla mnie sztuczka.
źródło
Przypominamy, jeśli masz pliki lokalnie, które nie są jeszcze w github i swój
git status
mówiMoże się to zdarzyć, jeśli pliki są w formacie
.gitignore
Spróbuj biegać
i sprawdzanie, czy te pliki się tam pojawiają. To by wyjaśniało, dlaczego git nie chce ich przenosić na pilota.
źródło