--- title: GIT — EITB 2022 subtitle: Erabilera aurreratua 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/2.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. # Git zerbitzarian ## Git zerbitzarian: sarrera Lankideen artean kodea partekatzeko zerbitzari bat izatea ideia ona da: beti dago eskuragarri, kudeaketa sinplifikatzen du, etab. Zerbitzarietan *bare repository*-ak erabiltzen dira. Hauek ez dute *working directory*-rik. `.git` direktorioan dagoena bakarrik dute. - `git init --bare` *bare repository* bat eratzeko. ## Protokoloak Protokolo ezberdinak erabili daitezke repositorioen arteko komunikazioa egiteko: - **Local**: beste fitxategi batean dagoen repositorioa. `git clone /path/to/file`-en bitartez klonatu daiteke. - **HTTP**: *smart* edo *dumb* moduak ditu. *Smart*-ek baimenak kudeatu ditzake. *Dumb*-ek fitxategiak eman baino ez du egiten. - **SSH**: Askotan erabiltzen da. Erabiltzaile bat behar du. `git clone ssh://[@]/.git` erabiliz. SCP-ren modu laburra erabili daiteke: `[@]:.git`. - **Git**: SSH-ren antzekoa da baina autentikazio barik. ## Protokoloak — Adibide bat Nire [zerbitzaria](https://git.elenq.tech/): - Web bitartez proiektuak aztertu daitezke. `cgit` erabiltzen du. Beste aukera batzuk daude: `gitweb` adibidez, Git-ekin datorrena. - Proiektu publikoak Git-en bitartez zerbitzatzen dira edonork kopiatu ahal izateko. - Idazteko baimena SSH-ren bitartez zerbitzatzen da, baimena kontrolatu ahal izateko. *Liburuan azaltzen da gauza hauek nola muntatu.* # Git workflowak ## Workflow zentralizatua Git-en izaera banatuak *workflow* ezberdin asko ahalbidetzen ditu baina gaur egun *workflow zentralizatua* erabiltzen da gehien, Web zerbitzu integratuen arrakastagatik (Github, Gitlab, Gitea...) non tiketak eta kodea kudeatzeko aukera dagoen. ![Bezero guztiak zerbitzariarekin sinkronizatzen dira](img/centralized_workflow.png){ height=140px } ## Email-en bitartez Software libre proiektu asko oraindik emailean oinarritzen dira aldaketak proposatzeko. - `git format-patch ` aukeratutako commitak patch fitxategietan idazteko - `git send-email ` patch-ak emailez bidaltzeko (konfigurazioa behar du) - `git am ` jasotako patch-ak proiektuan commiteatzeko - `git apply ` jasotako patch-ak aldaketa moduan aplikatzeko # Git tresna aurreratuak ## Commit selektoreak Giten komando askok commit askotan aplikatu daitezke. Gitek commit selektore ezberdinak aplikatzea ahalbidetzen du commitak aukeratzeko. - `git show ` aukeratutako objektuak erakusteko ## Commit selektoreak — I - **SHA-1 hasha**: commit identifikadorea bera erabili daiteke selektore moduan. Oso luzeak direnez, hasierako karaktereak bakarrik erabili daitezke anbiguoak ez badira. `git log --abbrev-commit` commit id-aren laburpena egiten du. - **Adarren burua**: adarraren izena erabiltzean, adarraren buruaren commita aukeratzen da: `git show `. Adarraren buruaren commit id-a ateratzeko: `git rev-parse `. - **Reflog-a**: Reflog-a repositorioaren egoera gordetzen du historiko baten modura. Reflog-aren sarreren izenak erabili daitezke commit selektore moduan. Gainera denbora erabili daiteke: `HEAD@{yesterday}`. - `git reflog` reflog-aren sarrerak erakusteko ## Commit selektoreak — II - **Gurasoak**: aukeratutako commiten gurasoak eta aitzindariak lortu daitezke: - Txapela (`^`) erabiliz aukeratutako commitaren gurasoak lortu daitezke. Adibidez: `git show HEAD^`. Merge commitetan (guraso asko dituztenak) gurasoen artean aukeratzeko `^` eta gero gurasoaren zenbakia jarri daiteke guraso konkretua lortzeko. - Tildea (`~`) erabiliz aitzindariak lortu daitezke. Zenbaki bat gehituta aurreko aitzindaria lortu daiteke. Adibidez `git show HEAD~2`: aurreko commitaren aurrekoa lortu. ## Commit selektoreak — III - **Commit tartea**: bi commiten arteko tartea lortzeko: `..` Adarrekin ere egin daiteke, adar batetik besteraren burura ailegatzeko behar diren commitak lortzeko: ![](img/double-dot.png){width=350px} - `git log master..experiment` => D C - `git log experiment..master` => F E ## Commit selektoreak — IV - **Puntu tripleak**: bi adarretatik ailegatu ahal diren commitak, baina amankomunean ez daudenak: ![](img/double-dot.png){width=350px} - `git log master...experiment` => F E D C - Zein adarretik datozen ikusteko `--left-right`: ``` git log master...experiment --left-right < F < E > D > C ``` ## Commit selektoreak — V - **Puntu multipleak**: eskaera konplexuagoak egiteko `^` (aurretik) edo `--not` erabili daiteke, adar horren commitak baztertzeko: - Hurrengo komandoak baliokideak dira: ``` git log refA..refB git log ^refA refB git log refB --not refA ``` - Hurrengo komandoek `refA`tik eta `refB`tik lortu daitezkeen commitak hartzen dituzte, `refC`tik lortu daitezkeenak baztertuz: ``` git log refA refB ^refC git log refA refB --not refC ``` ## Staging interaktiboa - `git add --interactive | -i` stage-a modu interaktiboan kudeatzeko - `git add --patch | -p` gehituko diren aldaketak modu interaktiboan aukeratzeko. Blokez bloke *Komando askotan erabili daitezken aukerak dira hauek. Oso erabilgarriak dira.* ## Stash-a Aldaketak gordetzeko zaku bat da *stash*a. Trakeatu gabeko aldaketak bertan sartu daitezke repositoria aldatu/berriztu/mergeatu eta gero aldaketak berriro adar berdinean edo beste batean ateratzeko. - `git stash [push]` direktorioa garbitu eta aldaketak *stash*era sartzeko - `git stash list` *stash*aren sarrerak ikusteko - `git stash apply []` aukeratutako *stash* sarrera (defektuz azkena) aplikatzen dio *working directory*ari. - `git stash drop []` aukeratutako *stash* sarrera ezabatzeko - `git stash pop` = `git stash apply` + `git stash drop` *Push* eta *pop* izenak erabiltzen dira *stash*a LIFO ilara edo stack baten moduan kudeatzen delako. *Gainetik gehitu eta gainetik atera* ## Stash-a — Aukera interesgarriak - `git stash apply --index` egitean *staging area*ra bidaltzen dira *stash*ean *staging area*an zeuden fitxategiak. Defektuz ez dira *stage*era bidaltzen. - `git stash --keep-index` indexatutako (*stage*a) fitxategiak ez dira *stash*era gehitzen, eta *stage*ean mantentzen dira. - `git stash --include-untracked|-u` trackeatuta ez dauden fitxategiak ere *stash*eatzeratzeko. - `git stash --all|-a` baztertutako fitxategiak (`.gitignore`) ere *stash*era gehitzeko - `git stash --patch|-p` *stash*eratzeratzeko aldaketak modu interaktiboan aukeratzeko - `git stash branch []` adar berri bat sortu eta bertan aukeratutako *stash*a aplikatu. Dena ondo badoa *stash*a garbitzen du bukatzerakoan. ## Direktorioa garbitzeko - `git stash --all` egitea direktorio osoa garbitzen du, hau da, trackeatuta ez dauden fitxategiak eta aldaketak *stash*earatzen ditu. - `git clean` egiten antzeko efektu bat lortu daiteke *stash*a erabili gabe, zuzenean aldaketak eta fitxategiak ezabatuz. - `-f` (*force*) beharrezkoa da (defektuz, aukera bat dago desaktibatzeko) nahi gabe ez egiteko > KONTUZ: `git clean --dry-run|-n` erabili badaezpada, zer egingo duen ikusteko > benetan exekutatu baino lehen. ## Sinadurak Commit faltsuak ekiditeko, commitak sinatu daitezke GPG-ren bitartez. > GPG (Gnu Privacy Guard), PGP-ren (Pretty Good Privacy) inplementazio bat da. `user.signkey` konfiguratu behar da. - `git commit -S` commitak sinatzeko - `git tag -s` tagak sinatzeko - `git merge --verify-signatures` sinadurak baieztatzeko mergetan - `git tag -v` tag-en sinadurak baieztatzeko Sinadurak erabiltzen badira, proiektu kide guztiek commitak sinatu behar dituzte. ## Bilaketak - `git grep` espresio erregularren bitartez bilaketak egiteko. `grep` komandoarekin alderatuta azkarragoa da eta historikoan eta indexean bilatzen du. - `git log` logetan bilatzeko funtzio oso interesgarriak daude: - `-S` *pikeaxe* funtzioa - `-L` lerroen eboluzioa edo funtzioaren eboluzioa erakusten du ## Historia berridazten - `git commit --amend` mini-rebase baten eragina dauka - `git rebase -i|--interactive ` aukeratutako commitera ailegatzeko behar diren commitak aldatu. Editorearen bitartez commit bakoitzarekin zer egin behar duen adierazi ahal zaio: commitak batu, aukeratu, mezua berridatzi, editatu... Aukera batzuek prozesua gelditzen dute. `git rebase --continue` egiten aurrera jarraitzen da, edo `--abort` egiten prozesua ezeztatzen da. Komandoak berak oso ondo azaltzen du nola egin. > KONTUZ: N+1 commit aldatu emaitza gutxienez commit bat behar duelako - `git filter-branch` eta antzeko tresnek aldaketa sakonak egin ditzakete. Adibidez, fitxategi bat commit *guztietatik* kendu. ## Reset eta checkout sakonki — I Reset eta Checkout ulertzeko Giten fitxategien egoerak eta haien arteko trantsizioak ondo ulertu behar dira. Hiru egoera posible daude: 1. HEAD: repositorioaren azkeneko commitaren snapshota 2. Index: *staging area*, hurrengo commitaren proposamena 3. Working Directory: Aldaketak egiten ditugun lekua ![Egoren arteko trantsizioak](img/reset-workflow.png){height=150px} ## Reset eta checkout sakonki — II - `git reset`-ek hiru modu ditu: - `--soft`: HEAD-ak apuntatzen duen adarra mugitu - `--mixed`: `--soft` + aldaketak indexera pasatu - `--hard`: `--mixed` + aldaketak *working directory*ra pasatu, bertako aldaketak zapalduz ## Reset eta checkout sakonki — III ![ ](img/reset-ex1.png) ## Reset eta checkout sakonki — IV ![ ](img/reset-ex2.png) ## Reset eta checkout sakonki — V ![ ](img/reset-ex3.png) ## Reset eta checkout sakonki — VI ![ ](img/reset-ex4.png) ## Reset eta checkout sakonki — VII ![ ](img/reset-ex5.png) ## Reset eta checkout sakonki — VIII ![ ](img/reset-ex6.png) ## Reset eta checkout sakonki — IX ![Commit gehiago gehituta](img/reset-start.png) ## Reset eta checkout sakonki — IX ![ ](img/reset-soft.png) ## Reset eta checkout sakonki — X ![ ](img/reset-mixed.png) ## Reset eta checkout sakonki — XI ![ ](img/reset-hard.png)