Translation(s): English - Italiano
Contents
Usare Git
Seminario online tenuto da David Paleino per Debian Women, 25-Nov-2010
Questa è una guida introduttiva all'uso di git. Verranno spiegate le basi per capire il suo funzionamento e il suo uso.
Requisiti
In questa guida si presume che:
si conosca l'uso di base della linea di comando e l'utilizzo di un editor di testo a scelta (emacs, vim, gedit, kate, etc.);
Requisiti tecnici:
Introduzione
Cos'è git? Git è un sistema di Controllo di versione distribuito. La parte importante è Controllo di versione -- significa che è un programma che permette di tenere traccia dei cambiamenti dei file e comparare le differenti "versioni", e fare anche un'altra cosa fantastica, come tornare indietro a precedenti versioni di un certo file.
Git viene usato da molti progetti software moderni, quindi è bene conoscere almeno un po' del suo funzionamento. Non c'è bisogno di andare molto nei dettagli, verrà spiegato solo il suo funzionamento di base e il suo uso generale.
Teoria
sistema di controllo di versione''Distribuito''
Noi abbiamo analizzato git come Sistema di Controllo di Versione, ma git è un VCS Distribuito. Distribuito è un dettaglio dell'architettura di git, che ha alcuni pro e alcuni contro. Ci sono altri "sistemi VCS famosi, come CVS e SVN, chiamati VCS Centralizzati; questi hanno bisogno di avere una connessione al server centrale, per conservare tutti i dati e per eseguire molte operazioni. Pensa al comando log: SVN ha bisogno di connettersi al server e scaricare i dati. Con i Ovviamente anche i VCS Distribuiti hanno i loro difetti, il problema più importante che ho riscontrato è il gran numero di
VCS Distribuiti (e git è uno di questi) ciò non avviene: ogni copia del repository è una copia completa. Questo significa che le operazione sono più veloci, e che soprattutto puoi usare git sul tuo computer locale, senza avere un server.
Il modello di immagazzinamento di git
Ogni oggetto all'interno di un repository git è identificato da una stringa univoca. Questa è chiamata hash. Normalmente è una somma SHA1 di alcune proprietà di cui parleremo più tardi.
Un oggetto git può essere un blob, un tree, commit o tag. Guardiamoli uno alla volta:
Un blob è un oggetto git su cui sono conservati i dati. Questo è generalmente un file su disco.
Un tree è come una cartella, fa referenza ad altri tree e/o blob. Immaginalo come una cartella con file e sottocartelle al suo interno.
Un commit è una referenza ad un singolo tree, e contiene anche altre meta-informazioni, come il timestamp, l'autore (nome ed email) che ha apportato le modifiche e un puntatore al commit precedente. Generalmente, quando si usa git, si fa riferimento solo ai commit.
Un tag è solo un modo per segnare un commit come se fosse in un certo modo speciale. Generalmente, i tag vengono usati per segnare commit con i numeri di versione, release e così via.
Se pensiamo al modello di immagazzinamento di git, distinguiamo una "area di lavoro", un "index" e un "repository":
L' area di lavoro è composta dai file presenti nella nostra cartella git
L' index e repository, invece, sono contenuti all'interno di ./.git/ -- qui è dove tutti i repository git risiedono, ed è sufficiente per ricreare il contenuto delle cartelle. Andando oltre, possiamo dire che l' index è come una temporanea area di sosta, dove tu puoi aggiungere i file prima di eseguire il commit. Una volta che il commit è stato eseguito, il contenuto andrà all'interno del repository, e l'azione compiuta verrà conservata nella sua cronologia, se tu non esegui il commit, puoi rimuovere i file dall'index senza lasciare traccia nella cronologia del repository.
Pratica
Creare un repository
Per la parte pratica, ho voluto usare un progetto reale, anzichè creare qualche repository. Ho scelto di usare "GNU Hello", scaricalo da http://ftp.gnu.org/gnu/hello/hello-2.6.tar.gz. Noi creeremo un repository da questo codice sorgente.
Scarichiamo il tarball:
$ wget http://ftp.gnu.org/gnu/hello/hello-2.6.tar.gz
Una volta fatto, spacchettiamolo:
$ tar zxvf hello-2.6.tar.gz
Questo comando creerà la cartella hello-2.6/. Adessim entriamo nella cartella ed iniziamo a giocare con git
Prima di tutto, abbiamo bisogno di configurare il nostro username e la nostra e-mail. Queste informazioni verranno usate nei nostri commit, e saranno visibili nella cronologia del repository. Per fare ciò, usiamo git config. In particolare, visto che siamo dei principianti, vogliamo settare username ed e-mail in modo globale. Quindi lanciamo i comandi:
$ git config --global user.name "Debian Woman Attendant" $ git config --global user.email "attendant@debian.org"
Naturalmente usa i tuoi dati
L'opzione --global fa in modo che il cambiamento sia globale, ad esempio per ogni repository git sul tuo computer lui scrivere le informazioni in ~/.gitconfig. Controlla questo file, dopo che avrai eseguito questi due comandi. Vedrai le informazioni che hai fornito.
L'username e l'e-mail possono anche essere cambiate in base al repository: in questo caso, puoi farlo dopo aver creato il repository, e senza l'opzione --global. Senza --global, lui inserirà le informazioni localmente in ./.git/config.
Abbiamo impostato l'username e l'e-mail. Ora, abbiamo bisogno di creare il repository git. Quindi abbiamo una cartella hello-2.6/: entriamoci ed lanciamo:
$ git init
Il risultato sarà qualcosa di simile:
Initialized empty Git repository in /tmp/dw/hello-2.6/.git/
git init semplicemente crea una cartella .git/, come alcuni valori di default. Per vedere lo stato di un repository, lancia:
$ git status
Ti mostrarà i file monitorati e non, e lo stato dell'index. In più, ti mostrerà in qualche branch sei (spiegerò i branch più tardi).
Indexing
Non abbiamo ancora nulla nel repository. Quindi aggiungiamo il codice sorgente:
$ git add .
Il "." è una sintassi dei sistemi Unix-like -- significa "cartella corrente". Quindi in questo modo aggiungiamo tutto il contenuto. Ora, controlla git status di nuovo. Vedrai che qualcosa è cambiato. Quello che vedi ora è lo stato di index.
Noi possiamo ancora rimuovere file o cartelle dall'index, senza lasciare tracce nella cronologia. Facciamolo! rimuoviamo il file We could still remove things from the index, without leaving traces in the repository history. Let's do it! Let's remove AUTHORS dall'index e rimettiamo nello stato di "non tracciato"
$ git rm --cached AUTHORS
Ora dai di nuovo uno sguardo a git status. Vedrai Changes to be committed(cambiamenti che devono essere committati) (l'index) e Untracked files (file non tracciati).
Committing
Ora vogliamo committarei file nell'index: questo creerà un commit, con un hash, e verrà conservato nella cronologia del repository. Lanciamo:
$ git commit
Questo comando aprirà il tuo $EDITOR (il mio è nano, controlla il tuo), dove tu dovrai scrivere un messaggio di commit. Se tu non ne scrivi uno, il commit verrà annullato (si, tu devi inserire un messaggio di commit)
Chiamiamolo "Commit iniziale". Ora, lancia di nuovo git status . I file dall'index sono spariti! Sono stati committati all'interno del repository, e il log è stato conservato.
Puoi vedere i log con:
$ git log
Ti verrà mostrato il committer(l'autore del commit, con le informazioni inserite prima), il timestamp, e l'hash del commit.
Puoi anche vedere l'ultimo commit con:
$ git show
Aprirà automaticamente $PAGER e mostrerà il contenuto del tuo ultimo commit. git show accetta anche un hash come argomento. Il mio commit ha hash: 11aab8486d20490b16b1b7d847e1cb1e4f7aa2fe . Che è differente dal uno dei tuoi. Non è necessario scrivere l'hash completo --normalmente bastano i primi 7,8 caratteri. Quindi possiamo lanciare:
$ git show 11aab848
git supporta anche un numero di nomi simbolici, ma non verranno spiegati ora in quanto credo non siano argomenti "di base" da poter essere spiegati in questa sessione (Sto parlando di HEAD, HEAD^, HEAD~2 e così via)
Quindi, abbiamo rimosso AUTHORS dal nostro repository... poveracci! nessun merito al loro lavoro! Correggiamo No credit for their work! possiamo correggere questo problema:
$ git add AUTHORS $ git commit -m 'Also add AUTHORS'
-m è una scorciatoia per il messagio -- evita così di aprire $EDITOR
Ora, abbiamo bisogno di moficare alcuni file, guarda le differenze, e commitale. Prima pretendiamo che abbiamo scritto un pezzo di codice.
Aggiungiamo il nostro nome al file AUTHORS
E aggiungiamo anche qualcosa a "?ChangeLog". Quello che vuoi, è solo un esempio.
Ora, git status. Vedrai le prime due linee indicate con modified(modificato). Puoi vedere le differenze che hai introdotto:
$ git diff
(Opzionalmente, git diff filename mostrerà solo le differenze in quel file.)
Se sei felice con quste modifiche, committiamo!. If you're happy with the diff, let's commit it. È possibile lanciare git add uno per uno e committare git commit oppure usare soltanto:
$ git commit -a -m "Messaggio a piacere"
L'argomento -a aggiungerà tutto all'index ( ma solo i file tracciati, quelli non tracciati non saranno toccati. Vedrai:
[master 3295347] Messaggio a piacere 2 files changed, 5 insertions(+), 0 deletions(-)
master è il branch in cui siamo ora. La stringa dopo di quello è l'hash del commit --puoi usarla in molti comandi (git show <commit>, git log <commit>, etc). E dopo, vi è il messaggio di commit e le statistiche dei cambiamenti apportati (diffstats).
Branching
Cos'è un branch?
Pensa al repository git come ad un fiume. Ad un certo punto, lo sviluppo può divergere dal "flusso principale" e rimanere solo lì, oppure Think of your git repository as a river. At a certain point, development can diverge from the main flow and it can stay on its own, oppure unirsi di nuovo al fiume originale. Ora il nostro master è il fiume principale". Creiamo un branch, chiamiamolo Per cambiare a questo nuovo branch lancia: Una scorciatoia per entrambi i comandi è: Ok, ora siamo nel branch Per tornare indietro al branch principale, esegui: git checkout master. Ma per il momento rimarremo sul branch Quindi, creiamo una cartella debian/. Se la cartella è vuota, git status non la mostrerà, è il comportamento previsto: Ora git status mostrerà la non-tracciata debian/. Aggiungila e committala. Ora torniamo al branch Ora vogliamo far divergere questi due branch, per simulare un branch reale: cambia tutti i file che vuoi, e committa i cambiamenti. Puoi usare un'interfaccia grafica ( come ad esempio Vedrai che i due branch hanno un commit inziale in comune, ma apparte questo hanno commit differenti. Quindi uniamo i cambiamenti di "debian" in "master" Vedrai qualcosa come: E ora ci saranno dei "conflitti". Se in Abbiamo unito
L'ultima cosa che voglio spiegare per quanto riguarda la parte della guida Suppomiamo che io trovi qualcosa che non mi piace nel mio git log. Per esempio diciamo che è il (mio) commit 2ba81dfaeb919e6a0c634be54fe363b11487d65a , quello con cui ho aggiunto la cartella debian/ directory. Ricordati che gli hash sono diffenti per ciascuna persona, quindi guarda i log per vedere il tuo. Dunque, non mi piace. Cosa dovrei fare ora? Posso usare il comando git revert. Questo comando prende semplicemente il cambiamento (diff) da un commit, e lo applica al contrario, e lascia i conflitti, se ce ne sono, proviamolo: $EDITOR ( You'll see: This means: a revert is a commit too. With a Committer, an Author, a Timestamp, and a Hash. Ideally, you can revert a revert. (you shouldn't do it NOTE: Reverting a merge is not that easy. You should also specify the mainline parent. Read about the -m switch of git revert. It also has some nasty (IMHO) side-effects, so don't merge if you're not absolutely sure. $ git branch debian
$ git checkout debian
$ git checkout -b debian
$ mkdir debian
$ touch debian/.gitignore
$ git checkout master
$ git show-branch
$ git merge debian
Merge made by recursive.
0 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 debian/.gitignore
commit cdfd20167aa05f74f4785ef7aa03355d51add5b3
Merge: 7e9ff3a 2ba81df
Author: David Paleino <dapal@debian.org>
Date: Thu Nov 25 23:45:28 2010 +0100
Merge branch 'debian'
commit 7e9ff3a18dc114b4ce1e1a96f1dd3ecd696f064d
Author: David Paleino <dapal@debian.org>
Date: Thu Nov 25 23:43:49 2010 +0100
New author
commit 2ba81dfaeb919e6a0c634be54fe363b11487d65a
Author: David Paleino <dapal@debian.org>
Date: Thu Nov 25 23:42:42 2010 +0100
add debian/
commit 3295347b1dbd7b5925dca7fcc6858af51a710ada
Author: David Paleino <dapal@debian.org>
Date: Thu Nov 25 23:32:55 2010 +0100
Some message
commit f6aa148a5ce1331de6d17e770a8efbb98ad32344
Author: David Paleino <dapal@debian.org>
Date: Thu Nov 25 23:11:57 2010 +0100
Also add AUTHORS
commit 11aab8486d20490b16b1b7d847e1cb1e4f7aa2fe
Author: David Paleino <dapal@debian.org>
Date: Thu Nov 25 23:03:42 2010 +0100
Initial commitRipristino
$ git revert 2ba81dfaeb919e6a0c634be54fe363b11487d65a
Finished one revert.
[master 37ce99f] Revert "add debian/"
0 files changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 debian/.gitignore
)
