Jak powrócić do wersji projektu nie usuwając po drodze commitów? Android Studio

0

Hej,
Jestem bardzo początkującym jeśli chodzi o programowanie. Poznałem podstawy Android Studio oraz Javy i dłubie sobie przy swoim projekcie. Poczytałem na temat Gita i zaimplementowałem go do mojego Android Studio. Poćwiczyłem Git na jednym pliku lecz przy większej ilości jak w przypadku Android Studio już się pogubiłem. Okazało się, git reset usuwa mi commity aż do wersji do której powróciłem, sam git checkout wpisany w konsole powoduje error: pathspec 'f332813' did not match any file(s) known to git. zamiast wpisywać w konsolę, w dolnym pasku odnalazłem "Version control" Tam widać wszystkie commity. Klikając prawym przyciskiem myszy można uruchomić checkout revision oraz reset to current branch. Obydwie opcje resetują commity nowsze aż do wybranego commitu. Czy jest możliwość aby wczytać commit bez usuwania nowszych? Wszystko odbywa się na lokalnym repozytorium.
Z góry dziekuję , pozdrawiam

1

A jezeli chodzi o checkout to musisz podac commit/hash/ do ktorego chcesz przejsc. Nie do konca zrozumialem czy to robisz?

1

Jeżeli nie masz zewnętrznego repozytorium, to powinieneś stworzyć osobną gałąź i na niej możesz się cofnąć, gdzie chcesz. W przypadku gdybyś chciał wrócić do kodu, który miałeś, to przełączasz gałąź do tej wcześniejszej.

Co do podrzuconego GitKrakena, to ja bym sobie odpuścił. Android Studio ma bardzo dobrego graficznego klienta gita i jeśli już z jakiegoś korzystasz, to korzystałbym właśnie z tego.

1

Czemu robisz 'git reset'? To operacja modyfikująca, której powinieneś używać w ostateczności (bardzo łatwo stracić zmiany na gałęzi; czasem da się to odzyskać, ale nie jest to proste).

Do przełączenia się na konkretną wersję służy git checkout, np. git checkout 23342332 (pierwsze kilka znaków hasha) albo git checkout mój_branch.

Błąd 'pathspec 'f332813' did not match any file(s) known to git' oznacza, że takiego commita nie ma w twoim repo (np. pomyliłeś się przy kopiowaniu, albo go wcześniej skasowałeś poleceniem git reset).

Last but not least, nie spotkałem się jeszcze z dobrze działającym pluginem do gita. Ani ten w Intellij, ani w eclipse nie jest bezpieczny; wielokrotnie naprawiałem bałagan, który ktoś sobie zrobił używając ich. Ja korzystam tylko z linii poleceń.

0

Hej Jaime,
Próbuję zrobić testy, które pomogą mi zrozumieć gita. Wychodzi mi z tego ze komenda git checkout <nazwa commita="commita"> kasuje nowsze commity (nie widze ich w git log- tylko starsze oraz ten do którego odniosłem się w git checkout). Widzę też, że git reset również kasuje commity i przechodzi do tego wybranego, nie widzę róznicy pomiedzy tymi dwoma komendami. Co dziwne opcja git checkout pozostawia informacje o skasowanych aktywnościach. Dla przykładu - dodaję po jednej aktywności i commituje. i tak np. 4 razy. Git log pokazuje 4 commity , cofam się do pierwszego commitu (inne się kasują) ale gdybym z poziomu tego commitu chcial dodać kolejną aktywność to nie mogę dać nazwy aktywności taką jak w tych skasowanych commitach. Spróbowałem dodawać do nowych commitów gałęzie (branch) i po zastosowaniu git reset --hard w git logu znikają, natomiast git branch wskazuje stworzone drzewa mimo ze commity zostały skasowane w logu.

Podsumowując - mój problem rozwiązuje tworzenie gałęzi z kazdym commitem tak, żebym mogl powrócić do wczesniejszej wersji nie kasując innych. Wydaje mi się, że cieżko będzie wymyślać kolejne nazwy gałęzi do kazdego commitu. Natomiast powrót do ostatniego commitu podczas gdy pracując na nim coś popsułem wystarczy mi git checkout lub git reset. Czy moje przemyślenia mają zastosowanie w realu i tak postępują developerzy, którzy pracują lokalnie?
Dzieki za pomoc

2

Strasznie mieszasz wszystko ze wszystkim... Ale po kolei: git log wyświetla wszystko do bieżącej wersji, nie używałbym go do oglądania drzewa. Do oglądania drzewa służy:
gitk --all &
(ctrl-f5 przeładowuje drzewko; możesz w dowolnym momencie podejrzeć, co się na nim dzieje)

git checkout to taki suwak, którym możesz przemieszczać się po drzewie, w tym i do poprzednich commitów albo do innych gałęzi. Jak chcesz się na chwilę cofnąć w historii, żeby np. wypróbować starszą wersję, używasz git checkout (a potem wrócić do HEAD, czyli ostatniej wersji na gałęzi). git reset ucina gałąź na podanym commicie, modyfikując drzewo. Jak chcesz wywalić na zawsze wszystko, co zrobiłeś na gałęzi, git reset do tego się nadaje. git log po resecie i checkoucie wyświetli to samo, ale to nie znaczy, że robią to samo.

git branch wyświetla gałęzie, które są tak naprawdę tagami. Gałąź istnieje nawet wtedy, gdy wywaliłeś wszystkie commity na niej, więc nie dziwne, że się wyświetla po git branch.

Podsumowując:
git checkout -- przełączanie się na starsze wersje (a do oglądania starszych wersji wystarczy gitk --all &, historia w intellij, etc.)
git reset -- kasowanie commitów

W praktyce robi się tak, że robi się nowy branch (git checkout -b abc_mój_branch), dodaje się nowe commity, a potem merge'uje się to do mastera (git checkout master; git pull origin master; git merge abc_mój_branch) (git pull jeśli commitujesz do wspólnego repo) Dobrze też trzymać porządek, np. za pomocą rebase'a interactive, ale tego nauczysz się później)

1

@haredzak to co gadasz to bzdury, bo nie poświęciłeś 5 minut na naukę narzędzi tylko bezmyślnie klepiesz komendy i nie rozumiesz ich sensu.

  1. Z gita nic nie znika ani się nie usuwa, chyba że zrobisz jakieś push force.
  2. Ale do tego trzeba go sensownie używać, tzn robić 2 poziomowe commity i mieć jakiś remote, a nie robic wszyskiego tylko lokalnie.
  3. Jeśli zrobisz reset hard to wycofa ci zmiany do podanego commita, ale reset soft już nie. Reset soft sprawia że aktualny head jest na podanym commicie, a wszystkie pliki zmienione w późniejszych commitach (które wycofałeś) są jako jeszcze nie commitowane zmiany.
  4. Normalni developerzy, którzy rozumieją co robią, pracują np. tak:
  • robisz nowy branch od mastera pod jakiś development
  • pracujesz na tym branchu, pushując do remote działające fragmenty
  • jak feature jest skończony to robisz rebase/merge brancha z masterem, żeby wciągnąć zmiany które reszta zespołu mogła wprowadzić w miedzyczasie
  • robisz pull request tego brancha do mastera

Nadal nie rozumiem po co ci generalnie takie cuda z resetowaniem historii do podanego miejsca. To jest coś czego się używa bardzo rzadko, głównie jak jest jakiś nieoczekiwany fuckup i trzeba coś wycofać. Napisz może co chciałeś osiągnąć? Bo mam wrażenie że to problem XY, pytasz o jedno, a realnie chcesz osiągnąć coś zupełnie innego i po prostu twoje podejście jest złe.

1
Jaime napisał(a):

Podsumowując:
git checkout -- przełączanie się na starsze wersje (a do oglądania starszych wersji wystarczy gitk --all &, historia w intellij, etc.)
git reset -- kasowanie commitów

Moment moment, bo to zależy. Zarówno checkout jak i reset to są różne operacje pod jedną nazwą w zależności od kontekstu.

Jeśli przy git checkout podamy nazwę pliku, to oznacza to wyzerowanie tego pliku do zacommitowanego stanu (czyli wykasowanie lokalnych zmian). Oczywiście można to interpretować jako „przełączenie pliku do ostatnio zacommitowanego stanu”.

git checkout -b blah tworzy na aktualnym commicie branczę blah i przestawia na nią. Trudno to nazwać przełączaniem się na starszą (czy jakąkolwiek) wersję, bo z working directory nic się w tym momencie nie dzieje.

No i jest też np. git checkout --detach które obrywa głowę.

git reset natomiast to zupełnie różne czynności w zależności czy to jest git reset --hard, --soft czy --mixed.
Samo git reset bez niczego (czyli “mixed”) zeruje indeks, czyli anuluje efekt wykonanego git add (ale przed git commit), jednak nie powoduje utraty żadnych danych (poza informacją co było a co nie było już „addnięte”).
Ale nawet git reset --hard niekoniecznie kasuje commity, tylko przestawia jakby „pointer” branczy na podany commit. Usunięte commity mogą sobie dalej istnieć na innej branczy na przykład.
Póki cokolwiek na nie wskazuje albo ma w swojej historii, to nie przepadną.

1 użytkowników online, w tym zalogowanych: 0, gości: 1