--- title: GIT — EITB 2022 subtitle: Sarrera eta erabilera basikoa license: CC-BY-SA 4.0 author: Ekaitz Zarraga - ElenQ Technology links-as-notes: true lang: basque polyglossia-lang: name: basque how-to: pandoc -f markdown+smart -t beamer % -o pdf/1.pdf --pdf-engine=xelatex --template=./template.tex ... ## Lizentzia - CC-BY-SA 4.0 - Dokumentu honen edukiak eta irudiak [**Pro Git (Scott Chacon, Ben Straub)**](https://git-scm.com/book/en/v2) liburutik atera dira. # Sarrera: Bertsio kontrol sistemak ## Bertsio kontrolerako sistemak `Document_v3_FINAL.pdf` --- ![Bertsio kontrol sistema zentralizatuak](img/zentralizatuak.png){ height=180px } --- ![Bertsio kontrol sistema banatuak](img/banatuak.png){ height=300px } # Git: Hasiera ## Kontestua - 2005-ean argitaratu zen - Linux garapenerako garatu zen - Milioika garatzaile - *Codebase* handiak kudeatzeko - Sistema banatua (*distributed*) da - *Snapshot*etan oinarrituta - Operazio gehienak lokalak dira eta normalean ez ditu datuak ezabatzen - Integridade kontrola egiten du SHA-1 erabiliz - Hiru egoera: `FITXATEGIA — STAGING AREA — REPOSITORIOA` ## Instalazioa Debian oinarritutako distribuzioetan: ``` apt-get install git ``` Beste distribuzioetan antzeko komandoren batekin egin daiteke. ## Konfigurazio sistema - Sistema mailakoa: `/etc/gitconfig` - Konfigurazio generala: `~/.config/git/config` edo `~/.gitconfig` - Konfigurazio lokala. Repositorio bakoitzeko: `$REPOSITORIOA/.git/config` Kaskada moduan dabil, konfigurazio lokalak generala zapaltzen du. Nondik datorren ikusteko: ``` git config --list --show-origin ``` ## Konfigurazioa kudeatzea Komandoek konfigurazio fitxategia irakurri edo idazten dute. Eskuz egin daiteke. Komando orokorra: ``` git config [--global] atala.klabea [balioa] ``` - `balioa` gehitzen ez bada konfigurazioa irakurtzen da idatzi beharrean. - `--global` konfigurazio globala kudeatzeko erabiltzen da. Benetan konplexuagoa da, laguntza begiratu. ## Hasierako konfigurazioa Identitatea definitu. Beharrezkoa da commiten egilea nor den jakiteko. ``` git config --global user.name "John Doe" git config --global user.email johndoe@example.com ``` Editorea aukeratzeko. ``` git config --global core.editor vim ``` ## Laguntza lortzeko - `git help` - `man` # Git basikoa ## Repositorio bat lortzen Bi aukera: - Repositorio berri bat hasi: `git init`. Oraingo direktorioan `.git` direktorioa eratuko du, bertan Git-en datuak gordeko dira. - Repositorio bat klonatu: `git clone `. Oraingo direktorioan emandako repositorioa kopiatuko du, bere `.git` direktorioa barne. Protokolo ezberdinetan egin daiteke komunikazioa. ## Fitxategien egoerak ![Fitxategien egoera ezberdinak](img/lifecycle.png){ height=180px } ## Repositorioaren egoera ikusteko - `git status` - Fitxategi batzuei jaramonik ez egiteko: `.gitignore` fitxategi bat gehitu. *Glob pattern*ak erabiltzen ditu. ## Egoeraz aldatzeko - Fitxategi berriak gehitzeko: `git add` - Aldaketak *staging area*ra bidaltzeko: `git add` ## Aldaketak ikusteko - `git diff` - `git diff --cached|--staged` - `git difftool` (konfiguratuta badago) ## Aldaketak idazteko - `git commit` Mezu bat idaztea eskatzen du: `$EDITOR` edo `git config --global core.editor` programa exekutatuz. ## Fitxategiak ezabatzeko - `git rm` - `git rm --cached` ## Izenak aldatzeko - `git mv` Edo bestela fitxategia eskuz lekuz aldatu eta gero `git rm` + `git add` egin. ## Commit historia ikusteko - `git log` Oso komando konplexua da. Aukera asko ditu. - `-` azkeneko `` commitak aurkezten ditu. `` zenbaki bat izan behar da. - `-p/--patch` commit-en *patch*-a ateratzen du. - `--stat` estatistikak aurkezteko. - `--pretty` formatua aldatzeko, modu asko dauzka. - `--graph` grafiko modua. Konbinatu daitezke: `git log --graph --pretty=oneline --decorate --all` ## Commit historia iragazteko `git log`-en irteera limitatu daiteke, eskaerak eginez: - `--since` noiztik ikusi nahi diren. Adibidez: `--since=2weeks`. - `--author` autorez iragazi. - `--grep` commit mezuan *keyword*ak bilatzeko. - `-S/-G/...` *pikeaxe function* deiturikoak, aldaketetan testua bilatzen dute. - `git log -- fitxategia` fitxategi horretan gertatutako aldaketak bakarrik atera. - `--no-merges` merge commitak deskartatu. Laguntza ikusi: `git help log` ## Aldaketak desegiteko - `git commit --amend` azkeneko commita berridazten du. - Mezua aldatu - Fitxategiak edo aldaketak gehitu - ... - `git reset` aldaketak *staging area*tik kentzeko. KONTUZ `--hard`-ekin - `git checkout` aldaketak desegiteko eta commiteatutako egoera berreskuratzeko. KONTUZ - `git restore` komando berria da (>2.23.0) `reset` eta `checkout`-ek egiten dituzten gauzak egiten dituena, baina intuitiboagoa da. ## Remoteak Repositorioaren kopiak dira. Remoteak eguneratu daitezke repositorio lokaletik aldaketak igotzen (*push*) edo repositorio lokala eguneratu daiteke remotean dauden aldaketak ekartzen (*fetch & pull*). Remoteak beste makinetan egon daitezke, sarearen bidez sarbidea emanda, edota makina berdinean, fitxategi sistemaren beste leku batetan. ## Remote-en kudeaketa - `git remote` `.git/config` fitxategian daude idatzita. Hortik ere kudeatu daitezke. - `git clone` -k remotea automatikoki gehitzen du konfiguraziora, `origin` izenarekin. - `git remote -v` - `git remote add ` - `git remote show ` - `git remote rename ` - `git remote remove ` ## Remotearekin informazioa elkarbanatu - `git fetch []`-ek remotearen informazioa deskargatzen du, repositorioa zapaldu gabe. - `git pull` informazioa deskargatu eta `merge`atzen du adarrak ondo konfiguratuta badaude: ``` git pull = git fetch + git merge ``` - `git push [ ]` datuak eta commitak igotzen ditu. Norbaitek commitak erdian gehitu baditu ez du uzten (aurrerago azalduko da). ## Tag-ak Commitei jarri ahal zaizkien izenak dira, normalean *release*ak errezago identifikatzeko. Horrela, tag-en izenak erabiltzen dira *commit-id*-ak balira moduan baina guk erabakitako izenekin. Adibidez, `v1.0`. - `git tag -l` tagak bistaratzeko Bi tag mota dago: - **Lightweight**: Puntero bat dira. Adar finko baten modukoak - **Annotated**: Git-en datu basean objetu oso bat dira: Mezu bat daukate, autorea, sinatu daitezke... ## Annotated tags - `git tag -a []` `git show` -k erakusten ditu. ## Lightweight tags - `git tag []` `git show`-k ez ditu erakusten, azpitik dagoen commita erakusten du. ## Tag-ak partekatzeko - `git push [] ` - `git push [] --tags` guztiak bidaltzeko ## Tag-ak ezabatzeko - `git tag -d ` - `git push [] --delete ` ## Aliasak Gitek komandu berriak eratzea ahalbidetzen du aliasen bitartez. Beste konfigurazio balioak bezala idazten eta irakurtzen dira: - `git config --global alias.co checkout` - `git co` => `git checkout` Nik asko erabiltzen dut: ``` git config --global alias.lg log --graph \ --decorate --all --oneline ``` # Git basikoa: Adarrak ## Adarrak (*branch*) Adarrek repositorioaren garapenean beste bide bat hartzea ahalbidetzen dute, bertan bide nagusian aldaketarik eragin gabe lan egiteko. Git adarrak erabiltzeko diseinatuta dago eta haien erabilera sustatzen du. Beraz, **oso garrantzitsuak** dira. Beste bertsio kontrol sistema batzuetan adarrak erabiltzea prozesu astuna da, errekurtso asko behar dituena. Git-en oso prozesu sinplea da eta ez du ia errekurtsorik behar. Git-en bitartez kudeatzen diren proiektuetan ez da arraroa ehundaka adar ikustea. ## Git barrutik - Fitxategiak *Staging Area*ra bidaltzean, Git-ek haien argazkiak gordetzen ditu *blob* objetu moduan eta haien checksuma kalkulatzen du (SHA-1) - Commita egiterakoan direktorio bakoitzaren checksuma kalkulatzen du eta *tree* objetu bat gordetzen du direktorio bakoitzeko. *Tree* objetuak, *blob* objetuetara apuntatzen duten punteroak dituzte. Gainera commitek beste datuak gordetzen dituzte: autorea, mezua, data... - Commit berri bat gehitzean bere commit gurasoei apuntatzen du: punterorik ez dauka lehengo commita bada, puntero bakarra dauka commit normaletan eta puntero asko ditu *merge* commiten kasuan. Adarrak commitetara apuntatzen duten puntero mugikorrak dira. ## Git barrutik ![Git repositorio baten barne datuak](img/commit-and-tree.png) ## Git barrutik ![Git repositorio baten commit estruktura](img/commits-and-parents.png) ## Adarrak eratzeko - `git branch ` Defektuz `master` deitutako adar bat dago. Izena konfiguragarria da, baina gutxienez adar bat egon behar da beti, bertan commitak gehitzen direlako. Git-ek oraingo adarrera apuntatzen duen erreferentzia bat gordetzen du: `HEAD` deiturikoa. ## Adarraz aldatzeko - `git checkout ` - `git checkout -b ` adarra eratu eta aldatzeko Bertsio berrietan, `checkout` komanduak gauza gehiegi egiten dituenez, komando espezifiko bat eratu zen adarrekin lan egiteko: - `git switch ` - `git switch -c ` adarra eratu eta aldatzeko - `git switch -` aurreko adarrera bueltatzeko ## Adarrak eta aldaketak — I ![`git branch testing`](img/head-to-master.png) ## Adarrak eta aldaketak — II ![`git checkout testing`](img/head-to-testing.png) ## Adarrak eta aldaketak — III ![`git commit ...`](img/advance-testing.png) ## Adarrak eta aldaketak — IV ![`git checkout master`](img/checkout-master.png) ## Adarrak eta aldaketak — V ![`git commit ...`](img/advance-master.png) ## Adarrak eta aldaketak — VI Giten interfazetik ikusita: ``` $ git log --oneline --decorate --graph --all * c2b9e (HEAD, master) Made other changes | * 87ab2 (testing) Made a change |/ * f30ab Add feature #32 * 34ac2 Fix bug #1328 * 98ca9 initial commit ``` > KONTUZ: Ez bada `--all` egiten ez dira defektuz adar guztiak bistaratzen `git > log`-en bitartez. ## Adarrak eta mergeak — I ![](img/basic-branching-4.png){ height=180px } ## Adarrak eta mergeak — II **Fast forward** kasua. Adar bat bestearen barruan dago. ![`git checkout master` `git merge hotfix`](img/basic-branching-5.png){ height=200px } ## Adarrak eta mergeak — III Beti ez da hain erreza. Demagun: ![](img/basic-branching-6.jpg){ height=180px } ## Adarrak eta mergeak — IV Arbaso amankomuna (*common ancestor*) ateratzen saiatzen da eta bi buruekin eta arbaso amankomunarekin *three-way merge* bat egiten du. ![`git checkout master` `git merge iss53`](img/basic-merging-1.jpg){ height=180px } ## Adarrak eta mergeak — V Commit berri bat gehitzen du, bi adarrak lotzen dituena. *Merge* commita da: bi guraso (edo gehiago) ditu. ![`git checkout master` `git merge iss53`](img/basic-merging-2.jpg){ height=180px } ## Konfliktoak — I Aurreko kasua ez da beti ondo ateratzen, batzutan konfliktoak egon daitezke bi adarretan aldaketak leku berdinetan agertzen direnean: ``` $ git merge iss53 Auto-merging index.html CONFLICT (content): Merge conflict in index.html Automatic merge failed; fix conflicts and then commit the result. ``` ## Konfliktoak - II ``` $ git status On branch master You have unmerged paths. (fix conflicts and run "git commit") Unmerged paths: (use "git add ..." to mark resolution) both modified: index.html no changes added to commit (use "git add" and/or "git commit -a") ``` ## Konfliktoak - III Fitxategia horrela ikusten da: ``` <<<<<<< HEAD:index.html ======= >>>>>>> iss53:index.html ``` Separadoreak daude `<<<<<<<`, `=======` eta `>>>>>>>`. Lehenengo zatian `HEAD`-en zegoena dago eta bigarrenean `iss53`-n zegoena. `git mergetool` erabili daiteke konfliktoak errezago konpontzeko. ## Adarrak kudeatzeko - `git branch` adarrak listatzeko - `git branch --merged | --no-merged` oraingo adarrarekin mergeatuta edo mergeatu gabe dauden adarrak listatzeko - `git branch -d ` adarrak ezabatzeko. Mergeatu gabe dauden adarrak ez ditu zuzenean ezabatzen. - `git branch --move ` izenez aldatzeko. - `git push --set-upstream ` remoteari zein adar erabili behar duen esateko - `git push --delete ` remotean adar bat ezabatzeko ## Adarrekin workflow ezberdinak - Long running branches: `master`, `testing` eta `development` - Topic branches: issue eta feature bakoitzeko adar berri bat eratzen da. ## Adarrak remotetan