En el blocs anteriors, ens hem centrat en conéixer la seua estructura i
realitzar accions bàsiques per realitzar canvis sobre aquest.
No obstant això, totes les accions que hem realitzat fins ara han sigut
sobre un repositori local, és a dir, un repositori que es troba en
el nostre dispositiu i aquests canvis no han segut publicats en cap
lloc.
En aquest bloc, ens centrarem en la creació de repositoris remots;
repositoris que es troben allotjats en un servidor, que permeten
l'accés a altres usuaris i la col·laboració en el desenvolupament de
projectes.
Preparació repositori local
En aquest material treballarem sobre un nou repositori local.
Inicialització:
#!/bin/bash# Elimina els repositori si existeixif[-d~/git_remots];thenrm-rf~/git_remots
fimkdir-p~/git_remots
cd~/git_remots
gitinit
gitbranch-mmain# (1)!echo"# Remots a Git">README.md
echo"Repositori del __Bloc: Remots__ del curs __\"Introducció a Git i la seua aplicació a l’aula\"__">>README.md
gitaddREADME.md
gitcommit-m"Commit inicial"gitlga
jpuigcerver@fp:~$mkdir-p~/git_remots
jpuigcerver@fp:~$cd~/git_remots
jpuigcerver@fp:~/git_remots$gitinit
Initialized empty Git repository in ~/git_remots/.git/jpuigcerver@fp:~/git_remots(main)$gitbranch-mmain# (1)!jpuigcerver@fp:~/git_remots(main)$echo"# Remots a Git">README.md
jpuigcerver@fp:~/git_remots(main)$echo"Repositori del __Bloc: Remots__ del curs __\"Introducció a Git i la seua aplicació a l’aula\"__">>README.md
jpuigcerver@fp:~/git_remots(main)$gitaddREADME.md
jpuigcerver@fp:~/git_remots(main)$gitcommit-m"Commit inicial"[main (root-commit) 113f1d4] Commit inicial 1 file changed, 2 insertions(+) create mode 100644 README.mdjpuigcerver@fp:~/git_remots(main)$gitlga
*113f1d4-(0 seconds ago)Commit inicial-Joan Puigcerver(HEAD -> main)
Canviem el nom de la branca principal a main.
README.md
# Remots a GitRepositori del __Bloc: Remots__ del curs __"Introducció a Git i la seua aplicació a l’aula"__
Un Repositori Remot és una còpia d'un repositori de Git que es troba allotjat en un servidor
o en un altre lloc fora del teu propi sistema local.
Aquesta còpia conté una rèplica completa de la història del repositori,
incloses totes les revisions i les branques.
Els repositoris remots permeten la col·laboració i el seguiment del desenvolupament del codi
entre múltiples persones, o tu mateix en diferents dispositius.
Entre les finalitats dels repositoris remots podem trobar:
Col·laboració: Permeten que diversos desenvolupadors treballen junts en un mateix projecte.
Cada desenvolupador pot treballar en la seua còpia local del repositori remot i,
una vegada fetes les seues modificacions, pot pujar els canvis al repositori remot perquè altres membres
de l'equip puguen veure i incorporar aquestes modificacions.
Còpia de seguretat: Un repositori remot pot servir com a còpia de seguretat del teu projecte.
Si el teu sistema local es danya o es perd, encara tindràs accés a la teua història completa
i als fitxers del projecte mitjançant el repositori remot.
Distribució: Els repositoris remots permeten distribuir el teu codi a altres llocs.
Això pot ser útil per compartir el teu codi amb altres persones
o per desplegar el teu projecte en un servidor en línia.
Gràcies a aquestes característiques, Git s'ha convertit en una eina clau en qualsevol desenvolupament,
però sobretot en els projectes de codi obert (open source), ja que permet la col·laboració
de desenvolupadors de tot el món en un mateix projecte de manera senzilla i distribuïda.
Els repositoris remots es poden allotjar en qualsevol màquina o servidor dedicat.
No obstant això, hi ha serveis d'allotjament de repositoris remots en línia que faciliten la creació
i la gestió de repositoris remots.
Alguns dels serveis d'allotjament repositoris remots en línia més coneguts són:
GitHub: Servei d'allotjament de repositoris creat en 2008 i adquirit per Microsoft en 2018.
És el servei d'allotjament de repositoris de Git més utilitzat.
Ofereix una opció gratuïta, que permet crear projectes públics i privats, però amb algunes restriccions.
També ofereix plans de pagament per projectes empresarials.
GitLab: Servei d'allotjament de repositoris. GitLab és una plataforma de codi obert.
Bitbucket: Servei d'allotjament de repositoris propietat de l'empresa Atlassian,
s'integra estretament amb altres eines d'aquesta empresa, com Jira.
Fes clic a l'opció "New" per crear un nou repositori.
Omple el formulari amb la informació del teu repositori:
Nom del repositori. Ha de ser un nom únic en el teu compte de GitHub.
Descripció del repositori. Opcional.
Visibilitat del repositori. Pots triar entre públic o privat.
Públic: Qualsevol persona pot veure el teu repositori. Sols les persones autoritzades poden fer canvis.
Privat: Només tu i les persones que tu autoritzes poden veure el teu repositori. Sols les persones autoritzades poden fer canvis.
README: Indica si vols afegir un README al teu repositori.
.gitignore: Indica si vols afegir un fitxer .gitignore per ignorar fitxers en el teu repositori.
Llicència: Indica si vols afegir una llicència al teu repositori.
Exemple: Creació d'un repositori a GitHub
Creem un repositori amb les següents característiques:
Nom: git_remots
Descripció: Repositori del Bloc: Remots del curs "Introducció a Git i la seua aplicació a l’aula"
Visibilitat: Públic
README: No
.gitignore: No
Llicència: No
Una vegada omplert el formulari, fes clic a "Create repository" per crear el teu repositori.
El teu repositori s'hauria de crear buit i hauries de veure una pàgina com la següent:
La Figura 3 mostra els passos per enllaçar el teu repositori local amb el repositori remot creat a GitHub.
En els següents apartats, explicarem aquestes ordres amb més detall.
Un Token d'Accés Personal (Personal Access Token o PAT) és una clau d'accés
que permet autenticar-se amb el servidor de GitHub mitjançant el protocol HTTPS.
Mitjançant la contrasenya: Pots utilitzar el teu token d'accés personal com a contrasenya
per autenticar-te amb el servidor de GitHub.
jpuigcerver@fp:~$gitclonehttps://github.com/<usuari>/<repositori>
Cloning into '<repositori>'...Username for 'https://github.com': <usuari>Password for 'https://<username>@github.com': <token>
Note
Per seguretat, no es mostrarà res en el camp de la contrasenya.
Consell
Per tal de no haver de recordar el PAT cada vegada, és possible configurar
Git perquè ho recorde automàticament.
gitconfig--globalcredential.helperstore
Aquesta comanda guardarà les credencials en un fitxer de text en el teu sistema local.
Danger
Aquesta opció guarda les credencials en text pla en el fitxer ~/.git-credentials.
Per autenticar-te amb el servidor de GitHub mitjançant el protocol SSH,
has de configurar una clau SSH en el teu sistema local i afegir-la al teu compte de GitHub.
Per generar una clau SSH, segueix els següents passos.
Crea una clau SSH al teu sistema local mitjançant la comanda ssh-keygen.
jpuigcerver@fp:~$ssh-keygen-trsa-b4096Generating public/private rsa key pair.Enter file in which to save the key (/home/jpuigcerver/.ssh/id_rsa):Enter passphrase (empty for no passphrase):Enter same passphrase again:Your identification has been saved in /home/jpuigcerver/.ssh/id_rsa
-t rsa: Indica el tipus de clau RSA.
-b 4096: Indica la longitud de la clau en bits.
Pots indicar la ruta on guardar la clau. Per defecte, es guarda en /home/<usuari>/.ssh/id_rsa.
Pots indicar una contrasenya per protegir la clau. Si no vols protegir-la, deixa el camp buit.
Còpia el contingut de la clau pública (id_rsa.pub) al porta-retalls.
Per afegir un repositori remot, utilitzarem la comanda git remote add.
La sintaxi és la següent:
gitremoteadd<nom><url>
<nom>: Nom o àlies del repositori remot en el teu repositori local.
Normalment, s'utilitza el nom origin per referir-se al repositori remot principal.
<url>: URL del repositori remot.
Warning
Si intentes publicar amb git push
els canvis en un repositori remot
sense haver enllaçat el teu repositori local,
Git et mostrarà un missatge d'error:
jpuigcerver@fp:~/git_remots(main)$gitpush
fatal: No configured push destination.Either specify the URL from the command-line or configure a remote repository using git remote add <name> <url>and then push using the remote name git push <name>
Exemple: Afegir un repositori remot
Enllaçarem el nostre repositori local amb el repositori
remot creat anteriorment a GitHub.
La URL del repositori remot és git@github.com:jpuigcerver/git_remots.git(1).
L'ordre git remote remove permet eliminar un repositori remot
associat al teu repositori local.
La sintaxi és la següent:
gitremoteremove<nom>
<nom>: Nom del repositori remot a eliminar.
Associació entre branques locals i remotes (git push --set-upstream)¶
De moment, les branques que hem creat resideixen en el repositori local,
és a dir, en el nostre dispositiu.
Podem associar les branques locals a branques remotes, del repositori remot,
perquè els canvis que fem localment es puguen veure reflectits en el repositori remot.
Per fer-ho, utilitzarem la comanda git push amb l'opció -u o --set-upstream.
gitpush[-u|--set-upstream]<remot><branca>
-u|--set-upstream: Configura la branca local perquè s'associe amb la branca remota.
<remot>: Àlies del repositori remot (configurat amb git remote add).
Aquesta comanda funciona sobre la branca on estem situats (HEAD).
Consell
Pots configurar git perquè configure automàticament la branca local
perquè s'associe amb la branca remota amb el mateix nom
amb l'opció push.autoSetupRemote.
gitconfig--globalpush.autoSetupRemotetrue
Exemple: Associació branca local i remota
Vegem que inicialment la branca main no està associada a cap branca remota.
Si intentem fer un git push, ens mostrarà un missatge d'error com que
hem d'anar associar una branca remota.
jpuigcerver@fp:~/git_remots(main)$gitlga
*113f1d4-(4 seconds ago)Commit inicial-Joan Puigcerver(HEAD -> main)jpuigcerver@fp:~/git_remots(main)$gitpush
fatal: The current branch main has no upstream branch.To push the current branch and set the remote as upstream, use git push --set-upstream origin mainTo have this happen automatically for branches without a trackingupstream, see 'push.autoSetupRemote' in 'git help config'.
Associem les branques main local i remota amb l'ordre git push --set-upstream.
Localment, s'ha creat la referència origin/main que apunta a la branca remota main.
jpuigcerver@fp:~/git_remots(main)$gitpush--set-upstreamoriginmain
branch 'main' set up to track 'origin/main'.To github.com:joapuiib/git_remots.git * [new branch] main -> mainjpuigcerver@fp:~/git_remots(main)$gitlga
*113f1d4-(6 seconds ago)Commit inicial-Joan Puigcerver(HEAD -> main, origin/main)
Vegem que els canvis s'han publicat correctament al repositori remot:
L'ordre git clone permet copiar un repositori remot a un repositori local en el teu sistema,
des del qual podràs realitzar canvis.
Aquesta ordre còpia els continguts del Directori de Treball i tota la informació del Repositori Local,
incloent la història de canvis. A més, configura automàticament el repositori remot com a origin.
La sintaxi és la següent:
gitclone<url>[<directori>]
<url>: URL del repositori remot. Pot ser una URL HTTPS o SSH.
<directori>: Opcional. Nom del directori on es copiarà el repositori. Per defecte, es crea un directori amb
el nom del repositori remot.
Exemple: Clonació d'un repositori remot
Com que ja tenim els canvis publicats al repositori remot,
podem clonar el repositori remot al nostre sistema local.
Esborrem el directori git_remots i el clonarem des del repositori remot.
jpuigcerver@fp:~/git_remots(main)$cd~
jpuigcerver@fp:~$rm-rf~/git_remots
jpuigcerver@fp:~$ls-l~/git_remots
ls: cannot access '~/git_remots': No such file or directoryjpuigcerver@fp:~$gitclonegit@github.com:joapuiib/git_remots.git
Cloning into 'git_remots'...jpuigcerver@fp:~$cd~/git_remots
jpuigcerver@fp:~/git_remots(main)$gitlga
*113f1d4-(8 seconds ago)Commit inicial-Joan Puigcerver(HEAD -> main, origin/main, origin/HEAD)
S'observa que s'ha clonat correctament el repositori remot git_remots
que conté els fitxers i la història de canvis del repositori remot.
L'ordre git fetch actualitza la informació de les branques remotes origin/<branca>
al nostre repositori local, però no aplica els canvis a les nostres branques locals.
gitfetch[<options>][<remot>]
<options>: Opcions de la comanda.
<remot>: Àlies del repositori remot. Per defecte, s'utilitza origin.
Aquesta ordre és útil per obtindre la informació dels canvis realitzats en el repositori remot
i decidir si volem incorporar-los al nostre repositori local.
La fusió (merge) implícita de git pull pot ser una Fusió directa
o es pot produir una Fusió de branques divergents si
la branca local i la branca remota divergeixen.
En aquest últim cas:
Poden produir conflictes. Si es produeixen, caldrà resoldre'ls manualment.
Executar directament git pullgenerarà un commit de fusió,
que pot ser no és desitjable si es vol mantenir una història lineal.
Consell
Per evitar la fusió de branques divergents en git pull,
es pot fer el següent:
git pull --ff-only: Incorpora els canvis de la branca remota
només si es pot fer una fusió directa (fast-forward).
Git pot ser configurat perquè només permeta aquest tipus de fusió
en la comanda git pull.
git config --global pull.ff only
git pull --rebase: Incorpora els canvis de la branca remota
mitjançant un rebase, és a dir, aplica els canvis de la branca local
després dels canvis de la branca remota.
Aquest comportament també es pot configurar per defecte en la comanda git pull.
git config --global pull.rebase true
Exemple: Incorporació de canvis fusió directa (pull --ff-only)
Vegem com el commit 1b3b4b0 forma part de la branca remota origin/main,
però no de la branca local main.
Realitza els següents canvis en el repositori remot directament a GitHub.
Modifica el fitxer menjar.txt amb el següent contingut:
menjar.txt
Pa
Macarrons
Pomes
Crea un commit amb el missatge Més menjar.
Exemple: Incorporació de canvis amb fusió de branques divergents (pull --no-ff i pull --rebase)
Una de les situacions més comunes que ens porten a que la branca local divergisca de la branca remota és
quan realitzem canvis sobre la branca local sense haver sincronitzat abans el seu estat amb la branca remota associada.
En aquest cas, s'ha realitzat un altre canvi en el repositori remot,
que nosaltres no hem incorporat.
No obstant això, anem a fer un canvi a la branca local main,
simulant la situació anteriorment descrita.
En aquest moment, el nou canvi Més menjar no està reflectit en la branca remota origin/main.
En aquest moment, podríem intentar publicar aquest canvi al repositori remot,
però com que el repositori remot té canvis que no estan reflectits en el nostre repositori local,
Git ens mostrarà un missatge d'error.
jpuigcerver@fp:~/git_remots(main)$gitpush
To github.com:joapuiib/git_remots.git ! [rejected] main -> main (fetch first)error: failed to push some refs to 'github.com:joapuiib/git_remots.git'hint: Updates were rejected because the remote contains work that you do nothint: have locally. This is usually caused by another repository pushing tohint: the same ref. If you want to integrate the remote changes, usehint: 'git pull' before pushing again.hint: See the 'Note about fast-forwards' in 'git push --help' for details.jpuigcerver@fp:~/git_remots(main)$gitfetch
From github.com:joapuiib/git_remots 8594cb9..8c604a3 main -> origin/mainjpuigcerver@fp:~/git_remots(main)$gitlga
*95b8d62-(4 seconds ago)Beguda-Joan Puigcerver(HEAD -> main)| *8c604a3-(6 seconds ago)Més menjar-Joan Puigcerver(origin/main, origin/HEAD)|/ *8594cb9-(12 seconds ago)Menjar-Joan Puigcerver*113f1d4-(22 seconds ago)Commit inicial-Joan Puigcerver
Vegem que l'ordre git push ens recomana fer un git pull per incorporar els canvis,
ja que les dues branques han divergit.
Si executem git pull, es produirà una fusió de branques divergents, que crearà un commit de fusió
i resultarà en una història no lineal.
Vegem que no podem incorporar els canvis amb una fusió directa git pull --ff-only.
jpuigcerver@fp:~/git_remots(main)$gitpull--ff-only
hint: Diverging branches can't be fast-forwarded, you need to either:hint:hint: git merge --no-ffhint:hint: or:hint:hint: git rebasehint:hint: Disable this message with "git config advice.diverging false"fatal: Not possible to fast-forward, aborting.
En aquest cas, haurem d'incorporar els canvis de dues maneres diferents.
Un commit de fusió: git pull --no-ff.
Aquesta opció crearà un commit de fusió, que no és desitjable si es vol mantenir una història lineal.
jpuigcerver@fp:~/git_remots(main)$gitpull--no-ff--no-edit# (1)!Merge made by the 'ort' strategy. menjar.txt | 1 + 1 file changed, 1 insertion(+)jpuigcerver@fp:~/git_remots(main)$gitlga
*a0b012f-(1 second ago)Merge branch 'main' of github.com:joapuiib/git_remots-Joan Puigcerver(HEAD -> main)|\ | *8c604a3-(10 seconds ago)Més menjar-Joan Puigcerver(origin/main, origin/HEAD)* |95b8d62-(8 seconds ago)Beguda-Joan Puigcerver|/ *8594cb9-(16 seconds ago)Menjar-Joan Puigcerver*113f1d4-(26 seconds ago)Commit inicial-Joan Puigcerver
L'opció --no-edit indica que no volem editar el missatge de commit de fusió i deixem el missatge per defecte.
Un canvi de base: git pull --rebase.
Aquesta opció aplica els canvis de la branca local després dels canvis de la branca remota,
mantenint una història lineal.
En aquests apunts, hem treballat les diferents operacions de sincronització entre repositoris
sobre la branca principal main. Les mateixes operacions poden ser realitzades sobre altres branques
de la mateixa manera.