Transcript for:
Wprowadzenie do komend Git

Elunia, kręcimy vloga? Elusia? Cześć, tu Roman, witam w kolejnym odcinku mojego vloga. Dzisiaj zaczynamy tematy bardzo poważne i bardzo niebezpieczne, jeśli ktoś nie wie jak się nimi posługiwać. Ale bez strachu w sercu możemy ruszyć w ten odcinek, ponieważ po nim wszystko stanie się dla Was jasne. powiem Wam o operacjach, które podmieniają, nadpisują historię naszego repozytorium, czyli git commit amend, bardzo prosta i bardzo przyjemna komenda, i git rebase, który jest już trochę bardziej poważnym zawodnikiem, ale nadal bardzo, bardzo przyjemny. przyjemnym, jeśli wiadomo co z nim robić, bo wielu deweloperów go nie lubi, nie wiem czemu, ale zobaczycie, że jest całkiem spoczko. Lecimy do kompa. Dobra, nadpisywanie historii w Gitcie zaczniemy sobie od najprzyjemniejszej komendy, która jest przy okazji najprostsza na świecie, więc bardzo ciężko tutaj cokolwiek spieprzyć, o ile trzymamy się kilku podstawowych zasad, ale o nich za chwilę. Najpierw wytłumaczmy sobie czym jest git commit amend. Flagę amend. Moim zdaniem bardzo łatwo jest sobie zapamiętać, kojarząc ją z amerykańską konstytucją, ponieważ bardzo często w filmach albo w mediach słyszymy o amendments, np. second amendment do amerykańskiej konstytucji, czyli druga poprawka. Więc amend to nic innego jak poprawić. Chcemy poprawić jakiś komit. Więc w sytuacji, kiedy tworzymy sobie nasz kod, komitujemy nasze zmiany, nagle wpada do nas taki pomysł, że kurczę, do tego komitu moglibyśmy dodać jeszcze jakąś jedną rzecz, jakąś jedną zmianę. Jak to zrobić? Moglibyśmy użyć na przykład komendy git reset, ale jeszcze jej nie znamy, bo poznamy ją dopiero w następnej lekcji, więc możemy równie dobrze posłużyć się komendą, której nauczymy się w dzisiejszej lekcji, czyli właśnie git commit amend. Działa ona w taki sposób, pamiętajcie o tym, że komity są niemutowalne, że bierze ona wszystkie zmiany z komita, który jest ostatni w naszym drzewie na konkretnym branczu, na którym obecnie się znajdujemy. Następnie łączy te zmiany z tego komita ze zmianami, które dodaliśmy wykonując komendę git commit amend i tworzy nam po prostu nowy komit, zastępując ten komit, który istniał wcześniej. Więc jeśli tutaj mieliśmy na przykład hasza 95a98 i to był nasz stary komit, to po wykonaniu komendy git commit amend ten komit zostanie usunięty, a na jego miejsce wskoczy nowy komit. z jakimś nowym haszem. Dodatkowo jeśli komendę git commit amend wpiszemy dokładnie w taki sposób, to git zawsze poprosi nas o nową nazwę comita, więc możemy też zmieniać nazwy commitów, nie tylko zmieniać pliki wewnątrz tego commitu. Załóżmy, że po prostu daliśmy... złą nazwę dla commitu, wtedy możemy też po prostu wykorzystać git commit amend, nie dodając żadnych zmian, tylko zmieniając nazwę tego, co wpisaliśmy w poprzednim commitie. Więc tak to działa w teorii. Chciałem Wam tylko to pokazać na tym grafie, żebyście pamiętali, że nie ma czegoś takiego jak edytowanie commitów. Nie można zrobić edycji commitu, który już istnieje w naszej historii. Możemy ewentualnie go wywalić, a na jego miejsce wrzucić nowe i tak właśnie działa git commit amend. A teraz zobaczmy jak to działa w praktyce. Przejdźmy sobie do terminala, zobaczmy git status. Mamy tutaj dwa pliki na stagingu, kontakt HTML i indeks HTML. Załóżmy, że chcemy stworzyć z tego commit. Stworzymy sobie add content to homepage. Dobra, stworzyliśmy nasz commit, mamy add content to homepage, ale dociera do nas po chwili, że mieliśmy też przecież content dodany do kontakt HTML, więc nie tylko do homepage. tego komita nie dodając żadnych innych plików na razie po prostu chcemy zmienić nazwy komita żeby nie wprowadzać nikogo tutaj w błąd czego on dotyczy git commit amend a jedna rzecz git log Zobaczmy sobie jaki ma hash 8 4 2 1 BBD teraz robimy git commit amend Otwiera nam się edytor, w którym możemy zmienić tytuł naszego komita, więc możemy napisać add content to homepage and contact page. Zamykamy git log i zobaczcie, że nasz komit ma inny hash, ale został zastąpiony. Więc ten commit, jakbyśmy sprawdzili sobie jego zawartość dokładną, to ten commit miałby tego parenta, który wcześniej był parentem naszego poprzedniego commitu. Więc najprościej na świecie mówiąc następuje tutaj podmianka. A teraz wejdźmy sobie jeszcze do powiedzmy index.html. Tutaj gdzieś mieliśmy jakiś obrazek. Skopiujemy sobie ten obrazek i wkleimy go również do naszego indeksu. Na przykład tutaj pod hello world. I stwierdziliśmy, że to też powinna być część tego komitu, który przed chwilą dodaliśmy. Mamy tutaj Add Content to Homepage and Contact Page. Nie musimy zmieniać nazwy, bo ona jest zgodna z tym, co robimy. git add. I teraz robimy git commit amend po raz kolejny. Nie musimy zmieniać nazwy, tak jak mówiłem, ale ta zmiana, którą przed chwilą dodałem do naszej strony, została zapisana jako część tego commitu. I teraz po raz kolejny, jak zrobimy git log, to zobaczymy, że hash naszego commitu jest inny. niż poprzednio. Więc po raz kolejny podmieniliśmy nasz commit. Ale w trakcie tego, jak dodawaliśmy ten commit, dotarło do nas, że tutaj nie chcemy mieć obrazka 200x200, tylko 300x300, bo tak zaprojektował designer i tutaj powinien być większy obrazek. Znowu musimy edytować nasz commit. Czy po raz kolejny musimy otwierać edytor naszego commitu, żeby zmienić jego nazwę, albo żeby po prostu zaakceptować nazwę, która była? Nie. Istnieje jeszcze jedna specjalna flaga do amend, która... Pozwala nam po prostu dodać te zmiany na szybko i zapomnieć o nich, nic więcej nie edytować. Więc zróbmy sobie git add i wpiszmy teraz git commit amend, a drugą flagą będzie no myślnik edit. I w ten sposób zobaczcie, że automatycznie dodane do stage'a zmiany są zapisane w naszym commit'cie. Mamy znowu inny hash, ale tym razem już nie musieliśmy wchodzić do edytora, do nano, żeby zaakceptować nazwę albo zmienić tę nazwę, jeśli byłaby taka. potrzeba. Więc jeśli chcecie na szybko coś dodać, to można to zrobić właśnie w taki sposób. Ja nawet do tego typu sytuacji mam specjalny alias w moim terminalu, nazywa się gamend i w momencie kiedy wykonuję gamend to wykonuje się właśnie dokładnie ta komenda. Jest po prostu krótszy zapis. Dobra, więc git-commitament mamy ogarnięte. Jeśli chodzi o nadpisywanie historii naszego gita, to była prostsza metoda. Teraz przechodzimy do git-rebase, który również jak go zrozumiemy, to jest całkiem prosty. Nie rozumiem dlaczego bardzo wielu devów, których spotykam, już takich devów z doświadczeniem, czasami boi się tej komendy i preferuje merdża. Ale najpierw wyjaśnię wam właśnie po co nam jest rebase i czym się różni od merdża. Więc wyobraźmy sobie taki scenariusz, że mamy sobie brancha main. do którego jakiś inny developer, jako pierwszy przed nami, dołączył swojego brancha. Po prostu go zmerdżował. Z racji, że nie miał tam żadnych konfliktów, to się zrobiło fast forward, tak jak pokazywałem wam w czwartej lekcji tego kursu. I teraz te komity po prostu są czubkiem naszego brancha main. No i jak pewnie zauważyliście, nasz feature branch w tym momencie jest w tyle. Jeśli zmiany, które... dodał inny developer, dotyczą plików, na których my również pracujemy, to prawdopodobnie w momencie, kiedy będziemy chcieli zmerdżować to do naszego maina, będziemy mieć konflikt. To również nas nie przeraża, po prostu wtedy byśmy spróbowali dołączyć nasz Featured Branch do... naszego maina, tworząc jak już pamiętacie pewnie z poprzedniej lekcji właśnie merge commit, czyli commit, który jest wyjątkowy, bo zawiera dwojga rodziców. Zapamiętajcie sobie ten scenariusz, ponieważ na końcu wrócę do niego i pokażę Wam jak można go rozegrać w trochę inny sposób, inną strategią, natomiast cofnijmy sobie te wszystkie zmiany. Zróbmy tak, że nie zmerge'owaliśmy naszego brancha do maina, ponieważ znajdujemy się w trochę innej sytuacji. Znajdujemy się w sytuacji, kiedy jesteśmy w tyle za mainem, ale te rzeczy, które są na mainie potrzebne nam są na naszym feature branchu. Powiedzmy, że nasz kolega albo nasza koleżanka dodała na swoim branczu rzeczy, które dotyczą tych samych plików, które my zmienialiśmy i po prostu potrzebujemy tych zmian w naszych plikach. Mamy tutaj również kilka strategii. Możemy analogicznie do tego, co przed chwilą powiedziałem, będąc na naszym feature branchu, zmerge'ować maina, czyli git merge main po prostu, będąc na naszym feature branch. W takiej sytuacji również tworzy nam się nowy commit. który jest merge commitem, ale na naszym feature branchu i zawiera rodzica w postaci ostatniego commita z maina i ostatniego commita z naszego feature brancha, zanim stworzyliśmy ten nasz merge commit. Dla wielu deweloperów jednak, i uważam po części, że słusznie, jest to rozwiązanie dość mało higieniczne, bo o ile merge commity na mainie jeszcze są moim zdaniem spoko całkiem, ponieważ pokazują wyraźnie moment, w którym domergeowany został jakiś branch do naszego maina, O tyle merge-comity na naszych feature-branchach wyglądają dość dziwnie. I można to zrobić w trochę bardziej elegancki sposób, tak jakby nigdy żaden merge się tutaj nie wydarzył, jakby te comity od zawsze były na naszym branchu. Problem tylko polega na tym, że ta operacja zmienia nam historię naszych comitów. I to dość poważnie, bo to już nie chodzi o jeden commit, jak w przypadku git commit amend, tylko chodzi tutaj o cały szereg comitów, czasami kilku, czasami kilkunastu. Więc musimy się bardzo dobrze zastanowić, czy na pewno chcemy to robić. I uwaga, tutaj zasada jest taka, a przynajmniej ja się tej zasady zawsze trzymam i polecam się jej trzymać, żeby nie wpaść w kłopoty. Jeśli pracujecie sami na jakimś branczu, to możecie zmieniać jego historię. Jeśli pracuje z wami ktokolwiek inny, jeśli pracujecie nawet w dwie osoby, to radzę nie wykonywać operacji, które zmieniają historię commitów, chyba że to bardzo dobrze między sobą skoordynujecie. Na końcu tego odcinka jeszcze opowiem trochę więcej o tym, co się może wydarzyć w momencie, kiedy namieszacie za bardzo w historii waszych commitów, ale na razie wróćmy do tego, jak działa git rebase. Więc wywalamy sobie tego merge commita i będąc na naszym feature branchu możemy wykonać operację. która właśnie nazywa się Git Rebase. Jak sama nazwa wskazuje, jest to poniekąd przebazowanie naszego całego feature brancha. No i teraz schodząc bardzo nisko poziomowo, bardzo łopatologicznie, po prostu przejdźmy przez całą operację Git Rebase, żeby ją zrozumieć, bo wydaje mi się, że niezrozumienie tego, co się dzieje pod maską, po raz kolejny budzi tutaj... Nieuzasadniony strach. Więc jesteśmy na branczu Feature Branch. Co to znaczy? To znaczy, że nasz head wskazuje na brancza Feature Branch, a nasz brancz Feature Branch wskazuje na commit FA765, czyli ostatni commit tutaj z tego naszego drzewka. I teraz tak, wpisujemy sobie git rebase main. Co się dzieje w tej chwili? W tej chwili... Git robi następującą rzecz. Bierze pierwszy commit z tego naszego brancha, który ma jeszcze rodzica na naszym mainie, ale jest to stary commit z naszego maina. Kopiuje zawartość tego commita. Tworzę sobie tutaj nowy commit, bo pamiętajcie, że komity są nieedytowalne, więc to nie jest tak, że po prostu sobie przepniemy ten commit tutaj i jesteśmy zadowoleni. Rodzic też jest niemutowalny, ponieważ jest to część naszego commitu. Nadajemy mu jakiś nowy hash i mówimy słuchaj nowy commitie, od dzisiaj to jest twój rodzic. Więc pojawił nam się nowy commit, który ma rodzica jako ostatni commit z brancha main, jako czubek naszego brancha main. Ten commit zawiera to, co zawierał ten commit. Teraz stworzymy nowy commit i się pewnie domyślacie, co się wydarzy. On również ma nowego rodzica w postaci tego comita. I ostatni. Cyk. stwórzmy im to jakieś nowe hasze i teraz jako ostatnią rzecz Nasz Feature Branch zostaje przeniesiony w to miejsce i nasz Head razem z naszym Feature Branchem również leci tutaj. Zakończyliśmy rebasowanie, czyli tak naprawdę zmieniliśmy historię naszych komitów. Powstały zupełnie nowe komity, które mają nowego rodzica, ale mają zawartość tych komitów odpowiednio. Nasz Feature Branch, czyli nasz tag do komita, jak już pamiętacie z odcinka o branczach, wskazuje teraz na nowy commit, który jest czubkiem naszego nowego brancha, mimo że jest to ten sam branch on po prostu został zrebase'owany i nasz head podążył za naszym branczem, pytanie co się stanie z tymi commitami tutaj, czy mamy jeszcze do nich dostęp, cóż jeśli byśmy wpisali git checkout i na przykład ten hash, to tak, nasz head może się tu przenieść tylko po co, wtedy będziemy mieli zjawisko, które się nazywa detached head nie chcemy tego tak na dobrą sprawę te komity będą po prostu, jak to się mówi po angielsku, garbage collected, czyli będą usunięte po jakimś czasie, ponieważ nikt już się do nich nie będzie odnosił, są po prostu zbędne w naszym repozytorium. Ta operacja dzieje się automatycznie i nie mamy na nią wpływu. I w ten właśnie sposób dokonało się zrebase'owanie naszego brancha. Co jest jeszcze bardzo istotne, pamiętajcie o tym, jak już mówiłem, że komity dodawane są jeden po drugim, to znaczy, że najpierw idzie ten, później ten, później ten. I za każdym razem, kiedy będziecie rebase'ować... możecie natrafić na nowy konflikt, ponieważ każdy z tych komitów może generować jakiś nowy, inny konflikt. Więc to nie dzieje się wszystko naraz, tak jak w przypadku merge'a, że naprawiamy od razu wszystkie konflikty, tylko najpierw aplikowany jest ten komit, sprawdzamy czy coś z tych komitów konfliktowało z tym komitem, naprawiamy to. Robimy git rebase continue, przechodzimy do następnego, naprawiamy, przechodzimy do następnego, naprawiamy i dopiero kiedy cała ta operacja zostanie ukończona wtedy mamy informację w gicie, że rebasowanie zostało ukończone. Brzmi to bardziej skomplikowane. ale zachowujemy większą higienę naszej historii komitów na naszym indywidualnym feature branchu. Ponadto po takiej operacji, kiedy będziemy chcieli zmerdżować naszego feature brancha, to z racji, że już nie mamy żadnych konfliktów tutaj i załóżmy, że nawet jak dodamy tutaj jeszcze jakieś z 2 komity, które też nie powodują jakichś nowych konfliktów, jeśli będziemy chcieli całego tego brancha zmerdżować, to nic prostszego, po prostu robimy pull requesta, merdżujemy to i będziemy mieli fast forward, ponieważ... Żadne konflikty się nie pojawią, żeby trzeba było je naprawiać. A teraz przejdźmy sobie do terminala i zobaczmy, jak to wygląda w praktyce. Dobra, więc przygotowałem sobie... brancha Change Contact Page, który zawiera trzy komity, zawierające jakieś drobne zmiany tutaj w naszym kontakt HTML. Teraz ten brancz jeszcze nie został zmerge'owany do main'a, więc main ma jeszcze naszą starą postać, którą zostawiliśmy przy okazji naszego Geek Commitment i teraz robimy sobie nowego brancha. Nazwijmy to Contact Page Redesign. Zobaczmy, że w tym momencie nasz Head wskazuje na Contact Page Redesign oraz na Main, czyli oba te brancze wskazują na ten sam commit, czyli Add Content to Homepage and Contact Page, czyli ostatni commit, który zrobiliśmy w kontekście naszego Git Commit Amend. I teraz przechodzimy sobie do naszego WebStorma. Przypominam, że jesteśmy już na nowym branczu i załóżmy, że chcemy tutaj coś porobić. Załóżmy, że chcemy na przykład wywalić message, że to będzie tylko taki formularz, gdzie możemy zostawić kontakt do siebie i... ktoś tam do nas odpisze. Potem nam się przypomina, że jeszcze musimy usunąć tutaj message i na pewno tutaj. Dobra. Moglibyśmy zmienić to za pomocą git commit amend, ale możemy też zrobić coś takiego, że tamto było o HTML-u, a tutaj zrobimy remove message field from... JS validation i tyle. A, zapomniałem to dodać do stage'a, więc nic nie zakomitowałem. Brawo ja, kursogi cię robię. Dobra, każdemu się zdarza. Mamy dwa komity. I załóżmy jeszcze, że designer nam zaprojektował trochę inaczej to wszystko i teraz to będzie zielone, to będzie bordowe, nawet nie wiem jak to wygląda w praktyce, ja tylko zmieniam suwaczki. tak jak nam zrobił designer czyli change colors of contact form dobra mamy trzy komity i teraz w tym momencie kiedy my pracowaliśmy sobie nad tymi zmianami ktoś na branczu main dodał rzeczy z change contact page czy robimy gitmerch change contact page Moglibyśmy to zrobić za pomocą githuba, ale w tym kontekście nam to nic nie robi. Kompletnie. Więc żeby było szybciej robimy to lokalnie tutaj na naszym terminalu. Wyobraźmy sobie, że jest to pull request, który ktoś zaakceptował, w każdym razie my sobie dociągamy wyciągamy tego maila lokalnie i znajdujemy tutaj takie właśnie rzeczy. Możemy to spuszczone, żeby faktycznie było na githubie już teraz, ale to jest trochę inny inna kolejność działań. Nas interesuje tylko to, że teraz na naszym mainie mamy add phone field, change name, change styles, czyli żeby być jeszcze bardziej precyzyjnym. Nasz branch main wskazuje na komit C1932. Teraz wróćmy sobie na nasz. Contact page redesign i zobaczmy tutaj. Zauważcie, że ostatni commit, który mieliśmy z maina, add content to homepage and contact page, już nie ma tutaj w nawiasie, że jest to commit z maina. ponieważ main się przeniósł w inne miejsce. Po tym m.in. wiemy, że nasz branż kontakt, page redesign jest z tyłu. I teraz my potrzebujemy tych zmian, które były domerge'owane przed chwilą na maina, więc musimy to zrobić za pomocą właśnie albo git merge'a, ale my w tym odcinku robimy git rebasa, więc zróbmy sobie teraz git rebase main. Zobaczymy co się wydarzy. Ostatnie tylko przypomnienie, mamy tutaj trzy komity, jak chcecie możecie zapamiętać ich hasze, jeśli macie tak dobre. dobrą pamięć. Ja tylko zapamiętam sobie ostatni. 1.6.b.a.9. Zobaczymy, co się wydarzy. Git rebase main. Dobra. Weszliśmy w trip rebase'owania. Po czym to poznać? Po tym, że mamy tutaj informację. Jesteśmy w trakcie rebase'a. Mamy informację nawet, co teraz powinniśmy robić. Powinniśmy rozwiązać wszystkie konflikty ręcznie, następnie dodać to, a następnie wykorzystać komendę git rebase continue. I tak jak mówiłem, git rebase leci tutaj commit po commit'cie, więc stop. Z tego, co kojarzę, będziemy mieć przynajmniej dwa konflikty do rozwiązania step by step. Zobaczmy, jakie mamy teraz konflikty. Tutaj mamy kontakt zamiast kontakt. Różnią nam się kolory. A wydaje mi się, że jednak zbandlował nam te wszystkie konflikty w jeden konflikt, ponieważ dotyczy to jednego pliku, więc nie będziemy musieli przechodzić przez to kilka razy. mi się, że teraz jak rozwiążemy te konflikty i zrobimy git rebase continue, to po prostu zakończę rebasowanie. To też jest spoko. Jakbyśmy mieli więcej plików, to prawdopodobnie mogłoby być tak, że commit po commit rozwiązujemy te konflikty. Przy okazji możecie zobaczyć jak wygląda rozwiązywanie konfliktów w webstormie, czyli obiekt pożądania większości deweloperów. Wszyscy tego zazdroszczą. Jest to naprawdę bardzo wygodne. Widzę, że message istnieje z jednej i z drugiej strony, czyli jednak będzie tak, że zaraz jeszcze nam walnie drugim commitem, gdzie usuwaliśmy to message. Zobaczymy, czy tak faktycznie będzie. Robimy apply. Rozwiązaliśmy wszystkie konflikty. Możemy sobie wrócić do terminala i zrobić git add. Zobaczcie, że mamy te zmiany tutaj. I teraz git rebase continue. Zapisujemy te zmiany i po raz kolejny mamy konflikty do rozwiązania. Sprawdzamy co tym razem. Tutaj nam się powtarza ten konflikt, tutaj również. I tutaj musimy trochę na tryb manualny przejść, czyli... Wrzucamy tutaj phone, nie mamy już tutaj message, zamieniamy name, dodajemy phone, usuwamy message, ponieważ tutaj walidacja została usunięta i tutaj również usuwamy message. Niestety nie wszystkie konflikty ładnie da się tak automatycznie zawsze naprawić. Dobra, git add. I kolejny commit. Czyli widzicie jednak jest tak, że commit po commit lecimy. Niestety on z racji, że to wszystko dotyczy tego samego pliku, on nas pyta wielokrotnie, ponieważ te zmiany dotyczyły... W paru miejscach tych samych rzeczy te zmiany bardzo mocno na siebie nachodzą i niektóre elementy faktycznie trzeba po kilka razy przejść. Czyli zobaczcie, commit po comicie przeszliśmy. Było to dość siermiężne, bo wszystko dotyczyło jednego pliku. Zazwyczaj to nie jest aż tak skomplikowane i te zmiany, nawet jeśli konfliktują, to w kilku plikach jednocześnie, więc w zależności od poziomu skomplikowania rozwiązywanie konfliktów bywa różne, ale zobaczcie, że mamy tutaj informację, że successfully rebased and updated. Czyli udało nam się zrebase'ować naszego brancha. Zobaczcie, że teraz w Gitlogu, tak jak mieliśmy trzy komity, tak mamy, tylko że teraz na czwartym komicie w Gitlogu, czyli tym, który już nie należy do naszego brancha, mamy maina z powrotem, czyli jakby nasz Contact Page Redesign brancz siedzi z powrotem na mainie. Main jest początkiem jakby tego wszystkiego, co działo się na naszym branczu. I nie mamy tutaj żadnego merchcomita, co jest bardzo dobrą wiadomością, bo jest to po prostu przyjemniejsze dla oka i trochę bardziej higieniczne, więc jeśli komuś zależy na tym, to serdecznie polecam. I zakładam, że może się teraz pojawić jakaś obawa na zasadzie Roman, ale na mainie przecież pracuje wielu deweloperów, a mówili, że nie zmienia się historii, jeśli pracuje wielu deweloperów. Tak, ale mówiłem o naszych branczach. czyli Contact Page Redesign. Na tym branczu pracowaliśmy wyłącznie my i my tylko dociągaliśmy zmiany z maina, które zostały wprowadzone przez innych deweloperów i my w ten sposób nie zmieniamy historii maina. Nasz brancz siedzi na mainie w tym momencie, więc nawet jeśli zmerdżujemy sobie tego brancza, to on nie nadpisze w żaden sposób historii naszego maina. A teraz wyobraźcie sobie scenariusz, w którym my zrebase'owaliśmy nasze zmiany. i są one z powrotem na mainie, a ktoś inny, kto pracował na kontakt Page Redesign, nie zrebase'ował tego, tylko pracował na takich historiach jak miał wcześniej, to w tym momencie mamy już taki rozjazd, że mamy trzy komity, które mają inne hasze, więc to są kompletnie inne komity, ale mają tę samą zawartość i dla Gita to będzie spory mindfuck, żeby to wszystko rozwiązać, więc ta historia nam się mega rozłazi, takich historii po prostu unikamy, takich sytuacji nie robimy, zawsze pamiętajcie, że jeśli... pracujecie sami na branczu, możecie nadpisywać historię, jeśli pracujecie w kilka osób, raczej nie nadpisujcie historii, jeśli pracujecie w dwie osoby, to zróbcie tak, że powiedzcie drugiemu ziomkowi albo ziomkini, słuchaj, ja teraz będę robił rebasa, poczekaj chwilę za swoimi zmianami, zaciągniesz sobie zaraz te rzeczy z nową historią, taką jak będzie u mnie i będziemy pracować na tej samej wersji historii i wtedy jesteście bezpieczniejsi. Jest jeszcze jedna komenda, o której nie powiedziałem i która spina to wszystko, czyli git commit reamend i git rebase, ponieważ na razie wszystko robiliśmy na lokalu, na lokalnym repozytorium, ale jeśli chcemy te zmiany z nadpisaną historią wysłać do naszego githuba, do naszego zdalnego repozytorium, musimy wykorzystać jeszcze jedną komendę. Ja na razie sobie wypchnę po prostu te zmiany, które miałem tutaj. I teraz wykorzystam komendę git commitament, żeby Wam pokazać o co mi chodzi. Żeby nadpisać historię na zdalnym repozytorium. Zobaczcie. Mój branż pojawił się na repozytorium zdalnym. Teraz mamy dwie wersje tego brancha, na zdalnym i na lokalnym. Na lokalnym mogę nadpisać jego historię, wykorzystując na przykład git commit amend i zmieniając nazwę mojego comita, zapisując. I teraz zobaczcie, że mamy tutaj dwie strzałeczki, jedna w dół, jedna w górę. To znaczy, że historie naszych branczy się różnią. Brancz zdalny ma inną historię, brancz lokalny ma inną historię. Co zrobić, żeby to naprawić? Pewnie pomyślicie git push. Otóż nasz git push zostanie zrejectowany, ponieważ wierzchołki naszych branczy nie są ze sobą zgodne. Mamy tam inne komity i github dostaje trochę mindfucka, więc żeby mu powiedzieć słuchaj ta historia z mojego brancza lokalnego jest słuszna, możemy mu to wepchnąć po prostu siłą, czyli używając flagi git push force. I w tym momencie mówimy słuchaj moja wersja jest poprawna. tamtą po prostu się nie przejmuj, nadpisz ją. I dlatego to jest takie niebezpieczne. Bo nadpisujemy nasze single source of truth, nasze jedyne źródło wiarygodnych informacji co do naszego projektu, czyli nasze zdalne repo. Czasami jeśli chcecie zapobiec takiemu bardzo niszczącemu nadpisywaniu, możecie wykorzystać force with lease, poczytajcie sobie też o tym, ale nie zawsze to pomaga, więc generalnie zasada jest taka, że jeśli pracujecie w kilka osób, to raczej unikajcie git push force, bo możecie się wpakować w tarapaty. A jeśli o tarapatach mowa, to w następnym odcinku opowiem Wam, jak cofać się w czasie w gicie, bo prędzej czy później faktycznie wpakujecie się w jakieś kłopoty, a wtedy warto wiedzieć, jak cofnąć te zmiany, do których doszło, przypadkiem lub nie. A tymczasem bardzo Wam dziękuję za obejrzenie tego odcinka i widzimy się już w następnym. Na razie.