Esercizio - Collaborare usando un repository condiviso
Il pull diretto dal repository di un altro utente riesce a condizione che ci si trovi entrambi nella stessa rete. Tuttavia, si tratta di un processo inefficace e la maggior parte dei collaboratori non si trova nella stessa rete. È preferibile configurare un repository centrale da cui e verso cui tutti i collaboratori possano eseguire il pull e il push.
Si supponga di parlare del proprio progetto a Bob, un amico sviluppatore, e che Bob chieda di partecipare. Questo è un caso ideale in cui configurare un repository centrale, denominato anche repository bare.
Creare un repository bare
È necessario un repository che non abbia un albero di lavoro. Un repository bare presenta diversi vantaggi rispetto a un albero di lavoro:
- Senza un albero di lavoro, tutti possono eseguire il push delle modifiche senza doversi preoccupare del ramo estratto.
- È facile per Git rilevare quando un altro utente ha eseguito il push di modifiche che possono essere in conflitto con le proprie.
- Un repository condiviso può essere usato da un numero qualsiasi di sviluppatori. Con un repository bare, è necessario identificare solo il repository condiviso, senza sapere nulla di quelli di tutti gli altri collaboratori dai quali può essere necessario eseguire il pull.
- Posizionando il repository condiviso in un server accessibile a tutti, non è necessario preoccuparsi di firewall e autorizzazioni.
- Non sono necessari account separati nel server, perché Git tiene traccia di chi ha eseguito ogni commit. GitHub ha milioni di utenti che condividono tutti l'account
git
. Tutti usano il protocollo di rete crittografico Secure Shell (SSH) e gli utenti vengono distinti tramite le rispettive chiavi pubbliche.
La creazione di un repository bare per la condivisione è semplice:
Creare una nuova directory denominata Shared.git allo stesso livello delle directory Alice e Cats in cui inserire il repository bare:
cd .. mkdir Shared.git cd Shared.git
Il nome della directory non è importante, ma in questi esercizi vi si farà riferimento come directory Shared.git o semplicemente directory shared.
L'assegnazione del nome Shared.git alla directory segue la lunga tradizione di assegnare ai repository bare un nome che termina con
.git
per distinguerli dagli alberi di lavoro. Si tratta di una convenzione, non di un requisito.Usare ora il comando seguente per creare un repository bare nella directory condivisa:
git init --bare
Quando un repository è ancora bare, non è possibile usare il comando
git checkout
per impostare il nome del ramo predefinito. A questo scopo, è possibile modificare il ramoHEAD
in modo che punti a un ramo diverso, in questo caso il ramomain
:git symbolic-ref HEAD refs/heads/main
Il passaggio successivo consiste nell'inserire il contenuto del proprio repository nel repository condiviso. Usare questi comandi per tornare alla directory del progetto in cui è archiviato il repository, configurare un repository remoto
origin
ed eseguire un push iniziale:cd ../Cats git remote add origin ../Shared.git git push origin main
Controllare l'output di . L'output indica che l'operazione è riuscita:
Counting objects: 12, done. Delta compression using up to 2 threads. Compressing objects: 100% (8/8), done. Writing objects: 100% (12/12), 1.07 KiB | 0 bytes/s, done. Total 12 (delta 1), reused 0 (delta 0) To ../Shared.git * [new branch] main -> main
I rami
push
epull
devono usare il ramomain
diorigin
per impostazione predefinita, come se il repository fosse stato creato tramite clonazione sin dall'inizio. Ma prima di tutto, è necessario indicare a Git il ramo di cui tenere traccia.git branch --set-upstream-to origin/main
Verificare questo output:
Branch main set up to track remote branch main from origin.
Git genera un errore se si tenta di eseguire questo comando prima del push iniziale, perché il nuovo repository non ha rami. Git non può tenere traccia di un ramo che non esiste. In background Git cerca in
.git/refs/remotes/origin
un file denominato trunk.
Eseguire la configurazione per i collaboratori
Nel passaggio successivo Bob deve clonare il repository bare e quindi Alice deve impostare il repository origin nel proprio repository come destinazione del repository condiviso per le operazioni di push e pull.
Creare una directory denominata Bob che sia di pari livello rispetto alla directory del progetto e quindi passare alla directory Bob:
cd .. mkdir Bob cd Bob
Clonare ora il repository condiviso, assicurandosi di includere il punto alla fine del comando:
git clone ../Shared.git .
Attualmente il repository di Alice è configurato per il push e il pull da e verso il proprio repository. Usare i comandi seguenti per passare alla directory Alice e modificare
origin
in modo che punti al repository condiviso:cd ../Alice git remote set-url origin ../Shared.git
Iniziare a collaborare
Ora che Bob può collaborare al sito Web, decide di aggiungere un piè di pagina in fondo alla pagina. Assumere il ruolo di Bob e Alice per alcuni istanti e apprendere le nozioni di base della collaborazione.
Per iniziare, passare alla directory Bob e operare come Bob:
cd ../Bob git config user.name Bob git config user.email bob@contoso.com
Aprire index. html e sostituire l'elemento
<hr>
con questa riga (presente alla fine dell'elemento<body>
):<footer><hr>Copyright (c) 2021 Contoso Cats</footer>
Salvare quindi il file e chiudere l'editor.
Eseguire il commit e il push delle modifiche nel repository remoto origin:
git commit -a -m "Put a footer at the bottom of the page" git push
Controllare l'output di . Se viene visualizzato un avviso come nell'esempio seguente, non è un problema. L'avviso comunica semplicemente agli utenti una variazione rispetto ai comportamenti predefiniti di Git. Per non visualizzare più l'avviso, è possibile eseguire
git config --global push.default simple
.warning: push.default is unset; its implicit value has changed in Git 2.0 from 'matching' to 'simple'. To squelch this message and maintain the traditional behavior, use: git config --global push.default matching To squelch this message and adopt the new behavior now, use: git config --global push.default simple When push.default is set to 'matching', git will push local branches to the remote branches that already exist with the same name. Since Git 2.0, Git defaults to the more conservative 'simple' behavior, which only pushes the current branch to the corresponding remote branch that 'git pull' uses to update the current branch. See 'git help config' and search for 'push.default' for further information. (the 'simple' mode was introduced in Git 1.7.11. Use the similar mode 'current' instead of 'simple' if you sometimes use older versions of Git)
Mentre Bob sta modificando il sito, anche Alice sta facendo la stessa cosa. Alice decide di aggiungere una barra di spostamento alla pagina. Per questa aggiunta, Alice deve modificare due file: index.html e site.css. Per iniziare, tornare alla directory Alice:
cd ../Alice
Aprire ora index.html e inserire la riga seguente dopo il tag
<body>
alla riga 8:<nav><a href="./index.html">home</a></nav>
Salvare quindi il file e chiudere l'editor.
Aprire quindi site.css nella cartella CSS e aggiungere la riga seguente alla fine:
nav { background-color: #C0D8DF; }
Salvare il file e chiudere l'editor.
Si supponga ora che Alice riceva un messaggio e-mail da Bob che segnala che Bob ha apportato modifiche al sito. Alice decide di eseguire il pull delle modifiche di Bob prima del commit delle sue modifiche. Se Alice avesse già eseguito il commit delle proprie modifiche, avrebbe avuto un problema diverso, che verrà illustrato in un altro modulo. Alice esegue questo comando:
git pull
Controllare l'output di . Dall'output sembra che Git abbia evitato un problema:
remote: Counting objects: 3, done. remote: Compressing objects: 100% (3/3), done. remote: Total 3 (delta 2), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. From ../Shared 843d142..2cf6cbf main -> origin/main Updating 843d142..2cf6cbf error: Your local changes to the following files would be overwritten by merge: index.html Please commit your changes or stash them before you can merge. Aborting
Git avvisa che il pull sovrascriverebbe la versione di Alice di index.html e le modifiche di Alice andrebbero perse. Ciò è dovuto al fatto che anche Bob ha modificato index.html. Se Alice non avesse modificato index.html, Git avrebbe eseguito il commit del merge.
Usare un comando
git diff
per visualizzare le modifiche apportate da Bob a index.html:git diff origin -- index.html
Controllare l'output di . Dall'output è evidente che le modifiche di Alice e quelle di Bob non si sovrappongono. Alice può ora accantonare le proprie modifiche.
git stash
salva lo stato dell'albero di lavoro e dell'indice eseguendo un paio di commit temporanei. È possibile pensare all'accantonamento come un modo per salvare il lavoro corrente mentre si esegue un'altra operazione, senza eseguire un commit "reale" o influire sulla cronologia del repository.In realtà, Alice avrebbe dovuto accantonare le modifiche o eseguirne il commit prima di provare a eseguire il pull. Il pull in un albero di lavoro modificato ma non salvato è rischioso, perché può comportare operazioni da cui non è facile eseguire il ripristino.
Usare il comando seguente per accantonare le modifiche di Alice:
git stash
Controllare l'output di . Sarà simile a questo esempio:
Saved working directory and index state WIP on main: 95bbc3b Change background color to light blue HEAD is now at 95bbc3b Change background color to light blue
Alice può ora eseguire il pull in tutta sicurezza, quindi può "prelevare" le modifiche accantonate, organizzate come stack.
git stash
è infatti la versione abbreviata digit stash push
. Lo stack è molto simile alla pila in cui vengono collocate le fatture ancora da pagare. Eseguire questi comandi:git pull git stash pop
Il prelievo delle modifiche accantonate comporta il merge delle modifiche. Se le modifiche si sovrappongono, può verificarsi un conflitto. Le informazioni su come risolvere queste situazioni sono disponibili in un modulo più avanzato su Git di Microsoft Learn.
Controllare l'output di . Alice visualizzerà questo output, che indica che il merge è riuscito e che le modifiche sono state ripristinate, ma non ancora preparate per il commit:
Auto-merging index.html On branch main Your branch is up-to-date with 'origin/main'. Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: CSS/site.css modified: index.html no changes added to commit (use "git add" and/or "git commit -a") Dropped refs/stash@{0} (0cfb7b75d56611d9fc6a6ab660a51f5582b8d9c5)
A questo punto Alice può continuare a lavorare o semplicemente eseguire il commit e il push delle modifiche. Apportare un'altra modifica nelle vesti di Alice assegnando ai piè di pagina lo stesso stile delle barre di spostamento.
Aprire site.css nella cartella CSS e sostituire la terza riga, che definisce lo stile degli elementi
<nav>
, con questa regola CSS condivisa. Quindi, come di consueto, salvare le modifiche e chiudere l'editor.nav, footer { background-color: #C0D8DF; }
Eseguire ora il commit e il push delle modifiche nel repository condiviso:
git commit -a -m "Stylize the nav bar" git push
Il sito aggiornato si trova ora nel repository condiviso.
Terminare tornando alla directory del progetto ed eseguendo un pull:
cd ../Cats git pull
Aprire index.html (quello nella directory del progetto) per verificare che le modifiche apportate da Bob e Alice siano presenti nel repository locale. Verificare che index.html includa il codice più aggiornato:
<!DOCTYPE html> <html> <head> <meta charset='UTF-8'> <title>Our Feline Friends</title> <link rel="stylesheet" href="CSS/site.css"> </head> <body> <nav><a href="./index.html">home</a></nav> <h1>Our Feline Friends</h1> <p>Eventually we will put cat pictures here.</p> <footer><hr>Copyright (c) 2021 Contoso Cats</footer> </body> </html>
Al momento, il proprio repository e quello di Alice sono sincronizzati, ma quello di Bob non lo è. Per finire, aggiornare anche il repository di Bob:
cd ../Bob git pull
Tutti e tre i repository sono ora allineati. Il repository condiviso è l'unica origine di dati reali per tutti gli utenti e tutte le operazioni di push e pull avvengono nel repository condiviso.
Se si vuole sapere quale aspetto avrà il sito Web, ecco un'anteprima:
Se si vuole, è possibile scaricare i file per visualizzarne un'anteprima in locale:
Comprimere la cartella Cats:
cd .. zip -r Cats.zip Cats
Scaricare il file compresso:
download Cats.zip
Decomprimere ora il file nel computer locale e aprire index.html per verificare di persona.