Gitlab - Repositori

  • Introducció

    Git és un sistema de control de versions descentralitzat.

    De totes maneres, és habitual allotjar el codi en un repositori remot per compartir codi amb altres, encara que només sigui amb tu mateix i els teus diferents equips i entorns d’execució.

    Usuari

    Si mai t’has registrat a Gitlab, el primer que has de fer és anar a aquest enllaç: Users - Sign In

    I a continuació registrar-te:

    Al final tindras un usuari amb la teva identitat:

    Projecte

    Crea un nou projecte:

    Escull Create blank project:

    Omple les dades que et demanen.

    L’slug del projecte forma part de l’URL del projecte.

    Ja pots crear el projecte!

    Com que ha deixat l’opció per defecte d’inicialitzar el repositori amb un fitxer README, aquest s’ha creat amb un commit inicial.

    SSH

    Per defecte, quan crees un repositori aquest és privat.

    Per accedir a un repositori remot privat, o modificar el contingut de qualsevol repositori (sigui públic o privat) necessites un sistema d’autenticació.

    Un clau “ssh” et permet identificar-te amb un servidor remot.

    Genera un parell de claus SSH tal com s’explica a: SSH

    ssh-keygen

    Fes clic a la teva icona d’usuari i selecciona Edit Profile

    A continuació selecciona SSH Keys.

    Mira quina és la clau pública que has generat:

    gc ~/.ssh/id_ed25519.pub
    ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFJgYeQKuRlSp6BOSaVriPqJ5IKakDpHLfP4csIN8Ft/ david@elite

    Afegeix la teva clau pública a GitLab:

    Verifica que et pots autenticar amb els servidors de Gitlab:

    ssh -T git@gitlab.com
    Welcome to GitLab, @ddemingo!

    Local

    Ves al projecte que has creat abans:

    Copia l’URL del projecte per clonar amb SSH:

    Obre una sessió de terminal amb Powershell.

    Clona el repositori en la màquina local amb la teva clau SSH:

    git clone git@gitlab.com:ddemingo/poesia.git
    Cloning into 'poesia'...
    remote: Enumerating objects: 3, done.
    remote: Counting objects: 100% (3/3), done.
    remote: Compressing objects: 100% (2/2), done.
    remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
    Receiving objects: 100% (3/3), done.

    Ja pots escriure la primera estrofa de la teva primera poesia:

    cd poesia
    notepad ara-mateix.txt

    Fes el commit corresponent:

    git add .\ara-mateix.txt
    git commit -a -m "Afegit primera estrofa del poema 'Ara mateix' de Miquel Martí i Pol"
    [main ade00cb] Afegit primera estrofa del poema 'Ara mateix' de Miquel Martí i Pol
     1 file changed, 5 insertions(+)
     create mode 100644 ara-mateix.txt

    El repositori local està configurat amb el repositori remot de Gitlab:

    git remote -v
    origin  git@gitlab.com:ddemingo/poesia.git (fetch)
    origin  git@gitlab.com:ddemingo/poesia.git (push)

    A continuació actualitza els teus commits al repositori remot de Gitlab:

    git push
    Enumerating objects: 4, done.
    Counting objects: 100% (4/4), done.
    Delta compression using up to 24 threads
    Compressing objects: 100% (3/3), done.
    Writing objects: 100% (3/3), 472 bytes | 472.00 KiB/s, done.
    Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
    To gitlab.com:ddemingo/poesia.git
       f7180ad..ade00cb  main -> main

    En qualsevol moment pots enviar tots els canvis que has fet al repositori remot.

    HTTPS

    Crea una màquina Linux amb Windows Subsystem for Linux (WSL) o Isard.

    PENDENT Continuarem el proper dia.

    Ves a la Web IDE i refresca la pàgina web (pots fer servir la tecla F5) per veure els canvis que has escrit al repositori remot.

    Modifica el fixer main.py:

    Fes un commit a la branca main:

    Torna al terminal i verifica que el teu repositori local està sincronitzat amb la comanda git status:

    $ git status
    On branch main
    Your branch is up to date with 'origin/main'.
    
    nothing to commit, working tree clean

    Pots veure que segons aquesta comanda la branca main està sincronitzada amb origin/main

    Però si mires el contingut del fitxer main.py pots veure que no és així

    El motiu és que main i origin/main apunten al mateix commit:

    origin/main0-8198f751-8b6240b2-b66eddemain

    Fetch

    Git no permet sincronitzar codi sense que tu no aprovis els canvis que es faran a la teva còpia local, és una qüestió de seguretat i confiança. En aquest cas ets tu, des d’un altre entorn que has fet els canvis, però en la majoria dels casos no és així si treballes amb altra gent i aquests amb altra gent.

    El primer que has de fer és un git fetch:

    git fetch origin
    Unpacking objects: 100% (3/3), 304 bytes | 101.00 KiB/s, done.
    From https://gitlab.com/ddemingo/daw
    914c179..c3e3ef6 main -> origin/main

    Pots veure que es llegeixen els canvis que s’han escrit al repositori remot.

    Per veure els “commits” que s’han afegit a l‘“upstream main”, pots executar la comanda git log fent servir origin/main com a filtre:

    $ git log --oneline main..origin/main
    c3e3ef6 (origin/main, origin/HEAD) if-else

    Pots veure que l’únic canvi que s’ha fet és el commit “if-else”.

    Però no pots veure aquests canvis perquè el punter main no ha avançat

    origin/main0-00380e01-e8c145e2-c2c8e9bmain3-950e8094-9d0b3d8

    Executa aquesta comanda:

    $ git log origin/main
    commit c3e3ef64f04735da05b33cd9e0e853b4b046b53e (origin/main, origin/HEAD)
    Author: David de Mingo <david@optersoft.com>
    Date: Mon Apr 10 15:17:02 2023 +0000
    
    if-else
    
    commit 914c179cb86d7b362ee8f708765a7145b6c629c8 (HEAD -> main)
    Author: David de Mingo <ddemingo@xtec.cat>
    Date: Mon Apr 10 14:36:10 2023 +0000
    
    fem servir un if

    Pots veure que HEAD -> main apunta a un commit diferent que origin/main i origin/HEAD.

    Pots canviar a origin/main amb la comanda git checkout:

    $ git checkout origin/main
    $ python3 main.py
    x is not 1

    El resultat és x is not 1.

    Pots tornar a main amb la comanda git checkout:

    $ git checkout main
    $ python3 main.py
    x is 1

    El resultat torna a ser x is 1.

    Merge

    Si els canvis et semblen bé pots fer un merge:

    $ git merge origin/main

    Després del merge main i origin/main tornen a coincidir:

    origin/main0-3185e94main1-66773762-b7399d7

    I si ara fas un git log pots veure que tots els punters apunten al mateix commit:

    $ git log
    commit c3e3ef64f04735da05b33cd9e0e853b4b046b53e (HEAD -> main, origin/main, origin/HEAD)
    Author: David de Mingo <david@optersoft.com>
    Date: Mon Apr 10 15:17:02 2023 +0000
    
    if-else

    Pull

    El que aviat aprendràs és que la majoria de la gent vol anar de pressa i confia en els altres perquè es va més de pressa. I que passa amb la seguretat? Doncs passa el que passa

    Ves a la Web IDE, torna a modificar el fitxer main.py:

    list = ["barcelona","girona","tarragona"]
    for city in list:
    print(city)

    Fes el commit corresponent (recorda de fer el commit a la branca main!)

    Ara anirem de pressa sense verificar res amb la comanda git pull (és com fer un fetch i un merge a la vegada):

    $ git pull

    I pots verificar que el repositori local s’ha sincronitzat amb el repositori remot:

    $ python3 main.py
    barcelona
    girona
    tarragona

    Posem-nos d’acord

    El que aviat descobriràs és que si no ens posem d’acord les coses no són tan fàcils com sembla.

    Ves a la Web IDE, torna a modificar el fitxer main.py:

    map = {"Portugal": "Lisboa", "França": "París"}
    print(map["Portugal"])

    Fes el commit corresponent (recorda de fer el commit a la branca main!)

    Modifica el fitxer main.py del repositori local:

    tuple = ( "David", 51, "Barcelona")
    print(tuple[0])

    Fes el commit corresponent:

    $ git commit -a -m "tuple"

    Ara tenim un problema, saps quin és? Ho pots imaginar, i git és conscient del problema si fas un git pull:

    $ git pull
    From https://gitlab.com/ddemingo/daw
    29c2140..876bb66 main -> origin/main
    hint: You have divergent branches and need to specify how to reconcile them.
    hint: You can do so by running one of the following commands sometime before
    hint: your next pull:
    hint:
    hint: git config pull.rebase false # merge (the default strategy)
    hint: git config pull.rebase true # rebase
    hint: git config pull.ff only # fast-forward only

    El que has de fer en aquesta situació és crear una branca nova per conservar els teus canvis:

    $ git branch conflict

    A continuació has de fer un “reset” de la teva branca principal a l’estat en què està la branca origin/main:

    git reset --hard origin/main

    Si executes el fitxer main.py pots veure que s’està executant el codi que has escrit mitjançant la Web IDE:

    $ python3 main.py
    Lisboa

    Resoldre el conflicte

    Fem un merge de la branca conflict

    $ git merge conflict
    Auto-merging main.py
    CONFLICT (content): Merge conflict in main.py
    Automatic merge failed; fix conflicts and then commit the result.

    El resultat de la comanda ens indica que tenim un conflicte en el fitxer main.py que git no pot resoldre de manera automàtica:

    Edita el fitxer main.py:

    <
    <
    <
    <
    <
    << HEAD
    map={"Portugal": "Lisboa", "França": "París"}
    
    print(map["Portugal"])
    =======
    tuple = ( "David", 51, "Barcelona")
    print(tuple[0])
    >>>>>>> conflict

    Que git no sàpida resoldre el conflicte no vol dir que no sàpiga exactament quin és el conflicte, i t’indica clarament en el fitxer main.py quin és el conflicte.

    Resol el conflicte. Per exemple, pots deixar els dos segments de codi:

    map = {"Portugal": "Lisboa", "França": "París"}
    print(map["Portugal"])
    
    tuple = ( "David", 51, "Barcelona")
    print(tuple[0])

    Un cop resolt el conflicte ja pots fer el commit i el push corresponent:

    git commit -a -m "merged tuple in main.py"
    git push

    També pots esborrar la branca conflict que ja no et fa falta.

    $ git branch -d conflict

    Auto-merging

    Pràctica

    Aquesta pràctica es fa en grups de dos alumnes.

    Suposem que són la Núria i en Joan.

    1. La Núria ha de crear un repositori remot al seu compte de Gitlab, i afegir al Joan com a membre del projecte.

    A la pàgina del projecte fes clic a Project Information > Members:

    Invita a l’alumne B amb el rol Maintainer:

    A la pàgina members apareixarà l’alumne B.

    2. El Joan ha de clonar el projecte, crear el fitxer data.py, fer un commit i un push:

    courses = ["Python", "Java"]
    enrollments = []
    students = ["Eva", "Marc"]

    3. La Núria ha de clonar el projecte, crear el fitxer admin.py, fer un commit i un push:

    import data
    
    def enroll(course, student):
    if student in data.students and course in data.courses:
    data.enrollments.append((course,student))
    return True
    return False

    5. El Joan ha de fer un fetch + merge, crear el fitxer main.py, fer un commit i un push:

    import admin
    import data
    
    assert "Eva" == data.students[0]
    assert True == admin.enroll("Python","Eva")
    
    print("It's working!")

    6. La Nuria ha de fer un fetch + merge.

    Executa el fitxer main.py:

    $ python3 main.py

    Veuràs que es crea una carpeta __pycache__ que no s’ha d’incorporar al control de versions.

    Has de crear un fitxer .gitignore amb aquest contingut:

    /__pycache__

    Fes un commit i un push.

    7. A continuació heu d’anar millorant el codi de manera interactiva: cada alumne en el seu ordinador i compartint les modificacions amb git push i git pull.

    Per exemple:

    • Afegir més estudiants als cursos
    • Afegir més cursos
    • Afegir les dades de teachers
    • Afegir una funció is_enrolled(course,student) al fitxer admin.py
    • Que la funció enroll(course,student) verifiqui que l’alumne no estigui matriculat al curs.

    L’objectiu és que aprengueu a fer servir git per treballar en equip, i de pas, una mica més de python.

    Pendent