Usuário:Musa
Git
GIT è un sistema di controllo di versione distribuito il quale software viene rilasciato in maniera open source. Ma cosa significa? Significa che tramite git è possibile tenere traccia delle modifiche effettuate su un insieme di file. Modifiche ai singoli file, aggiunte e cancellazione di file vengono memorizzate in uno storico. E' possibile lavorare in più persone sugli stessi file, o su una loro copia (clonatura) e poi fondere le modifiche tramite un sistema che aiuta nella soluzione di eventuali conflitti. L’idea di fondo è avere macchine in comunicazione tra loro in maniera distribuita, non c’è un server che si interfaccia con un client. E’ possibile realizzare due tipi di repository: locale o remoto (GitHub o Bitbucket), entrambe le possibilità verranno delineate negli articoli successivi, oggi mi soffermo sulle basi per acquisire padronanza con questo meraviglioso sistema.
- Git
GIT è un sistema di controllo di versione distribuito il quale software viene rilasciato in maniera open source. Ma cosa significa? Significa che tramite git è possibile tenere traccia delle modifiche effettuate su un insieme di file. Modifiche ai singoli file, aggiunte e cancellazione di file vengono memorizzate in uno storico. E' possibile lavorare in più persone sugli stessi file, o su una loro copia (clonatura) e poi fondere le modifiche tramite un sistema che aiuta nella soluzione di eventuali conflitti. L’idea di fondo è avere macchine in comunicazione tra loro in maniera distribuita, non c’è un server che si interfaccia con un client. E’ possibile realizzare due tipi di repository: locale o remoto (GitHub o Bitbucket), entrambe le possibilità verranno delineate negli articoli successivi, oggi mi soffermo sulle basi per acquisire padronanza con questo meraviglioso sistema.
- storia
Git è stato creato nel 2005 da Linus Torvalds, l'inventore del sistema operativo Linux. Inizialmente è stato creato per la scarsa capacità di progetti datati come CVS e Subversion nel gestire grossi progetti come quello del Kernel di Linux e per problemi di diritti con il software proprietario utilizzato fino ad allora, chiamato BitKeeper.
- Prima Configurazione di git
Prima di utilizzare Git bisogna attuare alcune configurazioni basilari: Inserire l’utente è fondamentale per fare in modo che i commit non escano con nomi casuali e irriconoscibili.
- La Propria Identità
La prima cosa che occorrerebbe fare, quando si installa Git, è impostare il proprio nome utente e indirizzo e-mail. Ciò è importante, perché ogni commit di Git usa queste informazioni, che vengono incapsulate nei commit che si fanno:
$ git config --global user.name "musa jedo" $ git config --global user.email musajedo@example.com
- Il Proprio Editor
Ora che è configurata la propria identità, si può configurare l'editor di testo predefinito, da usare quando Git avrà bisogno di inserire un messaggio. Per impostazione predefinita, Git usa l'editor di testo predefinito del sistema, che generalmente è Vi o Vim. Se vuoi usare un editor di testo differente, come Emacs, puoi fare come segue:
$git config --global core.editor emacs
- Il Proprio Diff
Un'altra utile opzione, che si potrebbe voler configurare, è lo strumento diff, predefinito, da usare per risolvere i conflitti di merge (fusione, ndt). Per usare vimdiff:
$git config --global merge.tool vimdiff
- Controllare le Impostazioni
Per controllare le proprie impostazioni, si può usare il comando git config --list, che elenca tutte le impostazioni di Git, fatte fino a questo punto:
musa@amilo:~/mocambos$ git config --list user.email=musajedo@example.com user.name=Musa core.editor=emancs core.repositoryformatversion=0 core.filemode=true core.bare=false core.logallrefupdates=true
La stessa chiave può comparire più volte, perché Git legge la stessa chiave da file differenti (/etc/gitconfig e ~/.gitconfig, per esempio). In questo caso, Git usa l'ultimo valore per ogni chiave unica che vede. Per controllare quale sia il valore di una chiave, ritenuto da Git usare, git config {key}:
$ git config user.name musa jedo
- Ottenere Aiuto
Questi comandi sono utili, perché puoi accedere ad essi da ogni dove, anche se sei offline. Se il manuale e questo libro non sono sufficienti e hai bisogno di un aiuto più diretto da una persona, puoi provare i canali #git o #github, sul server IRC di Freenode (irc.freenode.com). Questi canali sono regolarmente frequentati da centinaia di persone che conoscono molto bene Git e saranno davvero felici di aiutarti. Se dovessi avere bisogno di aiuto durante l'uso di Git, ci sono tre modi per vedere le pagine del manuale di aiuto per ogni comando di Git:
$ git help $ git --help $ man git
Per esempio, puoi avere la pagina del manuale di aiuto, per il comando config, lanciando
$ git help config
Per controllare la versione di git
$git --version $echo "$(git –version)"
- Creare un Repository Vuoto
Per comprendere git non ci servirà né Xcode né altri programmi. Ci baseremo infatti esclusivamente sul terminale. Avviamo quindi il terminale e creiamo la cartella “mocambos git” dove meglio ci piace. (ricordo che nel terminale cd è il comando per cambiare directory e mkdir quello per crearne una nuova).
musa@amilo:~$ mkdir mocambos musa@amilo:~$ cd mocambos/
Dall’interno della cartella “mocambos” appena creata digitiamo il comando
musa@amilo:~/mocambos$ git init
Questo inizializza un repository vuoto nella cartella in cui viene dato il comando. Vedremo quindi un messaggio simile a questo:
Initialized empty Git repository in /home/fasher/mocambos/.git/
Abbiamo appena creato il nostro primo repository. Possiamo infatti vedere che all’interno della cartella “mocambos ” è stata creata una cartella nascosta “.git”
musa@amilo:~/mocambos$ ls -laF totale 12 drwxr-xr-x 3 musa musa 4096 2013-08-02 14:57 ./ drwxr-xr-x 43 musa musa 4096 2013-08-02 14:56 ../ drwxr-xr-x 7 musa musa 4096 2013-08-02 14:57 .git/
Una volta che il repository è stato creato iniziamo ad aggiungere files al nostro progetto, aggiungiamo ad esempio un file di testo “file1.txt” che al suo interno abbia questo testo:
musa@amilo:~/mocambos$ echo 'hello world' > file.txt
git add . Aggiungerà ogni cosa cambiata.
musa@amilo:~/mocambos$ git add .
Facciamo il commit del nostro primo progetto Supponiamo che il nostro lavoro sia finito qui, siamo soddisfatti della frase scritta e vogliamo che diventi un punto fermo nella storia del nostro progetto: quello che vogliamo è creare un oggetto commit o come si dice in gergo “fare il commit del progetto”. Un commit è composto dai file che sono stati modificati dal precedente commit, un riferimento a tale commit e da un nome univoco. Se avete studiato un pò di teoria dei grafi potete immaginare i vari commit come un grafo aciclico e diretto:
- ciascun commit, escluso il primo, ha un riferimento ai precedenti commit (può essere figlio di due o più commit)
- ciascun commit, escluse le foglie, hanno un riferimento ai commit successivi.
Per creare il nostro primo commit digitiamo:
musa@amilo:~/mocambos$ git commit -a -m "initial commit"
Dovreste ottenere questo output:
musa@amilo:~/mocambos$ git commit -a -m "initial commit" [master (root-commit) 81a937a] initial commit 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 file.txt musa@amilo:~/mocambos$
Questa è la prima versione del progetto. in cui si vede chiaramente che abbiamo aggiunto un file. Creiamo altri due file sulla falsa riga del primo e creiamo un nuovo commit dopo aver creato ciascun file.
musa@amilo:~/mocambos$ echo 'hello world!' >file.txt musa@amilo:~/mocambos$ git commit -a -m "add emphasis" [master c03619d] add emphasis 1 files changed, 1 insertions(+), 1 deletions(-) musa@amilo:~/mocambos$
Dopo aver creato due commit digitiamo $git log vedremo un risultato simile al seguente:
musa@amilo:~/mocambos$ git log commit c03619ddb1c07958f6052ef96110dba6b27bb8b8 Author: Musa <hamato_jedo@hotmail.com> Date: Fri Aug 2 15:24:18 2013 +0200 add emphasis commit 81a937a86dc0215999bb76f581e6e3a6d00d1aa9 Author: Musa <hamato_jedo@hotmail.com> Date: Fri Aug 2 15:18:02 2013 +0200 initial commit
Vediamo in ordine inverso i due oggetti commit che abbiamo creato, con tanto di nome univoco SHA1, l’autore la data ed il commento.
$git cat-file -t 64b2c91d $git ls-tree 64b2c91d $ git cat-file blob 64b2c91d $ find .git/objects/ $ find .git/objects/ $cat .git/refs/heads/master
Altri comandi molto utili sono:
* git status: mostra quali file sono cambiati tra lo stato attuale del progetto e lo stato corrente del repository (*) * git diff: mostra le differenze sui singoli files * git mv: marca un file come da spostare sul repository * git rm: marca un file come da rimuovere sul repository
(*) l’indicazione dello stato corrente necessita una spiegazione: all’interno del repository vengono mantenuti dei riferimenti ai diversi oggetti commit, il riferimento HEAD punta al commit corrente e viene portato avanti automaticamente quando si effettua un nuovo commit.
- Git Branches
I progetti non hanno mai una vita lineare, neanche nel mondo ideale. Ci sono sempre almeno un paio di versioni “funzionanti” nelle quali si prova ad aggiungere nuove funzionalità o rimuovere vecchi problemi. git tiene conto di queste esigenze e risponde con la funzionalità chiamata branch. In un repository possono coesistere più branch contemporaneamente, il primo viene creato di default e si chiama master tutti gli altri possono essere creati successivamente dall’utente. Per creare il nuovo branch 'develop' occorre digitare:
musa@amilo:~/mocambos$ git branch develop
in questo modo abbiamo creato un nuovo ramo. Possiamo vedere il risultato di questo comando digitando
musa@amilo:~/mocambos$ git branch
vedremo un risultato simile al seguente:
musa@amilo:~/mocambos$ git branch develop * master
l'asterisco indica il branch attualmente selezionato per passare da un branch all'altro
musa@amilo:~/mocambos$ git checkout master Already on 'master'
Per portare avanti il codice su develop, selezioniamo il branch develop
musa@amilo:~/mocambos$ git checkout develop Switched to branch 'develop'
Per iniziare a sviluppare sul nuovo branch dobbiamo digitare il comando:
musa@amilo:~/mocambos$ echo 'hello world again' >file.txt musa@amilo:~/mocambos$ git add . musa@amilo:~/mocambos$ git commit -a -m "add emphasis2" [develop 41afd11] add emphasis2 1 files changed, 1 insertions(+), 1 deletions(-)
Se guardiamo il log vediamo che non appare il tre commit, perché è stato effettuato sul branch master, mentre stiamo lavorando sul branch develop.
musa@amilo:~/mocambos$ git log commit 41afd11c0d0c0ae3008ad23b2565bc038a6c58ad Author: Musa <hamato_jedo@hotmail.com> Date: Fri Aug 2 15:45:13 2013 +0200 add emphasis2 commit c03619ddb1c07958f6052ef96110dba6b27bb8b8 Author: Musa <hamato_jedo@hotmail.com> Date: Fri Aug 2 15:24:18 2013 +0200 add emphasis commit 81a937a86dc0215999bb76f581e6e3a6d00d1aa9 Author: Musa <hamato_jedo@hotmail.com> Date: Fri Aug 2 15:18:02 2013 +0200 initial commit
Per avere una idea grafica di quello che sta succedendo possiamo usare questo comando (trovato su stackoverflow):
musa@amilo:~/mocambos$ git log --graph --date-order -C -M --pretty=format:" %ad [%an] %Cgreen%d%Creset %s" --all --date=short * 2013-08-02 [Musa] (HEAD, develop) add emphasis2 * 2013-08-02 [Musa] (master) add emphasis * 2013-08-02 [Musa] initial commit
Da notare che il nuovo oggetto commit ottenuto con il merge ha due genitori, il quarto commit del brach master ed il quinto commit del branch nuovo_ramo. Per saltare da un ramo ad un altro si usa il comando:
$ git checkout master
- Merge
Terminate le modifiche effettuate sul branch nuovo_ramo è adesso il momento riportarle sul branch master. Purtroppo non abbiamo garanzia che nessuno abbia intanto modificato i file del branch master, anzi, in uno sviluppo condiviso, questa è la norma, quindi incrociamo le dita e speriamo che non ci siano conflitti di sorta. Switchiamo sul branch master e digitiamo:
musa@amilo:~/mocambos$ git checkout master Switched to branch 'master' musa@amilo:~/mocambos$ git merge develop Updating c03619d..41afd11 Fast-forward file.txt | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
will commit the result of the merge. Finally,
musa@amilo:~/mocambos$ gitk
se un giorno decidessimo che il branch develop non ci serve più, cancelliamolo
$git branch -d develop
- Eliminare un ramo
Dopo aver usato un ramo e dopo aver fatto il merge nel ramo principale possiamo decidere di eliminarlo dal nostro repository.
$ git branch -d <nome_ramo_locale> $ git branch -d -r <nome_ramo_remoto>
Questa prima parte della guida all’uso di git termina qui, nella prossima puntata affronteremo la condivisione dello stesso progetto su più utenti, anche attraverso internet.
- Prossimo Utilizzando git per la collaborazione
Git-annex
git-annex/ git-annex è grande. Si tratta di una estensione a git che permette di gestire i file con git senza peraltro riuscire a check-in git-annex fa sostituendo ogni file con un link simbolico che punta al reale contenuto nella directory git / annex (dal nome di un checksum del file di contenuti). Solo il collegamento simbolico viene controllato in git. ecco come fare per arrivare dal nulla per il monitoraggio di un file con git-annex:
- Creazione di un repository
Basta dire che una descrizione del repository.
musa@amilo:~$ mkdir Bocs musa@amilo:~$ cd Bocs/ musa@amilo:~/Bocs$ git init Initialized empty Git repository in /home/musa/Bocs/.git/ musa@amilo:~/Bocs$ git annex init "amilo" init amilo ok (Recording state in git...)
- aggiungere un remoto:
Come qualsiasi altro repository git, git-annex repository hanno remoto. Cominciamo con l'aggiunta di un drive USB come un remoto. se il tuo drive usb non installato, può installarlo con il commando sudo/mount/media/nome usb drive.
musa@amilo:/$sudo mount /media/6FFE-842D
per spostarlo nel usb drive con il commando cd /media/nome usb drive
musa@amilo:/$cd /media/6FFE-842D
clonare nostro directory con comando git clone ~/Bocs
musa@amilo:/media/6FFE-842D$ git clone ~/Bocs Initialized empty Git repository in /media/6FFE-842D/Bocs/.git/ warning: remote HEAD refers to nonexistent ref, unable to checkout.
spostare nel directory Bocs
musa@amilo:/media/6FFE-842D$cd Bocs musa@amilo:/media/6FFE-842D/Bocs$ git annex init "portable USB drive" init portable USB drive Detected a crippled filesystem. Enabling direct mode. Detected a filesystem without fifo support. Disabling ssh connection caching. ok (Recording state in git...)
per aggiunger usb drive remoto con computer portatile amilo
musa@amilo:/media/6FFE-842D/Bocs$ git remote add amilo ~/Bocs
aggiungere computer portatile amilo remoto con il drive USB
musa@amilo:/media/6FFE-842D/Bocs$ cd ~/Bocs musa@amilo:~/Bocs$ git remote add usbdrive /media/6FFE-842D/Bocs
Tutto questo è la configurazione standard di repository ad hoc distribuito git. L'unica git-annex specifica parte sta dicendo che il nome del nuovo repository creato sul drive USB. Si noti che entrambi i pronti contro termine sono impostati come remoto l'uno dell'altro. Ciò consente di ottenere sia annex file dall'altro. Avrai voglia di farlo, anche se si sta usando git in modo più centralizzato.
- aggiuntiamo un file nel directory Bocs al computer portatile amilo:
musa@amilo:~/Bocs$ cp /home/musa/zaghawa.jpg zaghawa.jpg musa@amilo:~/Bocs$ git annex add . add zaghawa.jpg (checksum...) ok (Recording state in git...) musa@amilo:~/Bocs$ git commit -a -m added [master (root-commit) d94ecb8] added 1 files changed, 1 insertions(+), 0 deletions(-) create mode 120000 zaghawa.jpg
- ottenere il contenuto del file: