# Tutorial de git/Treball distribuït

Fins ara hem parlat sobre com treballar sol "tancat en una habitació". A partir d'aquest apartat aprendrem a com treballar en equip, com compartir el nostre codi, etc.
En aquest apartat no aprofundirem en els protocols que fa servir el git. En general parlarem de la URL. Git fa servir 3 protocols: ssh, http i un protocol nou que és el git. Pel tutorial es pot fer servir qualsevol dels tres protocols, tot i que jo recomano el ssh ja que sembla el protocol en el qual tothom està més acostumat.

## Copiar un repositori d'una altra persona

En aquest apartat explicaré com copiar un repositori que ja existeix. La funcionalitat és molt senzilla. En la seva forma més bàsica és: git clone URL on URL és la URL del repositori que volem copiar. Aquesta comanda ens crearà una carpeta amb el mateix nom que el repositori original i ens copiarà tot el repositori.
Si vols que el directori es digui de manera diferent simplement has d'afegir el nom que vols després de la URL, quedant la comanda de la següent manera git clone URL directori
El git guarda un nom intern al repositori original per si després el necessitem. Per defecte fa servir origin però si volem canviar-li el nom podem fer servir el paràmetre -o. Així doncs, li podem dir remot de la següent manera: git clone -o remot URL directori
Un cop ja hem clonat el repositori el podem fer servir com si l'haguéssim creat nosaltres.

## Branques locals i remotes

Quan clonem un repositori en general clonem la branca master del repositori local, la resta de branques no les clonem.
Per exemple podem clonar el repositori de git amb l'ordre git clone git://git.kernel.org/pub/scm/git/git.git. Ara si fem un git branch veurem que només tenim la branca master.
Si en canvi fem un git branch -r veiem totes les branques remotes (podem veure que estan precedides per origin/, que recordem que és el nom que es dóna per defecte).
Si fem un git branch -a podem veure tant les branques locals com les remotes.
És a dir, el git coneix les branques remotes del repositori malgrat només ha fet una copia local del master.

## Actualitzar el teu repositori local des d'un repositori remot

En general de tant en tant quan has clonat un repositori voldràs actualitzar-lo per veure què està fent la resta de gent.
Hi ha dos comandes bàsiques per fer això. La comanda git fetch bàsicament el que fa és actualitzar les branques remotes; però la branca local la deixa igual. Si volem actualitzar la branca local el que hem de fer és un git merge origin/master o bé un git rebase origin/master.
Això no és molt pràctic, i és per aquest motiu que existeix la comanda git pull. Aquesta comanda t'actualitza la teva branca local amb la remota. Bàsicament fa un fetch més un merge. És la més usada en situacions normals. El paràmetre --rebase permet fer un fetch més un rebase .

## Actualitzar un repositori remot amb el teu repositori local

L'altre cosa important per treballar en equip és ser capaç de fer que els teus canvis locals es reflecteixin en el repositori remot.
Per tal de passar els teus canvis al repositori remot la comanda que s'ha de fer servir és git push. Aquesta comanda per defecte passa els canvis de la teva branca local master a la branca remota origin/master
Si volem actualitzar una altra branca hem de fer servir la sintaxi: git push origin nom_branca
En general es recomana treballar amb branques locals i quan estiguem segurs que la funcionalitat funciona, afegir-la a master i llavors fer el push de master. Tot i això hi ha situacions on és útil fer un push d'altres branques encara en desenvolupament per poder compartir-les amb més gent

## Crear branques locals a partir de branques remotes

Tal com hem vist, quan clonem un repositori remot en el nostre repositori local només ens crea la branca master. Moltes vegades volem obrir una branca local basada en una branca remota.
La manera més fàcil de fer-ho és amb la comanda git checkout -t origin/nom_branca. Amb aquesta comanda el git endevinarà quin nom posar-li a la branca local en funció de la branca remota que posis (origin/nom_branca és el nom d'una branca remota); i a més tindrà en compte que tot el que actualitzis a la branca local, quan facis un git push ho actualitzarà a la branca remota. També funciona amb el git pull
Si no volem que s'actualitzi sol en fer un git push/pull en lloc del paràmetre -t podem fer servir el paràmetre --no-track.
Finalment si volem posar-li un nom diferent podem fer servir el paràmetre -b. Així doncs la comanda git checkout -t -b branca_prova origin/nom_branca Crearà una branca local branca_prova a partir de la branca remota origin/nom_branca i que estarà actualitzada en fer un git push/pull

## Gestionant diversos repositoris remots

Hi ha vegades que només amb un repositori remot no en tens prou. És per aquest motiu que el git et permet gestionar més d'un repositori remot alhora.
La comanda per gestionar els repositoris remots és git remote. Aquí bàsicament parlarem d'afegir un repositori remot i d'esborrar-los.
La comanda git remote add et permet afegir un repositori remot. La sintaxi bàsica és git remote add nom URL. Aquesta forma ens permet afegir un repositori que tindrà un nom determinat. Per exemple git remote add uni uni.edu:Git-repo/ crea un remot que es diu uni i que apunta al repositori Git-repo que es troba en la màquina uni.edu.
Si ara fem un git branch -r veurem que encara no hi ha cap branca remota del repositori que acabem d'afegir. Si ara fem un git fetch nom, recordem que això actualitza la informació sobre els repositoris remots, i fem un git branch -r ja tindrem la informació sobre les branques remotes. Com que haver de fer un fetch després de cada add és engorros, existeix una manera de fer-ho directament git remote add -f nom URL
Si en aquest punt volem actualitzar-nos des del nou repositori remot, tal com recordem, hem de fer git pull nom[[#fn][*]]. Però què passa? Ens diu que no sap quina branca ha d'actualitzar. Una manera de fer que això no passi és dient-li quina branca vols actualitzar, per exemple git pull nom master.
Si quan afegim un repositori remot sabem que només el volem per seguir una branca ho podem dir amb el paràmetre -t. Així doncs, la comanda seria git remote add -t master -f nom URL. Amb aquesta comanda només tenim en compte la branca master i quan fem un git pull nom ja sap que ha d'actualitzar la branca master.
Per saber quines opcions té un repositori remot ho podem saber amb la comanda git remote show nom. Aquesta comanda ens donarà tota la informació del repositori remot (URL, nom, etc.)
Si mai volem esborrar un repositori remot ho podem fer de la següent manera git remote rm nom.
* fn
\* Si no posem el nom per defecte farà servir el origin. Si és un repositori que l'hem començat clonant un repositori (que per defecte és l'origin) i afegint un nou repositori remot, això pot passar i realment s'actualitzarà des del origin. Si no existeix el repositori remot origin simplement et dirà que no existeix el origin. És per aquest motiu que cal posar el nom

## Preparar un repositori per compartir

Abans d'explicar com preparar un repositori per compartir explicarem perquè cal preparar un repositori concret per compartir. Els motius més evidents són la seguretat. Ens interessarà crear un repositori per compartir diferent al nostre repositori local per tal de poder donar permisos de lectura i escriptura a qui cal, per poder decidir quines branques farem públiques i quines les mantindrem al nostre repositori local, etc. En aquí no parlarem sobre tot això, ni tampoc sobre quin protocol farem servir.
El que sembla més senzill és fer un git clone URL directori_compartir. D'aquesta manera creem una còpia del nostre repositori local que només segueix la branca master. Tot i que això sembla que està bé no és la solució més òptima. La comanda git clone està pensada per fer un repositori on tu hi treballaràs, per tant te àrea de treball i índex. Quan algú fa un git push a un repositori que te àrea de treball el git deixa l'àrea de treball igual que com estava abans del push per tal que no es perdin els canvis fets localment.
Tal com diu el GitFAQ (anglès):
És per aquest motiu que existeix el paràmetre --bare en la comanda git clone. Això et crearà un directori (que acostumarà a acabar amb .git) que no tindrà àrea de treball ni índex, tot el que tindrà a dintre serà els continguts de la carpeta .git/
Un repositori creat d'aquesta manera serà el millor per compartir. Cal dir també que la comanda git init també permet el paràmetre --bare
A partir de tenir un repositori preparat per compartir, el fet de compartir-ho i triar el protocol ho deixo a les vostres mans.

## Consideracions a tenir en compte en treballar en grup

Quan el repositori es comparteix s'ha de tenir en compte que la història també es reparteix per tots els repositoris que l'han copiat i que treballen amb ella. És per aquest motiu que s'ha de tenir en compte que la història està compartida. És a dir que qualsevol canvi que facis a la història serà difícil que es comparteixi, ja que la gent pot treballar amb versions diferents del repositori i que s'acabi creant un embolic i que sigui molt difícil integrar els diferents repositoris.
És per aquest motiu que cal anar molt en compte a fer un git reset o un git rebase en alguna cosa que ja estigui publicada. Per desfer canvis us recomano que busqueu informació sobre el git revert.

## Github

Si voleu tenir un repositori compartit existeix una pàgina web que ofereix de manera gratuïta repositoris públics de git i pagant repositoris privats. La veritat és que te molt bona acollida i te molt bones guies.
La seva adreça web és http://github.com/