Git

Iš Žinynas.
Jump to navigation Jump to search

Kas tos versijų kontrolės sistemos ir Git[keisti]

Kiekvienas projektas turi savo kūrimo etapus ir versijas. Net jei tos versijos nenumeruojamos akivaizdžiai, vis tiek yra žinoma, kad tą ir tą mėnesį pristatyta viena funkcija, po to kita, tada reikėjo kažkiek pataisymų ir t.t. Ir visa tai realiai yra atskiri kodo "gabalai", kurie yra diegiami į gyvą versiją. Ir tada su laiku kyla tokių situacijų ir klausimų: Prie projekto dirba keli žmonės - kaip organizuoti darbą, kad jie vienas kitam netrukdytų ir neredaguotų tų pačių failų? Prieš mėnesį kode buvo padarytas pakeitimas X - ar galima sužinoti kas jį padarė? Ir su kokiu tikslu? Gyvoje versijoje atsirado klaidų - reikia staigiai atšaukti paskutinį pakeitimą ir grąžinti kodą į prieš tai buvusį Esmė - tikrai prireikia atrasti, peržiūrėti, o kartais ir panaudoti senesnes kodo versijas. Kaip tai daroma "ūkiškai"? Žmonės tiesiog kuria katalogus su datomis, neretai projektuose tekdavo matyti katalogus "backup20150601" ar failus "OrderController_20150601.php". Visa tai galima atlikti daug patogiau ir efektyviau - su versijų kontrolės sistemomis, angliškai VCS (version control systems) arba kartais dar "source control".

Tokių sistemų yra įvairių, bet neabejotinai populiariausios yra dvi Git ir Subversion (arba SVN). Jų principas kažkiek skiriasi, bet jei pagausite bendrus principus - be vargo, esant reikalui, galėsite naudotis ir kitais analogais.

Visas Git versijų kontrolės mechanizmas realiai susideda iš dviejų dalių: jūsų kompiuteryje lokaliai esančios Git sistemos, ir nutolusiame serveryje saugomų kodo kopijų saugyklos, populiariausios iš jų yra Github ir Bitbucket. Esmė tokia - dirbate savo kompiuteryje, kol ateina laikas įkelti kodą į kodo saugyklą, ir iš ten jau naujausią versiją ne tik gali pasiimti komandos draugai, bet ir paprasta kelių komandų pagalba įkelti kodą į gyvą arba testavimo serverį.

Dar vienas šalutinis tokių sistemų privalumas yra tai, kad nebereikia tikrinti, kas iš komandos narių kokį kodą kada įkėlė - galima nustatyti visokių integracijų su sistemomis, kurios automatiškai praneš, kad, sakykime, Povilas ką tik įkėlė į serverį kažkiek failų, kurių paskirtis - užbaigta funkcija X. Tokiu būdu išvengiama krūvos elektroninių laiškų ar kitokių komunikacijos priemonių su klausimu "kas ką šiandien nuveikė" - visiems komandos nariams (ir vadovams) viskas matoma.

Šiuolaikiniame programavimo pasaulyje versijų kontrolės sistemų išmanymas yra nebe privalumas, o būtinybė - darbo skelbimuose ir pokalbiuose to klausiama jau dažniausiai nebe prie papildomų "būtų gerai" punktų, o daroma prielaida, kad jei jau pretenduojate į poziciją dirbti komandoje, tai mokate naudotis Git ar panašiu įrankiu, be kurių šiais laikais komandinis darbas beveik neįsivaizduojamas.

Pamirškite FTP[keisti]

Web-projektuose nuo senų laikų failų perkėlimui į serverį naudojamas FTP protokolas. Naudojant FTP klientą (FileZilla, CoreFTP ar dar kokį nors), failai tiesiog įkeliami į serverį kiekvieną kartą, kai reikia kažką paleisti į gyvą versiją. Atrodo lyg ir patogu, bet kas jeigu reikia įkelti 17 skirtingų failų iš skirtingų katalogų? Baksnoti ir kelti po vieną? Ar tiesiog perrašyti visus tuos katalogus "ant viršaus"? Ir kaip tada atsekti, kas būtent buvo pakeista? O kas jeigu viduryje siuntimo FTP ryšys pakimba ar dingsta?

Versijų kontrolės sistemos išgelbsti nuo visų šių problemų. Tiesą pasakius, kai pats ilgą laiką dirbi su FTP, net nežinai kad turi tą problemą - viskas daugmaž veikia o jei kažkur nulūžta tai būna nesunkiai sutvarkoma. Bet problemos prasideda kai tenka dirbti prie projektų su komanda. Ir tada kai reikia sekti kas kokius pakeitimus padarė ir įkėlė į serverį - tragedija. Dėl to siūlau jums judėti nuo failų įkėlimo per FTP prie versijų kontrolės. Per FTP apsimoka kelti nebent kokius paveiksliukus ar kitus failus, nesusijusius su kodu.

O jeigu projektą galima deployinti tiktai per ftp, pasinaudokite mano įrankiu git-ftp.

Ką reikia mokėti, norint naudotis Git[keisti]

Iš principo, jokių išankstinių reikalavimų nėra. Versijų kontrolė praktiškai nekeičia kodo rašymo proceso - tai, galima sakyti, atskiras papildomas veiksmas, siekiant užtikrinti efektyvesnį kodo saugojimą. Ir versijų kontrolė nepriklauso nuo programavimo kalbos ar operacinės sistemos (nors kiekviena OS turi savo Git įrankius). Realiai Git galima taikyti ne tik programiniam kodui - o jeigu, sakykime, norite saugoti skirtingas Word dokumento ar nuotraukų katalogo versijas.

Git turi tam tikrą komandų kalbą, dirbdami per komandinę eilutę - tai gali būti Command Prompt ar Terminal, taip pat yra atskiras įrankis Git Bash, bet principas tas pats: komandos leidžiamos iš komandinės eilutės. Taip pat yra programų, padedančių atlikti Git komandas vizualiai (panašiai kaip FTP klientai), bet vis tiek reikia žinoti versijų kontrolės pagrindus, kad suprastumėte, kas kaip vyksta.

Git Diegimas[keisti]

Pradėkime nuo "neįdomių" dalykų - paruošimo darbų. Kol kas, nesigilinant į tai, kas ką reiškia - tiesiog reikia įdiegti Git į kompiuterį. Pačios platformos diegimas priklauso nuo jūsų operacinės sistemos. Kadangi Lietuvoje populiariausia yra Windows platforma, bet pačios komandos nesiskirs, šiek tiek kitoks bus tik diegimas.

Windows sistemai viskas susiveda į vieną paketą, kurį galite parsisiųsti šiuo adresu: https://git-scm.com/download/win

02 01 download windows.png

Pastaba. Kitoms operacinėms sistemoms diegimo informaciją rasite šiame puslapyje.

Pats diegimas vyksta įprastu "Next" -> "Next" -> "Finish" principu, palikite visus nustatymus kaip siūloma, esminis svarbus langas yra tik šitas:

02 02 install.png

Paaiškinsiu ką jis reiškia: Git komandas galima rašyti per specialią komandinę eilutę pavadinimu Git Bash, kuri bus įdiegta kartu su šiuo paketu, bet galima tą patį daryti ir su Windows sistemos komandine eilute Command Prompt. Tai šiuo atveju aš rekomenduoju jums rinktis antrąjį variantą, nes gal jums asmeniškai pažįstama komandinė eilutė bus patogesnė. Bet šiaip jei pasirinksite ir vien Git Bash - nieko tokio.

Bus dar keletas tarpinių langų su klausimais, bet, kaip sakiau, palikite visus nustatymus kaip jums siūloma - jei norėsite, vėliau galėsite paanalizuoti, ką jie reiškia.

Ir viskas, galima naudotis Git. Iš principo, yra du įrankiai, kuriais galite naudotis - įrašę paieškoje git, pamatysite Git Bash (komandinė eilutė) ir Git GUI (vizualus įrankis):

02 03 bash gui.png

Apie Git GUI dabar net nepasakosiu, bet tiesiog turėkite omenyje kad yra ir GUI įrankis daugeliui komandų atlikti vizualiai.

Na, o Git Bash, jį paleidus, atrodo daugmaž taip:

02 04 git bash.png

Kaip ir paprasta komandinė eilutė, tik gal su šiek tiek daugiau spalvų. Tai tam kartui kaip ir viskas su diegimu, dabar prieš rašant komandas pats laikas apžvelgti apskritai Git veikimo principus.

Git veikimo principas ir pirmosios komandos[keisti]

Visgi pradėkime iš karto nuo praktikos - neišsigąskite, taip bus ir paprasčiau suprasti teoriją, ir įdomiau jums patiems. Sakykime, kad kuriame naują PHP projektą, visiškai nuo nulio, dėl paprastumo nenaudodami jokio frameworko. Tiesiog "Hello World". Atidarome mėgstamą kodo redaktorių (naudosiu Sublime Text) ir įrašome:

<?php echo "hello world";

02 05 hello world.png

Išsaugome index.php ir jau turime "paruoštą" projektą - tiksliau jo pirmąją versiją. Nesvarbu, kad ji susideda iš vieno failo.

Ir sakykime, kad nuo šiol norime sekti visus jo tolimesnius pakeitimus su Git. Tai paleidžiame komandinę eilutę Git Bash, pereiname su komanda cd į mūsų projekto katalogą (mano atveju C:/Users/Povilas/Gitproject) ir inicializuojame Git šiame kataloge - štai pirmoji paprasta komanda.

git init

02 06 init.png

Ką ši komanda daro? Realiai sukuria viduje savo katalogą .git - kuriame ir bus saugomos projekto versijos ir visa reikalinga informacija.

Šioje vietoje susiduriame su pirmu svarbesniu Git terminu: repozitorija. Šį žodį minėsime dažnai ir keliomis reikšmėmis, bet iš principo repozitorija yra ta vieta, kur saugomi visi jūsų kodo pakeitimai ir jų duomenys: kada jie buvo atlikti, kas tai padarė, kokį komentarą prie to prirašė ir kt.

Repozitorija gali būti lokali (t.y. saugoma jūsų kompiuteryje) ir nutolusi (angl. remote, pvz saugoma GitHub sistemoje). Apie jų skirtumus dar kalbėsime kurso eigoje, dabar jums reikia žinoti tik tiek, kad, ūkiškai tariant ir supaprastinant, repozitorija yra katalogas, kuriame saugomi visi jūsų failų pakeitimai. Mūsų atveju tai yra ką tik mūsų sukurtas katalogas .git.

02 07 folder.png

Jei šio katalogo nematote, nepamirškite įjungti Hidden failų/katalogų rodymo:

02 08 hidden.png

Patys rankiniu būdu to katalogo turinio keisti neturėtume, visi jo pakeitimai bus atliekami su Git komandomis iš komandinės eilutės.

Kalbant apie komandas, jų visų formatas yra toks:

git [komanda] [raktai] [parametrai]

Šiuo atveju buvome paleidę komandą init, be jokių papildomų raktų ar parametrų.

Paaiškinimas. Raktai ir parametrai veikia labai panašiai kaip ir kituose komandinės eilutės įrankiuose. Raktas yra raidės su brūkšneliu, o parametrai gali būti laisvos formos tekstas. Pavyzdys:

git commit -m "Pakeitimo žinutė"

-m šiuo atveju yra komandos raktas, o "Pakeitimo žinutė" - komandos parametras

Kita ir, turbūt, svarbiausia Git komanda, yra status - ji tiesiog parodo mums dabartinę katalogo būseną: ar turime naujų neapdorotų failų, ar yra kokių konfliktų (apie juos vėliau) ir pan.

02 09 status.png

Iš pirmo žvilgsnio atrodo, kad daug neaiškaus teksto. Bet pabandykime tiesiog įsiskaityti - viskas parašyta juodu ant balto (na kitom spalvom iš tikro, bet ne esmė): šiuo metu dabartinė mūsų repozitorijos būsena yra tokia, kad yra vienas naujas failas index.php, kuris dar nėra įkeltas į pakeitimus.

Kaip matote, Git ne tik parodo būseną, bet ir sufleruoja, kokią komandą mums toliau naudoti, norint pridėti failą (šiuo atveju git add).

Taigi, išmokome inicializuoti Git konkrečiame kataloge ir pažiūrėti būseną. Judame toliau - prie konkrečių failų valdymo.

Versijų kontrolės principai[keisti]

Prieš kalbant apie tolimesnes komandas, reikia paaiškinti kaip apskritai veikia versijų saugojimas.

Pastaba. Iš karto atsiprašau kad naudoju angliškus terminus, bet normalių lietuviškų vertimų jiems nelabai yra,
o ir visame pasaulyje priimti žodžiai bei jų junginiai bus vartojami nuolat kur sutiksite straipsniuose
ar pokalbiuose su kitais kolegomis, tad su laiku priprasite ir išmoksite.
Taip pat svarbu žinoti, kad tas pats dalykas gali būti vadinamas keliais skirtingais būdais,
tai visa tai pasiaiškinsime eigoje, nagrinėdami kiekvieną proceso dalį.

Realiai yra keturi "etapai", kaip saugoma konkreti pakeitimų būsena:

  • "Working copy" - kai tiesiog keičiate failus lokaliai, neleisdami jokių Git komandų;
  • "Staging area" arba "staging index" - čia kraunate visus savo mažus pakeitimus (su add komanda), bet jie dar nepatenka į Git repozitoriją;
  • "Local repository" - tai yra aktyvus Git katalogas, kuriame saugomi paskutiniai jūsų įkelti ir patvirtinti (su commit komanda) pakeitimai;
  • "Remote repository" - pirmųjų trijų etapų metu viskas vis dar vyksta jūsų kompiuteryje lokaliai, o jei norime kad pakeitimus matytų kiti žmonės - turime juos įkelti į nutolusį Git katalogą (dažniau vadinama "repozitorija" arba "repo"), kuris dažniausiai saugomas kokioje nors duomenų bazėje kaip Github ar Bitbucket.

Turbūt vis dar atrodo gan painu. Bet nebijokite, pabandysiu dar paaiškinti su kitokiu gyvenimišku pavyzdžiu.

Įsivaizduokite, kad dirbate fabrike, kuris gamina kažką - sakykime, žaislus. Jūs per valandą pagaminate X žaislų, tada kraunate juos į sunkvežimį, kuris pamainos pabaigoje nuveža sukrautą produkciją į parduotuves. Tai principas toks:

  • Vieno žaislo gaminimo procesas - tai yra jūsų "working copy", kuri dar niekam nerodoma
  • Pagaminote vieną žaislą - įdedate jį prie savęs prie tam skirtos pagamintų žaislų krūvos, kuri vėlgi prieinama tik jums: tai jūsų asmeninė "staging area"
  • Kai ta krūva prisipildo - nunešate į sunkvežimį (juk po vieną žaislą neapsimoka nešioti), ir tada jau savo fabriko viduje patvirtinate, kad tie žaislai pagaminti: tai "local repository"
  • Pamainos pabaigoje sunkvežimis nuveža žaislus į parduotuvę, kur jie prieinami visiems - "remote repository"

Tikiuosi, kad taip aiškiau - vėlgi tuos visus etapus aprašysiu vėliau...

Git ignore egzistuojantiems failams[keisti]

Pridedame ka reikia i .gitignore

git rm -r --cached .
git add .
git commit

Atšaukti rebase[keisti]

Jeigu taip išėjo jog lokalus branchas buvo atsitiktinai rebasintas ir pakeitimai supushinti į serverį, paprasta išeitis atstatyti pakeitimus ir sugrįžti į pradinę stadiją. Prieš tai patartina pasidaryti repozitorijos atsarginę kopiją. Naudojam komandą pažiūrėti pastarasias operacijas

git reflog

Matysime kur buvo darytas rebase, surandame commitą į kurį norime sugrįžti ir rašome

git reset --hard HEAD@{4}

HEAD@{4} matysis prie commito į kurį norime sugrįžti. Tuomet supushiname pakeitimus

git push --force

Jeigu norime sugrįžti prie brancho kuris yra serveryje

git reset --hard origin/HEAD