====== Git ======
[[vcs|Sistema de control de versions o VCS]] iniciat per l'equip de desenvolupament del //Kernel// de Linux el 2007. Actualment és el sistema més utilitzat esdevenint un estàndard hegemònic.
Referències:
* [[VCS]] : teoria sobre els sistemes de control de versions.
* https://git-scm.com la web oficial de Git.
* [[https://cacauet.org/wiki/index.php/Git:_comandes|Xuleta de comandes Git]]: apunts antics.
* [[https://www.w3docs.com/snippets/git.html|W3Docs.com secció Git]] : trucs variats i documentació.
* Proveidors de repositoris gratuïts:
* https://github.com
* https://gitlab.com : Gitlab té el servei de repositoris (SaaS) però també pots descarregar el //software// en local i muntar el teu propi servidor.
* [[https://cli.github.com|Documentació del CLI de Gitlab]] : github accessible via //command line//.
* Uns quants [[https://victorhckinthefreeworld.com/2018/08/09/6-errores-comunes-al-utilizar-git-y-como-solucionarlos/|trucs imprescindibles de Git]] per quan hem fet alguna gamba.
{{ git.png?300 }}
{{tag> #Daw #DawMp08 #DawMp08Uf4 #DawMp08Uf04 #DawMp05 #DawMp05Uf2 #DawMp05Uf02 #Dam #DamMp05 #DamMp05Uf2 #DamMp05Uf02 #Ciber #CiberMp03 #Ceti #CetiMp03 git cvs vcs versions subversion svn DevOps }}
\\
===== Abans d'entrar en pànic feu commit i push! =====
{{ https://victorhckinthefreeworld.files.wordpress.com/2016/09/git_commit_fire.png?300 }}
\\
===== Videotutorial Git + Apache =====
Videotutorial per iniciar-se amb Git i Apache:
{{youtube>YpSaqTe9M2E}}
\\
===== Comandes bàsiques =====
{{ git-push-pull.png?400 }}
Les comandes imprescindibles per treballar amb Git son:
* ''git clone'': descarrega un repositori d'una URL.
* ''git commit'': guarda modificacions en el sistema de versions.
* ''git push'': puja els canvis realitzats al repositori original des d'on s'ha creat (clonat) el repositori local.
* ''git pull'': actualitza (descarrega) els canvis que hi hagi als //remotes// configurats.
* ''git add'': afegeix nous arxius al repositori. Si creem arxius a la nostra carpeta no n'hi ha prou perquè s'afegeixin al sistema de versions. Cal fer el ''git add'' explícitament. La versió més habitual és afegir tots els arxius que hi ha a la carpeta:$ git add .
I tingueu en compte que hi ha alguns arxius importants:
* ''.git/config'': arxiu amb les configuracions de correspondència dels repositoris remots i branques.
* ''.gitignore'': arxiu que indica quins arxius o carpetes NO s'han de pujar al fer ''git add .'' Molt útil per arxius de producció amb contrasenyes i similars.
\\
===== Primera pràctica amb Git =====
La situació més habitual és la de clonar un repositori existent, contribuir-hi afegint arxius o modificacions, i tornant a pujar els canvis.
Clonarem el [[https://github.com/aws2/welcome|projecte Welcome del grup de DAW del Esteve Terradas]], on surten les fotos dels alumnes de desenvolupament que passen per l'institut, visualitzarem la web i afegirem la nostra foto i el nostre profile (arxiu HTML que es mostrarà quan cliquem sobre la foto).
Si ets alumne de l'Esteve Terradas pots seguir el tutorial tal qual, demanant al professor que t'inclogui a l'equip de treball del cicle, donant-li el teu //nickname// del Github.
Si no ets alumne del Terradas, pots clonar el projecte Welcome al teu compte de Github fent un FORK (busca el botó "Fork" a dalt a la dreta de la pàgina del projecte). Llavors canvia el ''git clone'' de l'inici i canvia l'adreça per la de la teva còpia que has fet (hauria de ser algo com ''https://github.com/elmeusuari/welcome'').
- Crea't un usuari a github.com i notifica el professor el teu //nickname// perquè t'inclogui al grup de treball.
- Instal·la ''git'' i ''php'' amb $ sudo apt install git php
- Descarrega el projecte Welcome en el teu PC local:
- Si ets alumne del Terradas: $ git clone https://github.com/aws2/welcome
- Si no ho ets, fes un //Fork// del projecte i te'l descarregues amb: $ git clone https://github.com/elmeuusuari/welcome
- Entra al directori de treball del repo local:$ cd welcome
- Engega l'aplicació en local executant el servidor integrat de PHP:$ php -S 0:8080
- Accedeix a la web per ''http://localhost:8080'' i comprova que funciona. Veuràs que al clicar la foto d'un alumne apareix el seu "profile".
- Afegeix la teva foto a la carpeta ''img/'' i el teu HTML a la carpeta ''profile/''.
- Comprova que a la web es veu la teva foto i que s'accedeix al //profile//.
- Afegeix els dos nous arxius al sistema de control de versions:$ git add .
- Comprova que els arxius han estat incorporats amb $ git status
- Consolida els canvis al repositori local$ git commit -am "afegida imatge i perfil en html"
- Si estàs en Linux, crea't un //personal token// anant a la web de de GithubGithub -> Settings -> Developer settings -> Personal access tokens
(en Windows //potser// no cal)
- Puja els canvis al repositori principal.$ git push
Per mes info i xuleta pràctica pots consultar: https://cacauet.org/wiki/index.php/Git:_comandes
\\
===== Per guardar el token i no haver de repetir credencials =====
Per ho haver de posar tota l'estona el //token// que hem creat com a credencial activem la //cache//:
$ git config --global credential.helper cache
\\
===== Crear un nou repositori =====
Cal distingir clarament entre el **repositori local** i el **repositori remot**.
Per **crear un repositori local** ho farem mitjançant ''git init'' , però primer cal crear la carpeta de projecte. Després podrem afegir arxius amb ''git add'' i pujar-los a un repositori remot amb ''git push''.
Per **crear un repositori remot** dependrà del proveïdor que l'hostatgi. Entre d'altres, les opcions que tenim son:
* Github.com
* Gitlab.com
* Un servidor nostre amb accés per SSH
Cada proveïdor té les seves eines, entre elles es pot fer via web. Però sempre ens serà molt útil disposar d'eines CLI (//Command Line Interface//). Github és la web més popular per hostatjar repositoris gratuïtament i té la eina **gh** https://cli.github.com/
En Debian/Ubuntu la podem instal·lar amb:
$ sudo apt install gitsome
I després ja ens podem logar. Caldrà que creem un **//personal access token//** a la web de Github.com.
$ gh configure
A partir d'aquí podrem [[https://cli.github.com/manual/gh_repo_create|crear un repositori remot a Github]]. Tenim un parell d'opcions:
$ gh repo create
Amb això ens crearà un repositori remot, però ens falta lligar el repositori remot amb un de local, i omplir els continguts. Si visiteu la URL del nou repo de Github, allà mateix us apareixerà una "xuleta" de com fer-ho:
https://github.com/elmeuusuari/elmeurepo
En concret, fixeu-vos en la més important:
$ mkdir elmeurepo
$ cd elmeurepo
$ git init
$ git add README.md # suposant que hem creat un fitxer README.md
$ git commit -m "primer commit"
$ git branch -M main
$ git remote add origin https://github.com/elmeuusuari/elmeurepo
$ git push -u origin main
Fixeu-vos en ''git remote add origin ...'' que és la que enllaça el repo local i el remot.
\\
===== Treballar amb branques =====
Cal tenir en compte i distingir les branques locals i les branques remotes, perquè no son les mateixes.
La comanda bàsica per veure les **branques locals** és:
$ git branch
Per veure totes les branques, locals i remotes fem:
$ git branch -a
Per **crear una nova branca local** ho fem amb: (ULL! Això només la crea, però no l'estem utilitzant encara)
$ git branch newbranch
Per **canviar-nos a la nova branca**:
$ git checkout newbranch
Ara podem pujar la nova branca amb:
$ git push -u origin newbranch
**Configuració de branques locals i remotes**
Molt important tenir en compte que una branca local no té perquè coincidir amb el nom de la branca remota.
Quan fem el procediment anterior (crear una branca remota des d'una local), automàticament ens ha creat una branca remota amb el mateix nom, i les enllaça perquè la local segueixi la remota. Aquesta situació, però, és configurable.
Per veure com estan enllaçades les branques i el repositori podem inspeccionar l'arxiu ''.git/config''
\\
===== Merge =====
Una bona referència: [[https://www.atlassian.com/es/git/tutorials/using-branches/git-merge|documentació Atlassian sobre Git Merge]].
Sempre que fem un ''git pull'' **es fa un //merge// automàticament**. Per tant, aneu al tanto amb aquestes operacions. Potser és més convenient utilitzar ''git fetch'', mirar els canvis que s'han introduït, i si s'entén que estan bé, procedir al ''git merge''.
Abans de fer un merge convé repassar com està l'arbre de versions, per exemple amb un:
$ git log --graph --all --oneline
El //merge// és una operació que comporta riscos potencialment. El developer que faci un //merge// es pot trobar amb diversos tipus d'errors:
* **Conflicte de versions**: significa que a l'hora de barrejar el codi, Git ha detectat que les dues branques o versions tenen línies amb canvis simultanis incompatibles. Qui faci el //merge// haurà de decidir què fer, si triar una de les versions o fer una barreja de les dues. Caldrà que es revisin el arxius marcat amb conflicte, que ens mostraran les diferències amb algo tipus:
<<<<<<< HEAD
Versió que teniem a la branca.
=======
Versió que estem fusionant.
>>>>>>> manolo
* **El codi deixa de compilar**: potser cada canvi per separat no donava errors i funcionava, i el //merge// no indica conflicte, però al ajuntar-los el codi deixa de compilar. Caldrà examinar què està passant i posar remei per part dels desenvolupadors responsables.
* **L'aplicació aparentment arrenca correctament però una funcionalitat falla**: per detectar aquesta situació el més còmode és disposar de tests automatitzats. Si no, és comprensible que després de cada //merge// caldrà comprovar totes les funcionalitats a mà.
Per procedir a un //merge// podem seguir les següents passes:
Descarregar els canvis dels altres desenvolupadors (farem **git fetch** i no git pull per evitar merges automàtics abans de comprovar els canvis):
$ git fetch
Comprovar els canvis mirant l'arbre de versions:
$ git log --graph --all
Anar a la branca destí:
$ git checkout
Unir la branca amb la branca :
$ git merge
Si surten conflictes, resoldre'ls amb les eines adequades (IDE, compiladors, etc.).
Caldrà fer de nou totes les proves (tests) pertinents (automatitzades o no).
Per finalitzar el //merge//, fer un commit i un ''push'':
$ git commit -am "merge branca origen"
I pujar els canvis:
$ git push
\\
===== Git submodules =====
Sovint necessitem tenir submòduls, és a dir, dependències del projecte principal, per exemple, llibreries, que cal incloure perquè el projecte principal funcioni.
Referències:
* Doc oficial: https://git-scm.com/book/en/v2/Git-Tools-Submodules
* Una referència pràctica: https://voragine.net/scripting/git-submodules
Prenent el cas que tinguem un projecte ''Desktop'' i una llibreria ''Lib'', amb els seus repos independents cadascun ja creats, podem incloure ''Lib'' dins de ''Desktop'' fàcilment.
Entrem a la carpeta de Desktop i fem:
$ git submodule add https://github.com/.../Lib
$ git commit -am "add lib submodule"
$ git push
Ens apareixerà la carpeta ''Lib'' amb el contingut del repo ja clonat.
==== Clonant de nou un repo amb dependències (submodules) ====
A partir d'ara, quan clonem el projecte principal en una nova ubicació, ens apareixerà la carpeta ''Lib'', però estarà buida. Caldrà que inicialitzem els submòduls des de l'arrel amb:
$ git submodule init
I després podem entrar a cadascuna de les llibreries i descarregar el codi pertinent:
$ cd Lib
$ git submodule update
\\
===== Fer que git recordi les credencials =====
[[https://www.freecodecamp.org/news/how-to-fix-git-always-asking-for-user-credentials/|Aquest article explica com evitar que git ens vagi demanant les credencials]] repetidament quan treballem per línia de comandes.
Resumint, es pot fer així:
git config --global credential.helper store
git config --global credential.helper cache
No és molt recomanable deixar la //cache// permanentment.
Si volem limitar la //cache// durant 10 minuts (600 segons) es pot fer amb un //timeout//:
git config --global credential.helper 'cache --timeout=600'
\\
===== Com arreglar alguns errors típics de Git =====
Aquest article ens ensenya alguns [[https://victorhckinthefreeworld.com/2018/08/09/6-errores-comunes-al-utilizar-git-y-como-solucionarlos/|trucs imprescindibles de Git]]:
* Com utilitzar ''git amend''.
* Com afegir un arxiu que he oblidat posar al darrer commit.
* Com esborrar un arxiu que he entrat per error al darrer commit.
* Com arreglar si has fet el commit a la //main trunk// (branca principal) en lloc d'a la teva branca.
* ...i algun més.
[[https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/removing-sensitive-data-from-a-repository|Com eliminar dades sensibles emmagatzemades en un repositori]]. És fàcil que succeeixi: un arxiu ''.env'' amb dades de desplegament reals, un arxiu de BD o de test amb contrasenyes reals (encara que estiguin //hashejades// no convé que algú li pugui fer un atac de diccionari), etc.