<div class="page"> <div class="cover text-center"> <img class="mx-auto" src=/itb/images/logo_mislata.png alt="logo"> # Repositori Remot <div class="text-end fit-content ms-auto my-3 mt-auto pt-3"> <p><strong>Autor:</strong> Joan Puigcerver Ibáñez</p> <p><strong>Correu electrònic:</strong> j.puigcerveribanez@edu.gva.es</p> <p><strong>Curs:</strong> 2024/2025</p> </div> <div> <p class="fw-bold mb-0">Llicència: BY-NC-SA</p> <p class="d-none d-md-block">(Reconeixement - No Comercial - Compartir Igual)</p> <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.ca" target="_blank"> <img class="mx-auto" src="/itb/images/license.png" alt="Licence"/> </a> </div><!--license--> </div><!--cover--> </div><!--page--> {:toc} ## Introducció Fins aquest moment ens hem centrat a estudiar quin és el funcionament d'un repositori de Git, conéixer la seua estructura i realitzar accions bàsiques per realitzar canvis sobre aquest. A més a més, també hem vist com es poden crear diferents branques per poder treballar d'una manera independent a l'estat de la branca principal i després, incorporar els canvis d'una branca a una altra. No obstant això, totes aquestes operacions s'han realitzat en __local__, és a dir, en el vostre dispositiu, i no s'han publicat els canvis enlloc. En aquest material ens centrarem amb què és un __repositori remot__ i les principals operacions de sincronització entre el repositori local i el repositori remot. ## Repositori Remot 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. #2.2[Repositori remot vinculat a múltiples repositoris locals](/itb/DAM-ED/UD2/img/git_material/02_remots/multiple_local_repo.png) 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. Alguns dels serveis d'allotjament repositoris remots en línia més coneguts són: - __[GitHub](https://github.com/)__: 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](https://gitlab.com/)__: Servei d'allotjament de repositoris. GitLab és una plataforma de codi obert. - __[BitBucket](https://bitbucket.org/)__: Servei d'allotjament de repositoris propietat de l'empresa Atlassian, s'integra estretament amb altres eines d'aquesta empresa, com Jira. ::: info Més informació: https://about.gitlab.com/competition/github/ ::: 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_). ## Publicar un repositori local existent En els materials anteriors vam crear el repositori `git_tutorial`, en el qual es van crear diferents commits de manera local. ```shell joapuiib@FP:~/git_tutorial (main) $ git lg * c9fc6c8 - (1 day ago) Changed README.md - Joan Puigcerver (HEAD -> main) * 8e70293 - (4 days ago) Added Readme.md - Joan Puigcerver ``` ### Creació Repositori Remot Ara l'objectiu és publicar aquests canvis a un _Repositori Remot_. El Repositori Remot pot estar allotjat en un servidor de l'empresa o en un servei d'allotjament. En el nostre cas, crearem un repositori en el servei d'allotjament GitHub. En la pàgina https://github.com/new pots crear un nou repositori i especificar les seues característiques, com el nom, la descripció i la visibilitat. #3.1.1[Captura de pantalla de la creació d'un Repositori Remot a GitHub](/itb/DAM-ED/UD2/img/git_material/remotes/repo_new.png) Una vegada creat, el repositori està buit i ens indiquen una sèrie de comandes per configurar el repositori. Anem a estudiar-les. #3.1.2[Captura de pantalla d'un Repositori Remot a GitHub el qual està buit](/itb/DAM-ED/UD2/img/git_material/remotes/repo_created.png) ### Afegir un remot Intentarem publicar els canvis mitjançant l'ordre `git push`: ```shell joapuiib@FP:~/git_tutorial (main) $ git push 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> ``` Com podeu observar, l'ordre `git push` ha fallat perquè el repositori local no té assignat cap repositori remot i no sap on ha de publicar els canvis. #3.2.1[Repositori Local no té cap remot configurat](/itb/DAM-ED/UD2/img/git_material/02_remots/unknown_remote.png) ::: docs Podeu consultar totes les opcions de `git remote` en el manual: ```bash man git remote # O bé... git remote --help ``` També disponible en línia: https://git-scm.com/docs/git-remote ::: #3.2.2[Repsitori Local es vincula amb un Repositori Remot](/itb/DAM-ED/UD2/img/git_material/02_remots/add_remote.png) L'ordre `git remote add` permet afegir un nou _Repositori Remot_: - `<remote>`: Nom del repositori remot. Normalment, s'utilitza el nom `origin` per definir l'àlies del remot. - `<url>`: Dirrecció URL del repositori remot. ```bash git remote add <remote> <url> ``` Afegim el repositori creat en GitHub: ```shell joapuiib@FP:~/git_tutorial (main) $ git remote add origin git@github.com:joapuiib/git_tutorial.git ``` ::: warning Vosaltres heu d'especificar l'enllaç del vostre repositori remot. ::: ::: note En aquest cas s'ha utilitzat l'enllaç SSH del repositori perquè hem configurat prèviament una clau SSH en el dispositiu. Veure: [Autentificació SSH](/itb/DAM-ED/UD1/materials/04_preparacio_entorn.html#autentificaci%C3%B3-ssh) ::: ### Mostrar i eliminar un remot L'ordre `git remote show` s'utilitza per mostrar tots els remots (pot ser més d'un!) del repositori. A més, podem veure més informació de cada remot configurat amb: ``` git remote show <remote> ``` En aquest cas: - __Fetch URL__: URL que s'utilitza per obtindre canvis. - __Push URL__: URL que s'utilitza per publicar canvis. - __HEAD branch__: Branca per defecte del repositori remot. De moment no hem publicat cap branca. ```shell joapuiib@FP:~/git_tutorial (main) $ git remote show origin joapuiib@FP:~/git_tutorial (main) $ git remote show origin * remote origin Fetch URL: git@github.com:joapuiib/git_tutorial.git Push URL: git@github.com:joapuiib/git_tutorial.git HEAD branch: (unknown) ``` Si es dessitja, es pot eliminar un remot amb: ```bash git remote remove <remote> ``` ### Publicació Una vegada ja s'ha configurat el remot, ja podem publicar els canvis amb `git push`: ```shell joapuiib@FP:~/git_tutorial (main) $ git push 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 main ``` #3.3.1[Es publiquen els canvis de la branca 'main' al Repositori Remot](/itb/DAM-ED/UD2/img/git_material/02_remots/push_setupstream.png) Podem observar que l'ordre `git push` ha tornat a fallar. En aquest cas ens indica que la branca actual `main` no té assignada cap branca en el remot i, per tant, no sap en quina branca ha de publicar els canvis. Per indicar la branca remota a la qual s'associa una branca local cal utilitzar l'opció `-u` o `--set-upstream`: - `--set-upstream` o `-u`: Opció per especificar la branca remota - `<remote>`: Nom del remot configurat. - `<remote_branch>`: Nom de la branca en el repositori remot. ```bash git push --set-upstream <remote> <remote_branch> ``` ```shell joapuiib@FP:~/git_tutorial (main) $ git push --set-upstram origin main Enumerating objects: 6, done. Counting objects: 100% (6/6), done. Delta compression using up to 12 threads Compressing objects: 100% (4/4), done. Writing objects: 100% (6/6), 526 bytes | 526.00 KiB/s, done. Total 6 (delta 1), reused 0 (delta 0) remote: Resolving deltas: 100% (1/1), done. To github.com:joapuiib/git_tutorial.git * [new branch] main -> main Branch 'main' set up to track remote branch 'main' from 'origin'. joapuiib@FP:~/git_tutorial (main) $ git lg * c9fc6c8 - (1 day ago) Changed README.md - Joan Puigcerver (HEAD -> main, origin/main, origin/HEAD) * 8e70293 - (4 days ago) Added Readme.md - Joan Puigcerver ``` Podeu observar que s'ha creat la branca `main` en el repositori remot i s'ha creat la referència `origin/main` i `origin/HEAD`. També podem consultar els canvis publicats en el repositori remot: #3.3.2[Estat del repositori remot a GitHub després del push](/itb/DAM-ED/UD2/img/git_material/remotes/repo_push.png) Una vegada fet el push, podem tornar a consultar les dades del remot `origin`: ```shell joapuiib@FP:~/git_tutorial (main) $ git remote show origin * remote origin Fetch URL: git@github.com:joapuiib/git_tutorial.git Push URL: git@github.com:joapuiib/git_tutorial.git HEAD branch: main Remote branch: main tracked Local branch configured for 'git pull': main merges with remote main Local ref configured for 'git push': main pushes to main (up to date) ``` - __HEAD branch__: La branca per defecte del repositori remot ha canviat a la branca `main`. - __Remote branch__: Ens indica que la branca actual està associada en la branca remota `main`. - __Local branch configured for 'git pull'__: Ens indica com s'incorporen els canvis de la branca actual des del repositori remot al repositori local quan s'executa `git pull`. - __Local branch configured for 'git push'__: Ens indica la branca del repositori remot on es publicaran els canvis efectuats en el repositori local quan s'executa la branca `git push`. ## Clonar un repositori remot En l'apartat anterior hem publicat un repositori local i sincronitzat els seus canvis amb un repositori remot buit. #4.1[Clonació d'un repositori remot](/itb/DAM-ED/UD2/img/git_material/02_remots/clone.png) Imagineu que hem compartit aquest repositori amb una altra persona. Aquesta persona necessita fer el contrari, _descarregar-se_ el repositori remot a un repositori local. Aquesta acció es pot dur a terme amb l'ordre `git clone`: - `<repository_url>`: Dirrecció URL del repositori remot. - `[<directory>`]: Paràmetre opcional que permet especificar el nom del directori on es clonarà el repositori remot. Per defecte té el mateix nom que el repositori remot. ``` git clone <repository_url> [<directory>] ``` Per il·lustrar aquest exemple ens imaginarem que hem compartit el repositori amb Pau. Clonem el repositori en el directori `git_tutorial_pau`, on Pau realitzarà els seus canvis. ::: note Per a indicar la persona que fa els canvis, es mostrarà un nom d'usuari diferent en el _prompt_ de la terminal. ::: ```shell pau@FP:~ $ git clone git@github.com:joapuiib/git_tutorial.git git_tutorial_pau Cloning into 'git_tutorial_pau'... remote: Enumerating objects: 6, done. remote: Counting objects: 100% (6/6), done. remote: Compressing objects: 100% (3/3), done. remote: Total 6 (delta 1), reused 6 (delta 1), pack-reused 0 Receiving objects: 100% (6/6), done. Resolving deltas: 100% (1/1), done. pau@FP:~ $ cd git_tutorial_pau/ pau@FP:~/git_tutorial_pau (main) $ cd git_tutorial_pau/ pau@FP:~/git_tutorial_pau (main) $ ls README.md pau@FP:~/git_tutorial_pau (main) $ git lg * c9fc6c8 - (1 day ago) Changed README.md - Joan Puigcerver (HEAD -> main, origin/main, origin/HEAD) * 8e70293 - (4 days ago) Added Readme.md - Joan Puigcerver pau@FP:~/git_tutorial_pau (main) $ git remotes show origin * remote origin Fetch URL: git@github.com:joapuiib/git_tutorial.git Push URL: git@github.com:joapuiib/git_tutorial.git HEAD branch: main Remote branch: main tracked Local branch configured for 'git pull': main merges with remote main Local ref configured for 'git push': main pushes to main (up to date) ``` S'ha realitzat el següent: - `git clone`: S'ha clonat el repositori en el directori `git_tutorial_pau`. - `cd`: Ens situem dins del directori. - `ls`: Mostrem els continguts. Vegem que és el contingut que teniem en el repositori remot. - `git lg`: S'observa que també s'ha copiat informació del repositori, com la història de _commits_. També inclou informació sobre on se situen les branques remotes `origin/main` i `origin/HEAD`. - `git remotes show`: Quan es clona el repositori, automàticament s'afegeix el remot `origin` i el _upstream_ de la branca principal. En aquest punt, Pau pot fer canvis i contribuir en el repositori. ::: note S'ha realitzat una configuració en el repositori per indicar que els canvis els està realitzant Pau. S'ha utilitzat l'ordre `git config` sense el paràmetre `--global` per indicar que aquesta configuració sols afecta a aquest repositori. ::: ```shell pau@FP:~/git_tutorial_pau (main) $ git config user.name "Pau" pau@FP:~/git_tutorial_pau (main) $ git config user.email "pau@fpmislata.com" pau@FP:~/git_tutorial_pau (main) $ echo "Modificació de Pau" > pau.txt pau@FP:~/git_tutorial_pau (main) $ cat pau.txt Modificació de Pau pau@FP:~/git_tutorial_pau (main) $ git status On branch master No commits yet Untracked files: (use "git add <file>..." to include in what will be committed) .red{pau.txt} nothing added to commit but untracked files present (use "git add" to track) pau@FP:~/git_tutorial_pau (main) $ git add pau.txt pau@FP:~/git_tutorial_pau (main) $ git commit -m "Modificació de Pau" pau@FP:~/git_tutorial_pau (main) $ git lg * bdbfcb2 - (1 second ago) Modificació de Pau - Pau (HEAD -> main) * c9fc6c8 - (1 day ago) Changed README.md - Joan Puigcerver (origin/main, origin/HEAD) * 8e70293 - (4 days ago) Added Readme.md - Joan Puigcerver pau@FP:~/git_tutorial_pau (main) $ git status On branch main Your branch is ahead of 'origin/main' by 1 commit. (use "git push" to publish your local commits) nothing to commit, working tree clean ``` Pau ha realitzat un nou _commit_ en el repositori on ha afegit el fitxer __pau.txt__. Observem en `git status` que ens indica que podem publicar aquest nou canvi mitjançant `git push`. ```shell pau@FP:~/git_tutorial_pau (main) $ git push Enumerating objects: 4, done. Counting objects: 100% (4/4), done. Delta compression using up to 12 threads Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 297 bytes | 297.00 KiB/s, done. Total 3 (delta 0), reused 0 (delta 0) To github.com:joapuiib/git_tutorial.git c9fc6c8..bdbfcb2 main -> main pau@FP:~/git_tutorial_pau (main) $ git status On branch main Your branch is up to date with 'origin/main'. nothing to commit, working tree clean pau@FP:~/git_tutorial_pau (main) $ git lg * bdbfcb2 - (1 second ago) Modificació de Pau - Pau (HEAD -> main, origin/main, origin/HEAD) * c9fc6c8 - (1 day ago) Changed README.md - Joan Puigcerver * 8e70293 - (4 days ago) Added Readme.md - Joan Puigcerver ``` Observem que després de fer el `push`, el `status` ja ens indica que estem al dia i s'han actualitzat les referències del repositori remot `origin/main` i `origin/HEAD`. Si consultem el repositori remot, podrem veure els canvis publicats. ## Incorporar canvis des del remot En aquest moment, Pau ha contribuït en el repositori, però nosaltres encara no ho sabem. Aquest és l'estat del nostre repositori: ```shell joapuiib@FP:~/git_tutorial (main) $ git lg * c9fc6c8 - (1 day ago) Changed README.md - Joan Puigcerver (HEAD -> main, origin/main, origin/HEAD) * 8e70293 - (4 days ago) Added Readme.md - Joan Puigcerver ``` Podem comprovar si han hagut modificacions o nous canvis en el repoitori remot mitjançant l'ordre `git fetch`. #5.1[Operació `fetch` en un repositori de Git](/itb/DAM-ED/UD2/img/git_material/02_remots/fetch.png) La comanda `git fetch` s'utilitza per recuperar els canvis des del repositori remot, però no els incorpora a la branca actual. ```shell joapuiib@FP:~/git_tutorial (main) $ git fetch remote: Enumerating objects: 4, done. remote: Counting objects: 100% (4/4), done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 0), reused 3 (delta 0), pack-reused 0 Unpacking objects: 100% (3/3), 277 bytes | 277.00 KiB/s, done. From github.com:joapuiib/git_tutorial c9fc6c8..bdbfcb2 main -> origin/main joapuiib@FP:~/git_tutorial (main) $ git status On branch main Your branch is behind 'origin/main' by 1 commit, and can be fast-forwarded. (use "git pull" to update your local branch) nothing to commit, working tree clean joapuiib@FP:~/git_tutorial (main) $ git lga * bdbfcb2 - (5 hours ago) Modificació de Pau - Pau (origin/main, origin/HEAD) * c9fc6c8 - (1 day ago) Changed README.md - Joan Puigcerver (HEAD -> main) * 8e70293 - (4 days ago) Added Readme.md - Joan Puigcerver joapuiib@FP:~/git_tutorial (main) $ ls README.md joapuiib@FP:~/git_tutorial (main) $ cat pau.txt cat: pau.txt: No such file or directory ``` S'observa que la referència `origin/main` ha avançat i ha aparegut el nou _commit_ que ha fet Pau. No obstant la referència `main` no ha canviat i no existeix el fitxer __pau.txt__. La comanda `git status` ens indica que la branca local està enrederida respecte a la branca del repositori remot i com podem integrar els canvis amb `git pull`. #[Operació `pull` en un repositori de Git](/itb/DAM-ED/UD2/img/git_material/02_remots/pull.png) Si volem incorporar els canvis, hem de llançar l'ordre `git pull`, que fusionarà els canvis entre la branca remota i la branca local mitjançant un `merge`. Aquesta ordre executa primer un `git fetch` per comprovar si hi ha nous canvis en el repositori remot. ::: note La fusió entre branques `merge` s'estudia en el següent material. ::: ```shell joapuiib@FP:~/git_tutorial (main) $ git pull Updating c9fc6c8..bdbfcb2 Fast-forward pau.txt | 1 .green{+} 1 file changed, 1 insertion(+) create mode 100644 pau.txt joapuiib@FP:~/git_tutorial (main) $ git status On branch main Your branch is up to date with 'origin/main'. nothing to commit, working tree clean joapuiib@FP:~/git_tutorial (main) $ git lga * bdbfcb2 - (5 hours ago) Modificació de Pau - Pau (HEAD -> main, origin/main, origin/HEAD) * c9fc6c8 - (1 day ago) Changed README.md - Joan Puigcerver * 8e70293 - (4 days ago) Added Readme.md - Joan Puigcerver joapuiib@FP:~/git_tutorial (main) $ cat pau.txt Modificació de Pau ``` Una vegada executada l'ordre `git pull`, podem observar que la referència `main` ja està en el _commit_ realitzat per Pau i que els canvis que ha realitzat existeixen en el nostre repositori i directori de treball. ## Recursos addicionals - Curs de Git des de zero per MoureDev: https://www.youtube.com/watch?v=3GymExBkKjE&ab_channel=MoureDevbyBraisMoure - https://github.com/UnseenWizzard/git_training ## Bibliografia - https://github.com/UnseenWizzard/git_training - https://about.gitlab.com/competition/github/