From 3d08769c9b942a42fe8dc3a9074a92882fc5f7c9 Mon Sep 17 00:00:00 2001 From: Ekaitz Zarraga Date: Mon, 4 Sep 2023 19:52:41 +0200 Subject: Gitignore --- .gitignore | 1 + 1.md | 606 ----------------------------------- 2.md | 1026 ------------------------------------------------------------ README.md | 12 + eu/1.md | 606 +++++++++++++++++++++++++++++++++++ eu/2.md | 1026 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 1645 insertions(+), 1632 deletions(-) create mode 100644 .gitignore delete mode 100644 1.md delete mode 100644 2.md create mode 100644 README.md create mode 100644 eu/1.md create mode 100644 eu/2.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..da0de7e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +pdf diff --git a/1.md b/1.md deleted file mode 100644 index a33f883..0000000 --- a/1.md +++ /dev/null @@ -1,606 +0,0 @@ ---- -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 -- Integritate kontrola egiten du SHA-1 erabiliz -- Hiru egoera: - `FITXATEGIA — STAGING AREA — REPOSITORIOA` - -## Instalazioa - -Debian-en oinarritutako distribuzioetan: - -``` -apt-get install git -``` - -Beste distribuzioetan antzeko komandoren batekin egin daiteke. - - -## Konfigurazio sistema - -- Sistema mailakoa: `/etc/gitconfig` -- Konfigurazio orokorra: `~/.config/git/config` edo `~/.gitconfig` -- Konfigurazio lokala. Repositorio bakoitzeko: `$REPOSITORIOA/.git/config` - -Kaskada moduan dabil, konfigurazio lokalak orokorra 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 [] -``` - -- `` 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 aukeratu: - -``` -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) - -`diff` komandoaren irteera fitxategi batean gorde eta gero, beste norbaiti -pasatu ahal zaio, berak bere repositoriaren kopian `git apply` erabiliz -aplikatzeko. - -## 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 mugatu daiteke, eskaerak eginez: - -- `--since` noiztik ikusi nahi diren. Adibidez: `--since=2weeks`. -- `--author` autorez iragazi. -- `--grep` commit mezuan *keyword*ak bilatzeko. -- `-S/-G/...` *pickaxe function* deiturikoak, aldaketetan testua bilatzen dute. -- `git log -- fitxategia` fitxategi horretan gertatutako aldaketak bakarrik - atera. -- `--no-merges` merge commitak baztertu. - -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`-ek informazioa deskargatu eta `merge`atzen du adarrak ondo - konfiguratuta badaude: - ``` - git pull = git fetch + git merge - ``` - -- `git push [ ]`-ek 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**: erreferentzia bat dira. Adar finko baten modukoak -- **Annotated**: Git-en datu basean objektu 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 komando 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* objektu moduan eta haien checksuma kalkulatzen du (SHA-1) -- Commita egiterakoan direktorio bakoitzaren checksuma kalkulatzen du eta - *tree* objektu bat gordetzen du direktorio bakoitzeko. *Tree* objektuek - *blob* objektuetara apuntatzen duten erreferentziak dituzte. Gainera commitek - beste datuak gordetzen dituzte: autorea, mezua, data... -- Commitek haien gurasoei apuntatzen duten erreferentziak dituzte: - lehengo commitek erreferentziarik ez dute, commit normalek erreferentzia - bakarra dute eta *merge* commitek erreferentzia asko dituzte. - -Adarrak commitetara apuntatzen duten erreferentzia 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 bertara aldatzeko - -Bertsio berrietan, `checkout` komandoak 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.png){ 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.png){ 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.png){ height=180px } - -## Konfliktoak — I - -Aurreko kasua ez da beti ondo ateratzen, batzuetan 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 errazago 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 -u|--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 - -Gitek remoten erreferentziak gordetzen ditu remoten egoera ikusi ahal izateko. -`git ls-remote ` edo `git remote show ` erabiliz remoteen -egorea ikusi daiteke. - -Remoten adarrak lokalean ikusi daitezke `/` izenarekin. Ezin -dira aldatu. Push egiterakoan aldatzen dira, remotearen egoera aldatu delako. - -![Adibidea: repositorio lokalak bi commit berri ditu](img/remote-branches.png) - -## Push egitea - -- `git push ` adarra remotera pusheatzeko. Eskuz egin behar - da. Horrela adar lokalak babesten dira eta ez dira automatikoki igotzen. - -- `:` erabiltzean izen ezberdinak jarri ahal zaizkie - adarrei, bata lokalean eta bestea remotean - -## Tracking branches - -Remoteak jarraitzeko erabiltzen mekanismoa da. Remotearen adar bat (*upstream*) -adar lokal baten (*tracking*) arteko erlazioa da. - -- `git checkout -b /`-k `/` - `` izenarekin *track*eatzen du -- `git checkout --track /` oraingo adarra eta remotearena - erlazionatu. Sinpleago. -- `git checkout `-k erlazioa eratzen du automatikoki, `` - lokalean existitzen ez bada. Sinpleago. -- `git clone` egiterakoan `master` adar lokala eratzen da `origin/master` - adarra *track*eatzen. -- `git branch -u|--set-upstream-to /` zure adarraren upstream-a - aldatzeko. Ikusi `git push`-en. - -> `@{upstream}` edo `@{u}` idatzi daiteke hortik aurrera remotearen adarraren -> izen osoa erabili beharrean - -## Pull egitea - -Tracking adarra aktibatuta badago, `git pull` egiteak zuzenean `git fetch` eta -`git merge` aldi berean egingo ditu. - -Kontuz ibili: batzuetan `git pull`-en magia ulertzeko zaila izan daiteke. -Proiektua jende askok ukitzen badu, hobe `git fetch` egitea. - -## Adarrak eta rebaseak — I - -![](img/basic-rebase-1.png) - -## Adarrak eta rebaseak — II - -![`git merge` egitean gertatzen dena](img/basic-rebase-2.png) - -## Adarrak eta rebaseak — II - -![`git checkout experiment` -`git rebase master`](img/basic-rebase-3.png) - -Orain merge-a *fast-forward* izango da eta ez du merge commit-ik gehituko. - -## Rebase konplexuago bat — I - -![](img/interesting-rebase-1.png) - -## Rebase konplexuago bat — II - -![`git rebase --onto master server client`](img/interesting-rebase-2.png) - -`client`-en dauden aldaketak pasatzen ditu `master`-era `server`-en daudenak -izan ezik. - -Orain `server` `master`-en rebaseatu daiteke eta gero `git merge` -*fast-forward* bat egin. - -## Rebasekin kontuz ibili - -Rebaseak egiterakoan commit berriak egiten dira, aurrekoen antzekoak edukiz, ez -dira berdinak. Remote-an pusheatzerakoan beste lankideek rebaseak egitera -behartzen ditu: - -- `git push --force` remotean historia berridazten du. Git zerbitzuetan adar - babestuak existitzen dira hau saihesteko. Kontuz. -- `git pull --rebase`-k lagundu dezake `pull` egiterakoan, remotean historia - berridatzi bada. Pull-en estrategietako bat da, asko daude eta defektuz - egiteko konfiguratu daitezke. - -## Rebase vs Merge - -Filosofiaren arabera bata edo bestea gehiago erabiltzea komeni da: - -- Repositorioa historiko moduan ulertuta: rebase egitea txarra izango - litzateke, historikoa zapaltzen baitu. (*fossil-ek filosofia hau jarraitzen - du, ez dauka rebase egiteko tresnarik*) -- Repositorioa *making of* modura ikusten bada aproposa da rebase egitea. - Historikoa garbiagoa uzten duelako. - -Aholkua: lokalean rebase egin commit historikoa garbitzeko baina behin -zerbitzarira igota historia ez aldatu, lankideen prozesuan eragina baitu. - diff --git a/2.md b/2.md deleted file mode 100644 index a4e64d1..0000000 --- a/2.md +++ /dev/null @@ -1,1026 +0,0 @@ ---- -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 asko commit askotan aplikatu daitezke. Gitek commit selektore -ezberdinak aplikatzea ahalbidetzen du commitak aukeratzeko. - -- `git show ` aukeratutako objektuak erakusteko - -*Ikusi `git show`-n laguntza. Objetu ezberdinak erakutsi ditzake* - -*Ikusi `git rev-parse`-n laguntza, selektoreen sintaxia azaltzen baitu.* - - -## 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 []`-k aukeratutako 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` *pickaxe* 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` + egoera indexera pasatu - - `--hard`: `--mixed` + egoera *working directory*ra pasatu, bertako - aldaketak zapalduz - - -## Reset eta checkout sakonki — III - -Grafikoki aztertuz. Repositorio hutsarekin hasita: - -![ ](img/reset-ex1.png) - -## Reset eta checkout sakonki — IV - -Fitxategi bat *indexera* gehitu: - -![ ](img/reset-ex2.png) - -## Reset eta checkout sakonki — V - -Fitxategia repositorioan idatzi: - -![ ](img/reset-ex3.png) - -## Reset eta checkout sakonki — VI - -Fitxategia aldatu: - -![ ](img/reset-ex4.png) - -## Reset eta checkout sakonki — VII - -Egoera *indexera* bidali: - -![ ](img/reset-ex5.png) - -## Reset eta checkout sakonki — VIII - -Commit berria gehitu: - -![ ](img/reset-ex6.png) - -## Reset eta checkout sakonki — IX - -Beste commit bat gehituta: - -![ ](img/reset-start.png) - -## Reset eta checkout sakonki — IX - -`--soft`: - -![ ](img/reset-soft.png) - -## Reset eta checkout sakonki — X - -`--mixed` (defektuz egiten da): - -![ ](img/reset-mixed.png) - -## Reset eta checkout sakonki — XI - -`--hard`: - -![ ](img/reset-hard.png) - -## Reset eta checkout sakonki — XII - -Hiru aukeraz aparte, `git reset`-i fitxategi bat sartu ahal zaio. - -Kasu horretan, lehenengo pausua (HEAD-a mugitzea) ezin da burutu[^head] baina -hurrengo pausuak arazo barik egin daitezke. Horrek funtzionamendu -interesgarriak ahalbidetzen ditu. - -- `git reset ` egiten denean, benetan - `git reset --mixed HEAD ` egiten da. - 1. ~~HEAD-a mugitu~~ - 2. Egoera indexean jarri - - Hau da: **Fitxategia indexetik atera** - -[^head]: HEADa ezin da erdizka mugitu, edo repositorio osorako mugitzen da edo - ez da mugitzen. - -## Reset eta checkout sakonki — XIII - -Grafikoki: - -![ ](img/reset-path1.png) - - -## Reset eta checkout sakonki — XIV - -Adibide konplexuago bat: `git reset -- ` - -1. HEAD-a ezin da mugitu -2. ``-k ``-en daukan egoera indexera sartzen da (`--mixed`). - -![ ](img/reset-path3.png){height=220px} - - -## Reset eta checkout sakonki — XV - -Ikusitakoa *squash* (commit batzuk bakarrean batu) egiteko erabili -daiteke[^rebase-interactive]. - -- `git reset --soft HEAD~` egitean HEADa atzera eraman daiteke, indexean - aldaketak mantenduz. `git commit` eginda, aldaketak repositorioan idatzi - daitezke, denak **commit bakarrean**. - -[^rebase-interactive]: Beste aukera `git rebase --interactive|-i` erabiltzea da - -## Reset eta checkout sakonki — XVI - -Grafikoki: - -![ ](img/reset-squash-r1.png) - -## Reset eta checkout sakonki — XVII - -HEADa mugitu aldaketak indexean mantenduz: - -![ ](img/reset-squash-r2.png) - -## Reset eta checkout sakonki — XIX - -Commit berria sartu aldaketa guztiekin batera eginda - -![ ](img/reset-squash-r3.png) - -## Reset eta checkout sakonki — XX - -`checkout` eta `reset` antzekoak dira, baina ez dira berdinak: - -- `git checkout`-ek ez du HEADa eraldatzen. HEAD erreferentzia non apuntatzen - duen aldatzen du, ez du azpian dagoen adarra aldatzen. - -- `git checkout ` eta `git reset --hard ` ia berdinak dira - baina `checkout`ek ez ditu aldaketak zuzenean zapaltzen. - -- `git checkout ` fitxategian zeuden aldaketak **zapaltzen ditu** - *working directory*an, `git reset --hard`en antzera. KONTUZ - -Bietan `--patch` erabili daiteke zatika egiteko. - - -## Reset eta checkout sakonki — XXI - -`git checkout` vs `git reset`en efektua HEADan: - -![ ](img/reset-checkout.png) - - - -## Merge aurreratuak, konfliktoen kudeaketa — I - -Mergeak egin baino lehen, ideia ona da *working directory*a garbitzea (`git -stash`), horrela, zeozer txarto badabil atzera buelta eman daiteke aldaketak -galdu barik. - -- `git merge --abort` mergea txarto doanean (konfliktoak) mergea ezeztatzen - du. - - > KONTUZ: aldaketak badaude *working directory*-an ezin izango da abortatu. - - -## Merge aurreratuak, konfliktoen kudeaketa — II - -Konfliktoetan Gitek 3 fitxategi ematen ditu: - -1. Stage 1: *common ancestor*-a (*base*), bi adarretatik iritsi daitekeen - lehengo commita: `git merge-base`-ekin lortu daiteke puntu hau -2. Stage 2: Gure (*ours*) bertsioa, gure adarrean dagoena -3. Stage 3: Haien (*theirs*) bertsioa, mergeatzen dugun adarrean dagoena - -- `git show ::` stage fitxategiak ikusteko - - `::`-k blob horren hasha lortzen du. - -- `git diff`-en bitartez ikusi daitezke, stage-a aukeratuz - - `git diff -1|--base` - - `git diff -2|--ours` - - `git diff -3|--theirs` - -## Merge aurreratuak, konfliktoen kudeaketa — III - -- `git show ::` eginez, stage bakoitzaren fitxategiak fitxategi - ezberdinetara idatzi daitezke eskuz prozesatzeko - -- `git merge-file` erabili daiteke hiru fitxategiak eskuz mergeatzeko. Merge - algoritmoak aplikatuko ditu - -## Merge aurreratuak, konfliktoen kudeaketa — IV - -Konfliktoak hobeto aztertzeko tresna batzuk: - -- `git checkout --conflict` konfliktoa daukan fitxategiaren konflikto - markadoreak berriro idazten ditu. Eskuz aldatzean nahi gabe ezabatu - ditugunean interesgarria da. - -- `git checkout --ours/--theirs` egin daiteke alde bat edo bestea ikusteko. - -- `git log --oneline --left-right --merge` interesgarria da testuingurua - ulertzeko. - -- `git diff` egitean konfliktoetan *combined diff* bat agertzen da, bi - zutabeetan ikusten dira aldaketak. - -- `git show -p|--patch` egitean `--cc` gehitu daiteke *combined diff*a ikusteko - - -## Merge aurreratuak, konfliktoen kudeaketa — V - -*Combined diff*-aren itxura, konflikto bat konpontzean: - -``` -diff --cc hello.rb -index 0399cd5,59727f0..0000000 ---- a/hello.rb -+++ b/hello.rb -@@@ -1,7 -1,7 +1,7 @@@ - #! /usr/bin/env ruby - - def hello -- puts 'hola world' - - puts 'hello mundo' -++ puts 'hola mundo' - end -``` - -Bi zutabe daude `-` eta `+` sinboloekin, alde bakoitzean zer gertatu den -ikusteko. - -## Merge aurreratuak, konfliktoen kudeaketa — VI - -Konfliktoetan `diff3` erabiltzea interesgarria izan daiteke, defektuz `merge` -erabiltzen da. Atal berri bat gehitzen dio konfliktoari, *base*a bistaratzeko. -``` -<<<<<<< ours - puts 'hola world' -||||||| base - puts 'hello world' -======= - puts 'hello mundo' ->>>>>>> theirs -``` - -- `git checkout --conflict=diff3` konfliktoa 3 stagetan bistaratzeko. - -- `git config --global merge.conflictstyle diff3` konfliktoak 3 bidetan - ikusteko - - -## Mergeak desegiten — I - -Bi aukera ezberdin dago mergea desegiteko: - -1. `git reset --hard HEAD~` (historikoa berridazten du) -2. `git revert -m 1 HEAD` commit bat gehitu aldaketak desegiten dituena. - Arazoak datoz adarra berriro mergeatu behar denean. - -## Mergeak desegiten — II - -`git revert -m 1 HEAD` egitean, mergea desegin da beste commit batekin. `^M` -eta `C6` eduki berdinak dituzte. Baina `topic` adarraren commitak `master`etik -iritsi daitezke. Gitentzat mergeatuta daudela dirudite. KONTUZ - -![](img/undomerge-revert.png) - -## Mergeak desegiten — III - -Txarragoa izan daitekeena, aldaketak gehitzen badira, Gitek commit berriak -baino ez ditu hartzen, bestea mergeatuta dagoela uste duelako. KONTUZ - -![](img/undomerge-revert2.png) - -## Mergeak desegiten — IV - -Arazoa saihesteko, aurreko mergea, desegin duguna, aplikatu behar da. -Horretarako, `revert` commita desegin daiteke beste `revert` bat eginez. - -![](img/undomerge-revert3.png) - -Orain, `topic`-en aldaketa guztiak `master`-en daude. - -## Mergeen preferentziak - -`git merge` aukera eta estrategia ezberdinak daude: - -- `-X` aukerak gehitzeko erabiltzen da. Adibidez: `-Xours` konfliktoak gure - aldera ebazteko - -- `-s` estrategiak gehitzeko. Adibidez: `-s ours` mergea egin beharrean, gure - aldeko aldaketak bakarrik aukeratu (Giti ziria sartzeko interesgarria da) - -Aukerak eta estrategiak ez dira gauza bera. Estrategiak merge algoritmoa -definitzen dute. Aukerek algoritmoa konfiguratzen dute. - -## Subtree-ak - -Subtree-ak beste proiektu bat gure proiektuaren barruan sartzeko mekanismo bat -dira. Azpiproiektua adar independente batean kudeatzen da: beste remote bat -moduan hasierazten da, baina adar berri batean sartu, beste adarrekin -zerikusirik ez duena. - -- `git read-tree` azpiproiektua irakurri eta beste adar baten azpidirektorio - moduan hasiarazteko -- `git merge -Xsubtree` erabiltzen da *subtree*aren adarra proiektuan - arazo barik mergeatzeko -- `git diff-tree` azpiproiektuaren aldaketak aztertzeko, `diff` normal bat ez - dabil - -*Ez da asko erabiltzen, *Submodule*ak gehiago erabiltzen dira. Gehiago ikasteko, -liburua irakurri.* - -## Rerere: Reuse Recorded Resolution — I - -Konfliktoak nola konpondu ditugun erregistratzeko sistema bat da, gero Gitek -konfliktoak automatikoki ebazteko kriterio berdina erabiltzen. Adibide baten -bitartez: - -1. Testing adarra mergeatzen konfliktoak daude -2. Konfliktoak konpontzen dira -3. Testak txarto doaz -4. Mergea desegin behar da -5. Testak konpondu behar dira -6. Mergea berriro egin => konflikto berdinak berriro konpondu behar dira - -`rerere`-ren bitartez lehenengo mergearen konfliktoen ebazpena gorde daiteke. -Horrela, mergea berriro aplikatzerakoan ez da konfliktoa berriro ebatzi behar, -automatikoki aurretik gordetako ebazpena erabiltzen delako. - -## Rerere: Reuse Recorded Resolution — II - -- `git config --global rerere.enabled true` -- `git rerere status` *rerere*ren egoera ikusteko -- `git rerere diff` *rerere*k aplikatuko lituzken aldaketak ikusteko -- `git add` + `git commit` egiterakoan ebazpena gordetzen da: - `"Recorded resolution"` -- `git reset --hard HEAD^` eta mergea berriro egiterakoan konfliktoak - automatikoki konpontzen dira: - `"Resolved with previous resolution"` -- `git checkout --conflict=merge ` eginda konfliktoa berreskuratu - daiteke, `rerere`a aktibatu gabe -- `git rerere` egiten berriro mergeatu daiteke automatikoki - - -## Gitekin debuggeatzen - -- `git blame` fitxategi baten aldaketak zein commitean sartu diren ikusi - daiteke. `^`-ekin hasten diren lerroak hasieratik aldatu gabeko lerroak dira. - `-C` aukerarekin mugitutako zatiak aurkitu daitezke[^move] - -[^move]: Gitek ez ditu mugimenduak gordetzen baina fitxategien zatiak aztertu - eta mugimenduak kalkulatu ditzake - -- `git bisect` [bisekzio metodoa][bisect] erabiliz errorea sartu zuen commita - aurkitzeko tresna oso interesgarria. Metodoa: - - Bi commit hartu: bat erroreduna eta bestea errore gabea - - Erdiko puntuan commit bat hartu: errorea badauka, errorea sartu zuen - commita commit honen eta errore gabeko commitaren artean dago. Errorea ez - badago, commit honen artean eta commit erroredunaren artean dago. - - Beste puntu bat hartu eta jarraitu tartea txikitzen commita aurkitzen den - arte. - -[bisect]: https://en.wikipedia.org/wiki/Bisection_method - - -## Gitekin debuggeatzen: `git bisect` - -Bisekzio metodoa aplikatzeko workflowa - -1. `git bisect start` bisekzio metodoa hasi -2. `git bisect bad` oraingo commita txarra da -3. `git bisect good ` commit hau ona da -4. `git bisect good/bad` oraingo commita ona edo txarra da. Gitek - hurrengo commita aukeratzen du: - `"Bisecting, N revisions left to test"` -5. `git bisect reset` hasierara bueltatu - -Automatizatu daiteke: `git bisect run ` - -- Komandoak `0` bueltatu behar du testa ondo badoa eta beste edozer errorea - badago - - -## Submoduluak - -Gure proiektuaren barruan azpiproiektuak kudeatzeko modu bat da. - -- `git submodule add ` azpiproiekturako karpeta berri bat gehitzen du eta - `.gitmodules` fitxategia hasieratzen du -- `.gitmodules` fitxategian azpiproiektuen informazioa gordetzen da: URLa, - izena eta path-a. -- `git submodule add ...` eta gero `git diff --cached` egitean ikusten da - submoduluen path-a ez dela fitxategi bezala kudeatzen: - `"Subproject commit ---"` -- `git diff --submodule --cached`-ekin hobeto ikusten da -- `git push` egiterakoan submodule-aren direktorioa erreferentzia moduan - pusheatzen da. - -## Submoduluak klonatzeko - -- `git clone`-ek **ez** ditu proiektuen submoduluak deskargatzen -- `git submodule init` submoduluen kontrola hasieratzeko -- `git submodule update` submoduluen fitxategiak berrizteko -- `git clone --recurse-submodule ` zuzenean submodule guztiak - deskargatzeko `clone` egiterakoan. Bestela `git submodule update --init` edo - `git submodule update --init --recursive` egin daiteke klonatu eta gero - -## Submoduluekin lanean - -- `git diff --submodule` ez egiteko `git config --global diff.submodule log` - egin daiteke eta zuzenean submoduluaren diffa ikusi daiteke `git diff` - egitean -- `git submodule update --remote ` submoduluen edukiak berrizteko - edo bestela submoduluaren barruan `fetch`+`merge` egin daiteke. -- `git config -f .gitmodules submodule..branch ` adarrez - aldatzeko, edo fitxategia zuzenean aldatu -- `git config status.submodulesummary 1` egitean `git status`-ek submoduluen - egoera bistaratuko du -- `git log --submodule` submoduluen aldaketak ikusteko - -## Submoduluak dituen proiektua berrizteko - -- `git pull` ez ditu submoduluak berritzen, informazioa baino ez du - deskargatzen. -- `git submodule update` aplikatu behar da, `--init`-ekin submodule berriak - gehitu badira, hauek gehitzeko eta `--recursive`, submoduluek submoduluak - badituzte. -- `git pull --recurse-submodules`-k efektu berdina dauka. Konfiguratu daiteke - automatikoki egiteko. -- `git submodule sync` egin behar da URLak aldatu badira. - -## Submoduluetan lanean - -Normalean ez da submoduluetan idazten, baina egin daiteke. - -- `git submodule update`-k azpirepositorioa *detached head* egoeran uzten du. - Bertak commitak gehitzean galduko lirateke (ez dago adarrik commitetara - ailegatzeko). Hau konpontzeko: - - 1. Adarrak konfiguratu behar dira: `cd && git checkout ` - 2. `git submodule update --remote --merge/--rebase` egin behar da *detached - head* egoeran ez gelditzeko. Submoduluan aldaketak badaude, konfliktoa - egon daiteke. - -## Submoduluen lana publikatzen - -- `git push` egin daiteke submodulu bakoitzean, Git repositorio normalak - baitira -- `git push --recurse-submodules=check/on-demand` bi estrategia dago. `check` - aldaketak pusheatu behar diren begiratzen du, eta `on-demand`-ek pusha egiten - du submodulu bakoitzean aldaketak badaude - - `git config push.recurseSubmodules check/on-demand` estrategia defektuz - konfiguratzeko - -## Submoduluen trukoak - -- `git submodule foreach ` egin daiteke submodule bakoitzean komando - bat executatzeko. Adibidez: `git submodule foreach 'git stash'` - -## Bundle - -Bundle-ak commitak edo repositorio osoak fitxategi baten bidez partekatzeko -sistema dira. - -- `git bundle create []` aukeratutako commitak (edo - guztiak) `` fitxategian gorde, bundle formatoan. Normalean, `HEAD` - sartzea komeni da, gero bundle-a kargatzean repositorioa non zegoen jakiteko. - -- `git clone ` bundle fitxategitik clone bat egiteko. Bundle-a - repositorio osoa izan behar du. - -- `git bundle verify ` bundle partzial bat repositorio batean - aplikatu daitekeen konprobatzeko - -- `git bundle list-heads ` bundle fitxategiaren adarrak ikusteko - -- `git fetch/pull ` bundle fitxategitik repositorioa - berriztatzeko - -## Replace - -Giten datu basea orokorrean ezin da aldatu, baina `git replace`-en bitartez -*replace* objektuak eratu daitezke, datu basea aldatu denaren itxura emango -dutenak. - -- `git replace ` aplikatzetik aurrera, `` - erabiltzean `` erabili balitz bezala funtzionatuko du - -*Erabileren adibide bat ikusteko liburuan ikusi, nahiko arraroa da hau ikustea* - -## Kredentzial sistema - -HTTP kredentziala erabiltzean, zerbitzariarekin egiten diren interakzio -guztietan erabiltzailea eta pasahitza eskatzen du Gitek defektuz. -Portaera konfiguratu daiteke: - -- `git config --global credential.helper ` - 1. Beti eskatu (defektuz egiten dena) - 2. `cache` kredentzialak memorian mantendu 15 minutu - 3. `store` kredentzialak gorde - -Aukera gehiago dago (`--timeout`, neurrira egindako kredentzial sistemak, -etab.). *Interesa balego, liburuan begiratu* - -# Git konfigurazio aurreratua - -## Git konfigurazioa - -Konfigurazioaren dokumentazioa ikusteko `git help git-config`. Atal -interesgarrienak: - -- Editorea eta paginadorea: `core.editor` eta `core.pager` -- Commit mezuen txantiloia: `commit.template` -- Merge eta diff tresnak: `merge.tool` eta `diff.tool` -- Espazio hutsen kontrola: `core.autocrlf` eta `core.whitespace` - -## Git attribute-ak — I - -Proiektuen barruan, fitxategi mailan, Giten portaera aldatzeko erabiltzen dira -atributuak (*attribute*). - -- `.gitattributes` fitxategian edo `.git/info/attributes` fitxategian, - repositorioarekin partekatu nahi ezbadira. - -Atributu fitxategia `.gitignore` fitxategiaren antzekoa da, baina lerro -bakoitzean fitxategien izenen txantiloiaz aparte haien atributuak definitu -behar dira. Askotan konfigurazio gehigarria behar da, *driver* programak -definitzeko. Ikusi `git help attributes`. - -## Git attribute-ak — II - -Atributu mota asko dago, interesgarrienetarikoak: - -- `binary` fitxategiak binario moduan identifikatzeko -- `diff=` diff-a exekutatu baino lehen fitxategiak iragazki batetik - pasatzeko. Konfigurazio gehigarria behar da: - - `git config diff..textconv ` - - Adibidez: `*.png diff=exif` - - `git config diff.exif.textconv exiftool` - png fitxategien estatistikak konparatzen dira, eta ez edukiak -- `ident` identifikazioa gehitzeko. `$Id$` testu literala SHA-1era bihurtzen da - espantsio baten bitartez - -## Git attribute-ak — III - -- `filter` fitxategiak iragazki batekin prozesatzeko - - `smudge` *index*etik *working directory*rako bidean - - `clean` *working directory*tik *index*erako bidean - - Adibidez: `*.c filter=indent` - - `git config filter.indent.clean indent` - `git config filter.indent.smudge cat` - fitxategiak automatikoki indentatzeko `git add` egiterakoan -- `export-ignore` artxibo (`git archive`) bat egiterakoan fitxategi batzuk - baztertzeko. -- `export-subst` artxibo bat egiterakoan `git log`-ek aplikatzen dituen - espantsioak aplikatzeko -- `merge` merge estrategiak aukeratzeko - - -## Git hooks - -Hookak gertaera garrantzitsuak gertatzen direnean exekutatzen diren programak -dira. Askotan erabiltzen dira. - -- `.git/hooks` direktorioan idazten dira, izen konkretu batekin eta exekuzio - baimenekin - -Defektuz, `git init` egiterakoan hook batzuk idazten dira, baina desaktibatuta -daude (haien izena `.sample`-n bukatzen delako). Erreferentzia moduan hartu -daitezke haien funtzionamendua ulertzeko. - - -## Bezero aldeko hookak - -Bakoitzarentzako bakarrik. **Ez dira kopiatzen repositorioarekin -batera**[^hookak-partekatu]. -Interesgarriak dira garatzaileei alertak botatzeko: testak ez direla pasatu, -formaturen bat txarto dagoela adierazteko, etab. Interesgarri batzuk: - -- `pre-commit` commit mezua idatzi baino lehen exekutatzen da, zeozer ahaztu - den konprobatzeko erabili ohi da -- `prepare-commit-msg` defektuzko commit mezua aldatzeko erabiltzaileak ikusi - baino lehen. Informazio gehigarriak sartu ahal zaio horrela, edo txantiloia - aldatu... -- `commit-msg` commit mezua aztertzen duen hooka. Txarto badago commita atzera - bota dezake. Normalean commitaren mezua txantiloi konkretu bat jarraitzeko - erabiltzen da. - -[^hookak-partekatu]: Tresna batzuek mekanismoak dauzkate hook hauek - partekatzeko, baina hau ez da Giten defektuzko funtzionamendua. Kontuz - workflow guztia honetan oinarritzearekin. - -## Zerbitzari aldeko hookak - -Politikak inposatzeko aproposak dira, txarto badoaz `push` egiteko eskaerak -atzera bota ditzaketelako. Interesgarri batzuk: - -- `pre-receive` push bat jasotzean erreferentzia guztiak jasotzen dituen - programa, errorea ematen badu ez da ezer berriztuko. -- `update` aurrekoaren antzekoa da, baina behin exekutatzen da adar bakoitzeko -- `post-receive` dena ondo jaso eta gero exekutatzen da, notifikazio moduan - erabili daiteke - - -# Git barrutik - -## Git barrutik: Sarrera - -Git maila baxuko tresna bat da, eta maila horretan lan egiteko komandoak ditu, -*plumbing* deiturikoak. Orain arte erabilitakoak *porcelain* deitzen dira, -maila altuan lan egiten dutelako. - -Git *content-addressing* aplikatzen duen datu base bat da, hau da, *Key-Value* -moduan gordetzen dira elementuak, non Key-a Valuaren edukiaren araberakoa den. -Orain arte ikusi da: elementuak haien edukiaren SHA-1 hasharen bitartez -identifikatzen dira. - -Eduki guzti hau `.git` karpetan gordetzen da. Baina elementu mota ezberdinak -daude. - -## Giten gordetzen diren elementu motak - -Bi elementu mota nagusiak daude Git datu basean: - -- Objektuak: edukiak dauzkaten elementuak dira: commitak, blobak, zuhaitzak, - etab -- Erreferentziak: beste elementuei apuntatzen duten elementuak dira: adarrak, - lightweight tagak, etab - - -## Objektuak - -`.git/objects`-en gordetzen dira, haien hasharen arabera. Lehengo bi -karaktereak direktorio moduan eta hurrengoak fitxategi moduan. -Adibidez: `.git/objects/cf/6cbb8a400c7cad0f7f93610366c3672f598cdd` - -- `git hash-object -w`-rekin idatzi daitezke (bueltan hash-a ematen du) -- `git cat-file`-ekin irakurri daitezke. `-p` egin emaitza **p**olita ikusteko. - -## Objektu motak - -`git cat-file -t`-rekin mota ikusi daiteke. - -- `blob`-ak fitxategien edukiak eta bestelako datuak gordetzeko -- `tree` fitxategien izenak eta direktorioak gordetzeko - Sarrera bat edo gehiago dute beste `tree` edo `blob`etara haien izena eta - hasha identifikatuz. -- `commit` commit datuak gordetzeko: `tree` bat snapshotarekin, mezua, autorea, - etab. - -## Objektu motak: tree - -![](img/data-model-1.png) - -## Objektu motak: commit - -![](img/data-model-3.png) - -## Erreferentziak - -Haien barruan identifikadore bat baino ez dago. - -- `git update-ref` edukia aldatzeko. Eskuz ere egin daiteke. - -Erreferentzia mota ezberdinak daude: - -- Tag-ak: `.git/refs/tag` karpetan. Edozein objetu tageatu - daiteke (normalean commitak). Bi mota dago: - - Lightweight tag: erreferentzia bat baino ez dira - - Annotated tag: tag *objektu* bat eratzen dute eta erreferentzia bat - idazten dute bertara -- Adarrak: `.git/refs/heads` karpetan. Commit-id batera erreferentzia - egiten dute. -- Remote-ak: `.git/refs/remotes` karpetan. Adarren antzerakoak baina ezin dira - aldatu. -- HEAD-a: `.git/HEAD`-en dago. Adar batera apuntatzen du, baina batzutan commit - batera apuntatu dezake (*Detached HEAD*). - -## Erreferentziak: adarrak - -![](img/data-model-4.png) - -## Ariketa: Notak - -- `git notes` komandoarekin kudeatzen dira. - -*Aztertu zer diren eta nola funtzionatzen duten. Ikusi `git help git-notes`* - -## Packfile-ak - -Datuen egitura efizienteagoa egiteko Gitek fitxategiak konprimatzen ditu, baina -hori ez da normalean nahikoa izaten. - -Git snapshotetan oinarritzen da, baina ez ditu fitxategi osoak behin eta -berriro idazten commit bakoitzean, aldaketak baino ez ditu gordetzen. - -Gainera fitxategiak taldekatu eta *packfile* deituriko fitxategietan gordetzen -ditu prozesua arintzeko. - -- `.git/objects/pack`-en ikusi daitezke -- `git gc` (*garbage collector*) fitxategiak taldekatu eta konprimatzeko (berak - bakarrik exekutatzen du beharrezkoa ikusten duenean) -- `git verify-pack` *packfile* baten edukia aztertzeko eta egiaztatzeko - -## Mantenamendua eta datuak berreskuratzea - -- `git gc --auto`-k packfileak berrorganizatzen ditu. -- `git reflog`-en HEAD-ean egindako aldaketak gordetzen dira, beraz commiten - bat galdu bada bertara salto egin daiteke, `reflog`a begiratu eta commita - berreskuratu daiteke. -- `git fsck --full` galdutako elementuak erakusten ditu, bertatik ere - datuak berreskuratu daitezke - -*ARIKETA: Fitxategi handiak nahi gabe gehitzea arazo bat da, `git rm`-k ez -dituelako ezabatzen. Nola egiten da? Zergatik?* - -## Refspec-a - -Lokalaren eta remotearen arteko adarren mapeoa kudeatzeko. `.git/config`-en -edukia `git remote add origin https://github.com/schacon/simplegit-progit` egin -eta gero: - -``` -[remote "origin"] - url = https://github.com/schacon/simplegit-progit - fetch = +refs/heads/*:refs/remotes/origin/* -``` - -`fetch` atalak **refspec** baten bitartez adarrak nola kudeatu behar diren -adierazten du. Sarrera asko egon daitezke arau ezberdinekin. Formatua: - -- Aukerako `+` bat *fast forward* ez direnean ere berrizteko -- `:` nola mapeatu behar diren adierazteko. `` - eta `` patroiak dira (`*`) - -## Refspec-a eskuz erabiltzen - -`git fetch/push` egitean refspec patroia (1 edo +) gehitu ahal da *"hau hona"* -eta *"beste hau hona"* esateko. - -Refspec-a ikusita, Gitek adarren adierazpenaren espantsioa egiten du: - -- `git log origin/master` - => `git log remotes/origin/master` - => `git log refs/remotes/origin/master` - -Adarrak ezabatzeko lehen refspec-a erabili behar zen: - -- `git push :` iturri atala utzik uztean, remotean adarra ezabatzen zen -- Orain `git push --delete ` egin daiteke - diff --git a/README.md b/README.md new file mode 100644 index 0000000..b2ce3ca --- /dev/null +++ b/README.md @@ -0,0 +1,12 @@ +# Git course + +Translations for several languages are provided. Each of them has a different +folder: + +- `eu`: the original, in Basque +- `es`: Spanish translation + +Each of the files has a note in the metadata indicating how to build it to PDF. +They expect to be run from the project root folder. + +> NOTE: This might be automated in the future diff --git a/eu/1.md b/eu/1.md new file mode 100644 index 0000000..a33f883 --- /dev/null +++ b/eu/1.md @@ -0,0 +1,606 @@ +--- +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 +- Integritate kontrola egiten du SHA-1 erabiliz +- Hiru egoera: + `FITXATEGIA — STAGING AREA — REPOSITORIOA` + +## Instalazioa + +Debian-en oinarritutako distribuzioetan: + +``` +apt-get install git +``` + +Beste distribuzioetan antzeko komandoren batekin egin daiteke. + + +## Konfigurazio sistema + +- Sistema mailakoa: `/etc/gitconfig` +- Konfigurazio orokorra: `~/.config/git/config` edo `~/.gitconfig` +- Konfigurazio lokala. Repositorio bakoitzeko: `$REPOSITORIOA/.git/config` + +Kaskada moduan dabil, konfigurazio lokalak orokorra 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 [] +``` + +- `` 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 aukeratu: + +``` +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) + +`diff` komandoaren irteera fitxategi batean gorde eta gero, beste norbaiti +pasatu ahal zaio, berak bere repositoriaren kopian `git apply` erabiliz +aplikatzeko. + +## 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 mugatu daiteke, eskaerak eginez: + +- `--since` noiztik ikusi nahi diren. Adibidez: `--since=2weeks`. +- `--author` autorez iragazi. +- `--grep` commit mezuan *keyword*ak bilatzeko. +- `-S/-G/...` *pickaxe function* deiturikoak, aldaketetan testua bilatzen dute. +- `git log -- fitxategia` fitxategi horretan gertatutako aldaketak bakarrik + atera. +- `--no-merges` merge commitak baztertu. + +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`-ek informazioa deskargatu eta `merge`atzen du adarrak ondo + konfiguratuta badaude: + ``` + git pull = git fetch + git merge + ``` + +- `git push [ ]`-ek 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**: erreferentzia bat dira. Adar finko baten modukoak +- **Annotated**: Git-en datu basean objektu 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 komando 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* objektu moduan eta haien checksuma kalkulatzen du (SHA-1) +- Commita egiterakoan direktorio bakoitzaren checksuma kalkulatzen du eta + *tree* objektu bat gordetzen du direktorio bakoitzeko. *Tree* objektuek + *blob* objektuetara apuntatzen duten erreferentziak dituzte. Gainera commitek + beste datuak gordetzen dituzte: autorea, mezua, data... +- Commitek haien gurasoei apuntatzen duten erreferentziak dituzte: + lehengo commitek erreferentziarik ez dute, commit normalek erreferentzia + bakarra dute eta *merge* commitek erreferentzia asko dituzte. + +Adarrak commitetara apuntatzen duten erreferentzia 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 bertara aldatzeko + +Bertsio berrietan, `checkout` komandoak 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.png){ 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.png){ 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.png){ height=180px } + +## Konfliktoak — I + +Aurreko kasua ez da beti ondo ateratzen, batzuetan 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 errazago 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 -u|--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 + +Gitek remoten erreferentziak gordetzen ditu remoten egoera ikusi ahal izateko. +`git ls-remote ` edo `git remote show ` erabiliz remoteen +egorea ikusi daiteke. + +Remoten adarrak lokalean ikusi daitezke `/` izenarekin. Ezin +dira aldatu. Push egiterakoan aldatzen dira, remotearen egoera aldatu delako. + +![Adibidea: repositorio lokalak bi commit berri ditu](img/remote-branches.png) + +## Push egitea + +- `git push ` adarra remotera pusheatzeko. Eskuz egin behar + da. Horrela adar lokalak babesten dira eta ez dira automatikoki igotzen. + +- `:` erabiltzean izen ezberdinak jarri ahal zaizkie + adarrei, bata lokalean eta bestea remotean + +## Tracking branches + +Remoteak jarraitzeko erabiltzen mekanismoa da. Remotearen adar bat (*upstream*) +adar lokal baten (*tracking*) arteko erlazioa da. + +- `git checkout -b /`-k `/` + `` izenarekin *track*eatzen du +- `git checkout --track /` oraingo adarra eta remotearena + erlazionatu. Sinpleago. +- `git checkout `-k erlazioa eratzen du automatikoki, `` + lokalean existitzen ez bada. Sinpleago. +- `git clone` egiterakoan `master` adar lokala eratzen da `origin/master` + adarra *track*eatzen. +- `git branch -u|--set-upstream-to /` zure adarraren upstream-a + aldatzeko. Ikusi `git push`-en. + +> `@{upstream}` edo `@{u}` idatzi daiteke hortik aurrera remotearen adarraren +> izen osoa erabili beharrean + +## Pull egitea + +Tracking adarra aktibatuta badago, `git pull` egiteak zuzenean `git fetch` eta +`git merge` aldi berean egingo ditu. + +Kontuz ibili: batzuetan `git pull`-en magia ulertzeko zaila izan daiteke. +Proiektua jende askok ukitzen badu, hobe `git fetch` egitea. + +## Adarrak eta rebaseak — I + +![](img/basic-rebase-1.png) + +## Adarrak eta rebaseak — II + +![`git merge` egitean gertatzen dena](img/basic-rebase-2.png) + +## Adarrak eta rebaseak — II + +![`git checkout experiment` +`git rebase master`](img/basic-rebase-3.png) + +Orain merge-a *fast-forward* izango da eta ez du merge commit-ik gehituko. + +## Rebase konplexuago bat — I + +![](img/interesting-rebase-1.png) + +## Rebase konplexuago bat — II + +![`git rebase --onto master server client`](img/interesting-rebase-2.png) + +`client`-en dauden aldaketak pasatzen ditu `master`-era `server`-en daudenak +izan ezik. + +Orain `server` `master`-en rebaseatu daiteke eta gero `git merge` +*fast-forward* bat egin. + +## Rebasekin kontuz ibili + +Rebaseak egiterakoan commit berriak egiten dira, aurrekoen antzekoak edukiz, ez +dira berdinak. Remote-an pusheatzerakoan beste lankideek rebaseak egitera +behartzen ditu: + +- `git push --force` remotean historia berridazten du. Git zerbitzuetan adar + babestuak existitzen dira hau saihesteko. Kontuz. +- `git pull --rebase`-k lagundu dezake `pull` egiterakoan, remotean historia + berridatzi bada. Pull-en estrategietako bat da, asko daude eta defektuz + egiteko konfiguratu daitezke. + +## Rebase vs Merge + +Filosofiaren arabera bata edo bestea gehiago erabiltzea komeni da: + +- Repositorioa historiko moduan ulertuta: rebase egitea txarra izango + litzateke, historikoa zapaltzen baitu. (*fossil-ek filosofia hau jarraitzen + du, ez dauka rebase egiteko tresnarik*) +- Repositorioa *making of* modura ikusten bada aproposa da rebase egitea. + Historikoa garbiagoa uzten duelako. + +Aholkua: lokalean rebase egin commit historikoa garbitzeko baina behin +zerbitzarira igota historia ez aldatu, lankideen prozesuan eragina baitu. + diff --git a/eu/2.md b/eu/2.md new file mode 100644 index 0000000..a4e64d1 --- /dev/null +++ b/eu/2.md @@ -0,0 +1,1026 @@ +--- +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 asko commit askotan aplikatu daitezke. Gitek commit selektore +ezberdinak aplikatzea ahalbidetzen du commitak aukeratzeko. + +- `git show ` aukeratutako objektuak erakusteko + +*Ikusi `git show`-n laguntza. Objetu ezberdinak erakutsi ditzake* + +*Ikusi `git rev-parse`-n laguntza, selektoreen sintaxia azaltzen baitu.* + + +## 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 []`-k aukeratutako 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` *pickaxe* 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` + egoera indexera pasatu + - `--hard`: `--mixed` + egoera *working directory*ra pasatu, bertako + aldaketak zapalduz + + +## Reset eta checkout sakonki — III + +Grafikoki aztertuz. Repositorio hutsarekin hasita: + +![ ](img/reset-ex1.png) + +## Reset eta checkout sakonki — IV + +Fitxategi bat *indexera* gehitu: + +![ ](img/reset-ex2.png) + +## Reset eta checkout sakonki — V + +Fitxategia repositorioan idatzi: + +![ ](img/reset-ex3.png) + +## Reset eta checkout sakonki — VI + +Fitxategia aldatu: + +![ ](img/reset-ex4.png) + +## Reset eta checkout sakonki — VII + +Egoera *indexera* bidali: + +![ ](img/reset-ex5.png) + +## Reset eta checkout sakonki — VIII + +Commit berria gehitu: + +![ ](img/reset-ex6.png) + +## Reset eta checkout sakonki — IX + +Beste commit bat gehituta: + +![ ](img/reset-start.png) + +## Reset eta checkout sakonki — IX + +`--soft`: + +![ ](img/reset-soft.png) + +## Reset eta checkout sakonki — X + +`--mixed` (defektuz egiten da): + +![ ](img/reset-mixed.png) + +## Reset eta checkout sakonki — XI + +`--hard`: + +![ ](img/reset-hard.png) + +## Reset eta checkout sakonki — XII + +Hiru aukeraz aparte, `git reset`-i fitxategi bat sartu ahal zaio. + +Kasu horretan, lehenengo pausua (HEAD-a mugitzea) ezin da burutu[^head] baina +hurrengo pausuak arazo barik egin daitezke. Horrek funtzionamendu +interesgarriak ahalbidetzen ditu. + +- `git reset ` egiten denean, benetan + `git reset --mixed HEAD ` egiten da. + 1. ~~HEAD-a mugitu~~ + 2. Egoera indexean jarri + + Hau da: **Fitxategia indexetik atera** + +[^head]: HEADa ezin da erdizka mugitu, edo repositorio osorako mugitzen da edo + ez da mugitzen. + +## Reset eta checkout sakonki — XIII + +Grafikoki: + +![ ](img/reset-path1.png) + + +## Reset eta checkout sakonki — XIV + +Adibide konplexuago bat: `git reset -- ` + +1. HEAD-a ezin da mugitu +2. ``-k ``-en daukan egoera indexera sartzen da (`--mixed`). + +![ ](img/reset-path3.png){height=220px} + + +## Reset eta checkout sakonki — XV + +Ikusitakoa *squash* (commit batzuk bakarrean batu) egiteko erabili +daiteke[^rebase-interactive]. + +- `git reset --soft HEAD~` egitean HEADa atzera eraman daiteke, indexean + aldaketak mantenduz. `git commit` eginda, aldaketak repositorioan idatzi + daitezke, denak **commit bakarrean**. + +[^rebase-interactive]: Beste aukera `git rebase --interactive|-i` erabiltzea da + +## Reset eta checkout sakonki — XVI + +Grafikoki: + +![ ](img/reset-squash-r1.png) + +## Reset eta checkout sakonki — XVII + +HEADa mugitu aldaketak indexean mantenduz: + +![ ](img/reset-squash-r2.png) + +## Reset eta checkout sakonki — XIX + +Commit berria sartu aldaketa guztiekin batera eginda + +![ ](img/reset-squash-r3.png) + +## Reset eta checkout sakonki — XX + +`checkout` eta `reset` antzekoak dira, baina ez dira berdinak: + +- `git checkout`-ek ez du HEADa eraldatzen. HEAD erreferentzia non apuntatzen + duen aldatzen du, ez du azpian dagoen adarra aldatzen. + +- `git checkout ` eta `git reset --hard ` ia berdinak dira + baina `checkout`ek ez ditu aldaketak zuzenean zapaltzen. + +- `git checkout ` fitxategian zeuden aldaketak **zapaltzen ditu** + *working directory*an, `git reset --hard`en antzera. KONTUZ + +Bietan `--patch` erabili daiteke zatika egiteko. + + +## Reset eta checkout sakonki — XXI + +`git checkout` vs `git reset`en efektua HEADan: + +![ ](img/reset-checkout.png) + + + +## Merge aurreratuak, konfliktoen kudeaketa — I + +Mergeak egin baino lehen, ideia ona da *working directory*a garbitzea (`git +stash`), horrela, zeozer txarto badabil atzera buelta eman daiteke aldaketak +galdu barik. + +- `git merge --abort` mergea txarto doanean (konfliktoak) mergea ezeztatzen + du. + + > KONTUZ: aldaketak badaude *working directory*-an ezin izango da abortatu. + + +## Merge aurreratuak, konfliktoen kudeaketa — II + +Konfliktoetan Gitek 3 fitxategi ematen ditu: + +1. Stage 1: *common ancestor*-a (*base*), bi adarretatik iritsi daitekeen + lehengo commita: `git merge-base`-ekin lortu daiteke puntu hau +2. Stage 2: Gure (*ours*) bertsioa, gure adarrean dagoena +3. Stage 3: Haien (*theirs*) bertsioa, mergeatzen dugun adarrean dagoena + +- `git show ::` stage fitxategiak ikusteko + - `::`-k blob horren hasha lortzen du. + +- `git diff`-en bitartez ikusi daitezke, stage-a aukeratuz + - `git diff -1|--base` + - `git diff -2|--ours` + - `git diff -3|--theirs` + +## Merge aurreratuak, konfliktoen kudeaketa — III + +- `git show ::` eginez, stage bakoitzaren fitxategiak fitxategi + ezberdinetara idatzi daitezke eskuz prozesatzeko + +- `git merge-file` erabili daiteke hiru fitxategiak eskuz mergeatzeko. Merge + algoritmoak aplikatuko ditu + +## Merge aurreratuak, konfliktoen kudeaketa — IV + +Konfliktoak hobeto aztertzeko tresna batzuk: + +- `git checkout --conflict` konfliktoa daukan fitxategiaren konflikto + markadoreak berriro idazten ditu. Eskuz aldatzean nahi gabe ezabatu + ditugunean interesgarria da. + +- `git checkout --ours/--theirs` egin daiteke alde bat edo bestea ikusteko. + +- `git log --oneline --left-right --merge` interesgarria da testuingurua + ulertzeko. + +- `git diff` egitean konfliktoetan *combined diff* bat agertzen da, bi + zutabeetan ikusten dira aldaketak. + +- `git show -p|--patch` egitean `--cc` gehitu daiteke *combined diff*a ikusteko + + +## Merge aurreratuak, konfliktoen kudeaketa — V + +*Combined diff*-aren itxura, konflikto bat konpontzean: + +``` +diff --cc hello.rb +index 0399cd5,59727f0..0000000 +--- a/hello.rb ++++ b/hello.rb +@@@ -1,7 -1,7 +1,7 @@@ + #! /usr/bin/env ruby + + def hello +- puts 'hola world' + - puts 'hello mundo' +++ puts 'hola mundo' + end +``` + +Bi zutabe daude `-` eta `+` sinboloekin, alde bakoitzean zer gertatu den +ikusteko. + +## Merge aurreratuak, konfliktoen kudeaketa — VI + +Konfliktoetan `diff3` erabiltzea interesgarria izan daiteke, defektuz `merge` +erabiltzen da. Atal berri bat gehitzen dio konfliktoari, *base*a bistaratzeko. +``` +<<<<<<< ours + puts 'hola world' +||||||| base + puts 'hello world' +======= + puts 'hello mundo' +>>>>>>> theirs +``` + +- `git checkout --conflict=diff3` konfliktoa 3 stagetan bistaratzeko. + +- `git config --global merge.conflictstyle diff3` konfliktoak 3 bidetan + ikusteko + + +## Mergeak desegiten — I + +Bi aukera ezberdin dago mergea desegiteko: + +1. `git reset --hard HEAD~` (historikoa berridazten du) +2. `git revert -m 1 HEAD` commit bat gehitu aldaketak desegiten dituena. + Arazoak datoz adarra berriro mergeatu behar denean. + +## Mergeak desegiten — II + +`git revert -m 1 HEAD` egitean, mergea desegin da beste commit batekin. `^M` +eta `C6` eduki berdinak dituzte. Baina `topic` adarraren commitak `master`etik +iritsi daitezke. Gitentzat mergeatuta daudela dirudite. KONTUZ + +![](img/undomerge-revert.png) + +## Mergeak desegiten — III + +Txarragoa izan daitekeena, aldaketak gehitzen badira, Gitek commit berriak +baino ez ditu hartzen, bestea mergeatuta dagoela uste duelako. KONTUZ + +![](img/undomerge-revert2.png) + +## Mergeak desegiten — IV + +Arazoa saihesteko, aurreko mergea, desegin duguna, aplikatu behar da. +Horretarako, `revert` commita desegin daiteke beste `revert` bat eginez. + +![](img/undomerge-revert3.png) + +Orain, `topic`-en aldaketa guztiak `master`-en daude. + +## Mergeen preferentziak + +`git merge` aukera eta estrategia ezberdinak daude: + +- `-X` aukerak gehitzeko erabiltzen da. Adibidez: `-Xours` konfliktoak gure + aldera ebazteko + +- `-s` estrategiak gehitzeko. Adibidez: `-s ours` mergea egin beharrean, gure + aldeko aldaketak bakarrik aukeratu (Giti ziria sartzeko interesgarria da) + +Aukerak eta estrategiak ez dira gauza bera. Estrategiak merge algoritmoa +definitzen dute. Aukerek algoritmoa konfiguratzen dute. + +## Subtree-ak + +Subtree-ak beste proiektu bat gure proiektuaren barruan sartzeko mekanismo bat +dira. Azpiproiektua adar independente batean kudeatzen da: beste remote bat +moduan hasierazten da, baina adar berri batean sartu, beste adarrekin +zerikusirik ez duena. + +- `git read-tree` azpiproiektua irakurri eta beste adar baten azpidirektorio + moduan hasiarazteko +- `git merge -Xsubtree` erabiltzen da *subtree*aren adarra proiektuan + arazo barik mergeatzeko +- `git diff-tree` azpiproiektuaren aldaketak aztertzeko, `diff` normal bat ez + dabil + +*Ez da asko erabiltzen, *Submodule*ak gehiago erabiltzen dira. Gehiago ikasteko, +liburua irakurri.* + +## Rerere: Reuse Recorded Resolution — I + +Konfliktoak nola konpondu ditugun erregistratzeko sistema bat da, gero Gitek +konfliktoak automatikoki ebazteko kriterio berdina erabiltzen. Adibide baten +bitartez: + +1. Testing adarra mergeatzen konfliktoak daude +2. Konfliktoak konpontzen dira +3. Testak txarto doaz +4. Mergea desegin behar da +5. Testak konpondu behar dira +6. Mergea berriro egin => konflikto berdinak berriro konpondu behar dira + +`rerere`-ren bitartez lehenengo mergearen konfliktoen ebazpena gorde daiteke. +Horrela, mergea berriro aplikatzerakoan ez da konfliktoa berriro ebatzi behar, +automatikoki aurretik gordetako ebazpena erabiltzen delako. + +## Rerere: Reuse Recorded Resolution — II + +- `git config --global rerere.enabled true` +- `git rerere status` *rerere*ren egoera ikusteko +- `git rerere diff` *rerere*k aplikatuko lituzken aldaketak ikusteko +- `git add` + `git commit` egiterakoan ebazpena gordetzen da: + `"Recorded resolution"` +- `git reset --hard HEAD^` eta mergea berriro egiterakoan konfliktoak + automatikoki konpontzen dira: + `"Resolved with previous resolution"` +- `git checkout --conflict=merge ` eginda konfliktoa berreskuratu + daiteke, `rerere`a aktibatu gabe +- `git rerere` egiten berriro mergeatu daiteke automatikoki + + +## Gitekin debuggeatzen + +- `git blame` fitxategi baten aldaketak zein commitean sartu diren ikusi + daiteke. `^`-ekin hasten diren lerroak hasieratik aldatu gabeko lerroak dira. + `-C` aukerarekin mugitutako zatiak aurkitu daitezke[^move] + +[^move]: Gitek ez ditu mugimenduak gordetzen baina fitxategien zatiak aztertu + eta mugimenduak kalkulatu ditzake + +- `git bisect` [bisekzio metodoa][bisect] erabiliz errorea sartu zuen commita + aurkitzeko tresna oso interesgarria. Metodoa: + - Bi commit hartu: bat erroreduna eta bestea errore gabea + - Erdiko puntuan commit bat hartu: errorea badauka, errorea sartu zuen + commita commit honen eta errore gabeko commitaren artean dago. Errorea ez + badago, commit honen artean eta commit erroredunaren artean dago. + - Beste puntu bat hartu eta jarraitu tartea txikitzen commita aurkitzen den + arte. + +[bisect]: https://en.wikipedia.org/wiki/Bisection_method + + +## Gitekin debuggeatzen: `git bisect` + +Bisekzio metodoa aplikatzeko workflowa + +1. `git bisect start` bisekzio metodoa hasi +2. `git bisect bad` oraingo commita txarra da +3. `git bisect good ` commit hau ona da +4. `git bisect good/bad` oraingo commita ona edo txarra da. Gitek + hurrengo commita aukeratzen du: + `"Bisecting, N revisions left to test"` +5. `git bisect reset` hasierara bueltatu + +Automatizatu daiteke: `git bisect run ` + +- Komandoak `0` bueltatu behar du testa ondo badoa eta beste edozer errorea + badago + + +## Submoduluak + +Gure proiektuaren barruan azpiproiektuak kudeatzeko modu bat da. + +- `git submodule add ` azpiproiekturako karpeta berri bat gehitzen du eta + `.gitmodules` fitxategia hasieratzen du +- `.gitmodules` fitxategian azpiproiektuen informazioa gordetzen da: URLa, + izena eta path-a. +- `git submodule add ...` eta gero `git diff --cached` egitean ikusten da + submoduluen path-a ez dela fitxategi bezala kudeatzen: + `"Subproject commit ---"` +- `git diff --submodule --cached`-ekin hobeto ikusten da +- `git push` egiterakoan submodule-aren direktorioa erreferentzia moduan + pusheatzen da. + +## Submoduluak klonatzeko + +- `git clone`-ek **ez** ditu proiektuen submoduluak deskargatzen +- `git submodule init` submoduluen kontrola hasieratzeko +- `git submodule update` submoduluen fitxategiak berrizteko +- `git clone --recurse-submodule ` zuzenean submodule guztiak + deskargatzeko `clone` egiterakoan. Bestela `git submodule update --init` edo + `git submodule update --init --recursive` egin daiteke klonatu eta gero + +## Submoduluekin lanean + +- `git diff --submodule` ez egiteko `git config --global diff.submodule log` + egin daiteke eta zuzenean submoduluaren diffa ikusi daiteke `git diff` + egitean +- `git submodule update --remote ` submoduluen edukiak berrizteko + edo bestela submoduluaren barruan `fetch`+`merge` egin daiteke. +- `git config -f .gitmodules submodule..branch ` adarrez + aldatzeko, edo fitxategia zuzenean aldatu +- `git config status.submodulesummary 1` egitean `git status`-ek submoduluen + egoera bistaratuko du +- `git log --submodule` submoduluen aldaketak ikusteko + +## Submoduluak dituen proiektua berrizteko + +- `git pull` ez ditu submoduluak berritzen, informazioa baino ez du + deskargatzen. +- `git submodule update` aplikatu behar da, `--init`-ekin submodule berriak + gehitu badira, hauek gehitzeko eta `--recursive`, submoduluek submoduluak + badituzte. +- `git pull --recurse-submodules`-k efektu berdina dauka. Konfiguratu daiteke + automatikoki egiteko. +- `git submodule sync` egin behar da URLak aldatu badira. + +## Submoduluetan lanean + +Normalean ez da submoduluetan idazten, baina egin daiteke. + +- `git submodule update`-k azpirepositorioa *detached head* egoeran uzten du. + Bertak commitak gehitzean galduko lirateke (ez dago adarrik commitetara + ailegatzeko). Hau konpontzeko: + + 1. Adarrak konfiguratu behar dira: `cd && git checkout ` + 2. `git submodule update --remote --merge/--rebase` egin behar da *detached + head* egoeran ez gelditzeko. Submoduluan aldaketak badaude, konfliktoa + egon daiteke. + +## Submoduluen lana publikatzen + +- `git push` egin daiteke submodulu bakoitzean, Git repositorio normalak + baitira +- `git push --recurse-submodules=check/on-demand` bi estrategia dago. `check` + aldaketak pusheatu behar diren begiratzen du, eta `on-demand`-ek pusha egiten + du submodulu bakoitzean aldaketak badaude + - `git config push.recurseSubmodules check/on-demand` estrategia defektuz + konfiguratzeko + +## Submoduluen trukoak + +- `git submodule foreach ` egin daiteke submodule bakoitzean komando + bat executatzeko. Adibidez: `git submodule foreach 'git stash'` + +## Bundle + +Bundle-ak commitak edo repositorio osoak fitxategi baten bidez partekatzeko +sistema dira. + +- `git bundle create []` aukeratutako commitak (edo + guztiak) `` fitxategian gorde, bundle formatoan. Normalean, `HEAD` + sartzea komeni da, gero bundle-a kargatzean repositorioa non zegoen jakiteko. + +- `git clone ` bundle fitxategitik clone bat egiteko. Bundle-a + repositorio osoa izan behar du. + +- `git bundle verify ` bundle partzial bat repositorio batean + aplikatu daitekeen konprobatzeko + +- `git bundle list-heads ` bundle fitxategiaren adarrak ikusteko + +- `git fetch/pull ` bundle fitxategitik repositorioa + berriztatzeko + +## Replace + +Giten datu basea orokorrean ezin da aldatu, baina `git replace`-en bitartez +*replace* objektuak eratu daitezke, datu basea aldatu denaren itxura emango +dutenak. + +- `git replace ` aplikatzetik aurrera, `` + erabiltzean `` erabili balitz bezala funtzionatuko du + +*Erabileren adibide bat ikusteko liburuan ikusi, nahiko arraroa da hau ikustea* + +## Kredentzial sistema + +HTTP kredentziala erabiltzean, zerbitzariarekin egiten diren interakzio +guztietan erabiltzailea eta pasahitza eskatzen du Gitek defektuz. +Portaera konfiguratu daiteke: + +- `git config --global credential.helper ` + 1. Beti eskatu (defektuz egiten dena) + 2. `cache` kredentzialak memorian mantendu 15 minutu + 3. `store` kredentzialak gorde + +Aukera gehiago dago (`--timeout`, neurrira egindako kredentzial sistemak, +etab.). *Interesa balego, liburuan begiratu* + +# Git konfigurazio aurreratua + +## Git konfigurazioa + +Konfigurazioaren dokumentazioa ikusteko `git help git-config`. Atal +interesgarrienak: + +- Editorea eta paginadorea: `core.editor` eta `core.pager` +- Commit mezuen txantiloia: `commit.template` +- Merge eta diff tresnak: `merge.tool` eta `diff.tool` +- Espazio hutsen kontrola: `core.autocrlf` eta `core.whitespace` + +## Git attribute-ak — I + +Proiektuen barruan, fitxategi mailan, Giten portaera aldatzeko erabiltzen dira +atributuak (*attribute*). + +- `.gitattributes` fitxategian edo `.git/info/attributes` fitxategian, + repositorioarekin partekatu nahi ezbadira. + +Atributu fitxategia `.gitignore` fitxategiaren antzekoa da, baina lerro +bakoitzean fitxategien izenen txantiloiaz aparte haien atributuak definitu +behar dira. Askotan konfigurazio gehigarria behar da, *driver* programak +definitzeko. Ikusi `git help attributes`. + +## Git attribute-ak — II + +Atributu mota asko dago, interesgarrienetarikoak: + +- `binary` fitxategiak binario moduan identifikatzeko +- `diff=` diff-a exekutatu baino lehen fitxategiak iragazki batetik + pasatzeko. Konfigurazio gehigarria behar da: + - `git config diff..textconv ` + - Adibidez: `*.png diff=exif` + - `git config diff.exif.textconv exiftool` + png fitxategien estatistikak konparatzen dira, eta ez edukiak +- `ident` identifikazioa gehitzeko. `$Id$` testu literala SHA-1era bihurtzen da + espantsio baten bitartez + +## Git attribute-ak — III + +- `filter` fitxategiak iragazki batekin prozesatzeko + - `smudge` *index*etik *working directory*rako bidean + - `clean` *working directory*tik *index*erako bidean + - Adibidez: `*.c filter=indent` + - `git config filter.indent.clean indent` + `git config filter.indent.smudge cat` + fitxategiak automatikoki indentatzeko `git add` egiterakoan +- `export-ignore` artxibo (`git archive`) bat egiterakoan fitxategi batzuk + baztertzeko. +- `export-subst` artxibo bat egiterakoan `git log`-ek aplikatzen dituen + espantsioak aplikatzeko +- `merge` merge estrategiak aukeratzeko + + +## Git hooks + +Hookak gertaera garrantzitsuak gertatzen direnean exekutatzen diren programak +dira. Askotan erabiltzen dira. + +- `.git/hooks` direktorioan idazten dira, izen konkretu batekin eta exekuzio + baimenekin + +Defektuz, `git init` egiterakoan hook batzuk idazten dira, baina desaktibatuta +daude (haien izena `.sample`-n bukatzen delako). Erreferentzia moduan hartu +daitezke haien funtzionamendua ulertzeko. + + +## Bezero aldeko hookak + +Bakoitzarentzako bakarrik. **Ez dira kopiatzen repositorioarekin +batera**[^hookak-partekatu]. +Interesgarriak dira garatzaileei alertak botatzeko: testak ez direla pasatu, +formaturen bat txarto dagoela adierazteko, etab. Interesgarri batzuk: + +- `pre-commit` commit mezua idatzi baino lehen exekutatzen da, zeozer ahaztu + den konprobatzeko erabili ohi da +- `prepare-commit-msg` defektuzko commit mezua aldatzeko erabiltzaileak ikusi + baino lehen. Informazio gehigarriak sartu ahal zaio horrela, edo txantiloia + aldatu... +- `commit-msg` commit mezua aztertzen duen hooka. Txarto badago commita atzera + bota dezake. Normalean commitaren mezua txantiloi konkretu bat jarraitzeko + erabiltzen da. + +[^hookak-partekatu]: Tresna batzuek mekanismoak dauzkate hook hauek + partekatzeko, baina hau ez da Giten defektuzko funtzionamendua. Kontuz + workflow guztia honetan oinarritzearekin. + +## Zerbitzari aldeko hookak + +Politikak inposatzeko aproposak dira, txarto badoaz `push` egiteko eskaerak +atzera bota ditzaketelako. Interesgarri batzuk: + +- `pre-receive` push bat jasotzean erreferentzia guztiak jasotzen dituen + programa, errorea ematen badu ez da ezer berriztuko. +- `update` aurrekoaren antzekoa da, baina behin exekutatzen da adar bakoitzeko +- `post-receive` dena ondo jaso eta gero exekutatzen da, notifikazio moduan + erabili daiteke + + +# Git barrutik + +## Git barrutik: Sarrera + +Git maila baxuko tresna bat da, eta maila horretan lan egiteko komandoak ditu, +*plumbing* deiturikoak. Orain arte erabilitakoak *porcelain* deitzen dira, +maila altuan lan egiten dutelako. + +Git *content-addressing* aplikatzen duen datu base bat da, hau da, *Key-Value* +moduan gordetzen dira elementuak, non Key-a Valuaren edukiaren araberakoa den. +Orain arte ikusi da: elementuak haien edukiaren SHA-1 hasharen bitartez +identifikatzen dira. + +Eduki guzti hau `.git` karpetan gordetzen da. Baina elementu mota ezberdinak +daude. + +## Giten gordetzen diren elementu motak + +Bi elementu mota nagusiak daude Git datu basean: + +- Objektuak: edukiak dauzkaten elementuak dira: commitak, blobak, zuhaitzak, + etab +- Erreferentziak: beste elementuei apuntatzen duten elementuak dira: adarrak, + lightweight tagak, etab + + +## Objektuak + +`.git/objects`-en gordetzen dira, haien hasharen arabera. Lehengo bi +karaktereak direktorio moduan eta hurrengoak fitxategi moduan. +Adibidez: `.git/objects/cf/6cbb8a400c7cad0f7f93610366c3672f598cdd` + +- `git hash-object -w`-rekin idatzi daitezke (bueltan hash-a ematen du) +- `git cat-file`-ekin irakurri daitezke. `-p` egin emaitza **p**olita ikusteko. + +## Objektu motak + +`git cat-file -t`-rekin mota ikusi daiteke. + +- `blob`-ak fitxategien edukiak eta bestelako datuak gordetzeko +- `tree` fitxategien izenak eta direktorioak gordetzeko + Sarrera bat edo gehiago dute beste `tree` edo `blob`etara haien izena eta + hasha identifikatuz. +- `commit` commit datuak gordetzeko: `tree` bat snapshotarekin, mezua, autorea, + etab. + +## Objektu motak: tree + +![](img/data-model-1.png) + +## Objektu motak: commit + +![](img/data-model-3.png) + +## Erreferentziak + +Haien barruan identifikadore bat baino ez dago. + +- `git update-ref` edukia aldatzeko. Eskuz ere egin daiteke. + +Erreferentzia mota ezberdinak daude: + +- Tag-ak: `.git/refs/tag` karpetan. Edozein objetu tageatu + daiteke (normalean commitak). Bi mota dago: + - Lightweight tag: erreferentzia bat baino ez dira + - Annotated tag: tag *objektu* bat eratzen dute eta erreferentzia bat + idazten dute bertara +- Adarrak: `.git/refs/heads` karpetan. Commit-id batera erreferentzia + egiten dute. +- Remote-ak: `.git/refs/remotes` karpetan. Adarren antzerakoak baina ezin dira + aldatu. +- HEAD-a: `.git/HEAD`-en dago. Adar batera apuntatzen du, baina batzutan commit + batera apuntatu dezake (*Detached HEAD*). + +## Erreferentziak: adarrak + +![](img/data-model-4.png) + +## Ariketa: Notak + +- `git notes` komandoarekin kudeatzen dira. + +*Aztertu zer diren eta nola funtzionatzen duten. Ikusi `git help git-notes`* + +## Packfile-ak + +Datuen egitura efizienteagoa egiteko Gitek fitxategiak konprimatzen ditu, baina +hori ez da normalean nahikoa izaten. + +Git snapshotetan oinarritzen da, baina ez ditu fitxategi osoak behin eta +berriro idazten commit bakoitzean, aldaketak baino ez ditu gordetzen. + +Gainera fitxategiak taldekatu eta *packfile* deituriko fitxategietan gordetzen +ditu prozesua arintzeko. + +- `.git/objects/pack`-en ikusi daitezke +- `git gc` (*garbage collector*) fitxategiak taldekatu eta konprimatzeko (berak + bakarrik exekutatzen du beharrezkoa ikusten duenean) +- `git verify-pack` *packfile* baten edukia aztertzeko eta egiaztatzeko + +## Mantenamendua eta datuak berreskuratzea + +- `git gc --auto`-k packfileak berrorganizatzen ditu. +- `git reflog`-en HEAD-ean egindako aldaketak gordetzen dira, beraz commiten + bat galdu bada bertara salto egin daiteke, `reflog`a begiratu eta commita + berreskuratu daiteke. +- `git fsck --full` galdutako elementuak erakusten ditu, bertatik ere + datuak berreskuratu daitezke + +*ARIKETA: Fitxategi handiak nahi gabe gehitzea arazo bat da, `git rm`-k ez +dituelako ezabatzen. Nola egiten da? Zergatik?* + +## Refspec-a + +Lokalaren eta remotearen arteko adarren mapeoa kudeatzeko. `.git/config`-en +edukia `git remote add origin https://github.com/schacon/simplegit-progit` egin +eta gero: + +``` +[remote "origin"] + url = https://github.com/schacon/simplegit-progit + fetch = +refs/heads/*:refs/remotes/origin/* +``` + +`fetch` atalak **refspec** baten bitartez adarrak nola kudeatu behar diren +adierazten du. Sarrera asko egon daitezke arau ezberdinekin. Formatua: + +- Aukerako `+` bat *fast forward* ez direnean ere berrizteko +- `:` nola mapeatu behar diren adierazteko. `` + eta `` patroiak dira (`*`) + +## Refspec-a eskuz erabiltzen + +`git fetch/push` egitean refspec patroia (1 edo +) gehitu ahal da *"hau hona"* +eta *"beste hau hona"* esateko. + +Refspec-a ikusita, Gitek adarren adierazpenaren espantsioa egiten du: + +- `git log origin/master` + => `git log remotes/origin/master` + => `git log refs/remotes/origin/master` + +Adarrak ezabatzeko lehen refspec-a erabili behar zen: + +- `git push :` iturri atala utzik uztean, remotean adarra ezabatzen zen +- Orain `git push --delete ` egin daiteke + -- cgit v1.2.3