Tutorial su Git: inizia con il controllo della versione di Git

Questo articolo ti introduce a Git, incluso come installare il software necessario per accedere ai server Git in cui verrà archiviato il tuo progetto software.

Concetti di controllo della versione

Per comprendere Git e il concetto di controllo della versione, è utile esaminare il controllo della versione da una prospettiva storica. Ci sono state tre generazioni di software di controllo della versione.

La prima generazione

La prima generazione era molto semplice. Gli sviluppatori hanno lavorato sullo stesso sistema fisico e hanno "estratto" un file alla volta.

Questa generazione di software di controllo della versione utilizzava una tecnica chiamata blocco dei file . Quando uno sviluppatore ha estratto un file, questo è stato bloccato in modo che nessun altro sviluppatore potesse modificare il file. 

Esempi di software di controllo della versione di prima generazione includono Revision Control System (RCS) e Source Code Control System (SCCS).

La seconda generazione

I problemi con la prima generazione includevano quanto segue:

  • Solo uno sviluppatore alla volta può lavorare su un file. Ciò ha provocato un collo di bottiglia nel processo di sviluppo.

  • Gli sviluppatori dovevano accedere direttamente al sistema che conteneva il software di controllo della versione.

Questi problemi sono stati risolti nella seconda generazione del software di controllo della versione. Nella seconda generazione, i file vengono archiviati su un server centralizzato in un repository. Gli sviluppatori possono estrarre copie separate di un file. Quando lo sviluppatore completa il lavoro su un file, il file viene archiviato nel repository. 

Se due sviluppatori controllano la stessa versione di un file, esiste il rischio di problemi. Questo è gestito da un processo chiamato unione .

Cos'è un'unione? Supponiamo che due sviluppatori, Bob e Sue, controllino la versione 5 di un file denominato abc.txt. Dopo che Bob ha completato il suo lavoro, controlla di nuovo il file. In genere, questo si traduce in una nuova versione del file, la versione 6.

Qualche tempo dopo, Sue controlla nel suo fascicolo. Questo nuovo file deve incorporare le sue modifiche e quelle di Bob. Ciò si ottiene tramite il processo di unione.

A seconda del software di controllo della versione utilizzato, potrebbero esserci diversi modi per gestire questa unione. In alcuni casi, come quando Bob e Sue hanno lavorato su parti completamente diverse del file, il processo di unione è molto semplice. Tuttavia, nei casi in cui Sue e Bob hanno lavorato sulle stesse righe di codice nel file, il processo di unione può essere più complesso. In questi casi, Sue dovrà prendere decisioni, ad esempio se il codice di Bob o il suo codice sarà nella nuova versione del file.

Al termine del processo di unione, viene eseguito il processo di commit del file nel repository. Eseguire il commit di un file significa essenzialmente creare una nuova versione nel repository; in questo caso, la versione 7 del file.

Esempi di software di controllo della versione di seconda generazione includono Concurrent Versions System (CVS) e Subversion.

La terza generazione

La terza generazione è indicata come sistemi di controllo della versione distribuiti (DVCS). Come con la seconda generazione, un server di repository centrale contiene tutti i file per il progetto. Tuttavia, gli sviluppatori non estraggono singoli file dal repository. Invece, l'intero progetto viene estratto, consentendo allo sviluppatore di lavorare sul set completo di file anziché solo sui singoli file. 

Un'altra (molto grande) differenza tra la seconda e la terza generazione di software di controllo della versione ha a che fare con il funzionamento del processo di unione e commit. Come accennato in precedenza, i passaggi nella seconda generazione consistono nell'eseguire un'unione e quindi eseguire il commit della nuova versione nel repository.

Con il software di controllo della versione di terza generazione, i file vengono archiviati e quindi uniti. 

Ad esempio, supponiamo che due sviluppatori controllino un file basato sulla terza versione. Se uno sviluppatore esegue il check-in di quel file, ottenendo una versione 4 del file, il secondo sviluppatore deve prima unire le modifiche dalla sua copia ritirata con le modifiche della versione 4 (e, potenzialmente, altre versioni). Al termine dell'unione, la nuova versione può essere salvata nel repository come versione 5.

Se ti concentri su ciò che è nel repository (la parte centrale di ogni fase), vedi che c'è una linea di sviluppo molto retta (ver1, ver2, ver3, ver4, ver5 e così via). Questo semplice approccio allo sviluppo del software pone alcuni potenziali problemi:

  • Richiedere a uno sviluppatore di unirsi prima di impegnarsi spesso fa sì che gli sviluppatori non vogliano eseguire il commit delle modifiche su base regolare. Il processo di unione può essere un problema e gli sviluppatori potrebbero decidere di aspettare solo più tardi e fare una fusione piuttosto che un mucchio di unioni regolari. Ciò ha un impatto negativo sullo sviluppo del software poiché all'improvviso vengono aggiunti enormi blocchi di codice a un file. Inoltre, si desidera incoraggiare gli sviluppatori a eseguire il commit delle modifiche al repository, proprio come si desidera incoraggiare qualcuno che scrive un documento a salvarlo regolarmente.
  • Molto importante: la versione 5 in questo esempio non è necessariamente il lavoro completato originariamente dallo sviluppatore. Durante il processo di unione, lo sviluppatore potrebbe scartare parte del suo lavoro per completare il processo di unione. Questo non è l'ideale perché provoca la perdita di codice potenzialmente buono.

Può essere utilizzata una tecnica migliore, anche se probabilmente più complessa. Si chiama grafo aciclico diretto (DAG) .

Immagina lo stesso scenario di cui sopra, in cui due sviluppatori controllano la versione 3 di un file. In questo caso, se uno sviluppatore archivia quel file, risulta comunque una versione 4 del file. Tuttavia, il secondo processo di archiviazione risulta in un file versione 5 che non è basato sulla versione 4, ma piuttosto indipendente dalla versione 4. Nella fase successiva del processo, le versioni 4 e 5 del file vengono unite per creare una versione 6.

Sebbene questo processo sia più complesso (e, potenzialmente, molto più complesso se si dispone di un gran numero di sviluppatori), fornisce alcuni vantaggi rispetto a una singola linea di sviluppo:

  • Gli sviluppatori possono eseguire il commit delle modifiche su base regolare e non devono preoccuparsi della fusione fino a un momento successivo.
  • Il processo di fusione potrebbe essere delegato a uno sviluppatore specifico che ha un'idea migliore dell'intero progetto o codice rispetto agli altri sviluppatori.
  • In qualsiasi momento, il project manager può tornare indietro e vedere esattamente quale lavoro ha creato ogni singolo sviluppatore.

Certamente esiste un argomento per entrambi i metodi. Tuttavia, tieni presente che questo articolo si concentra su Git, che utilizza il metodo del grafico aciclico diretto dei sistemi di controllo della versione di terza generazione.

Installazione di Git

Potresti già avere Git sul tuo sistema perché a volte è installato per impostazione predefinita (o un altro amministratore potrebbe averlo installato). Se hai accesso al sistema come utente normale, puoi eseguire il seguente comando per determinare se hai installato Git:

ocs @ ubuntu: ~ $ quale git / usr / bin / git

Se Git è installato, gitviene fornito il percorso del comando, come mostrato nel comando precedente. Se non è installato, non si ottiene alcun output o un errore come il seguente:

[ocs @ centos ~] # which git / usr / bin / which: no git in (/usr/lib64/qt-3.3/bin:/usr/local/bin:/usr/local/sbin:/usr/ bin: / usr / sbin: / bin: / sbin: / root / bin)

In qualità di amministratore su un sistema basato su Debian, puoi utilizzare il dpkgcomando per determinare se il pacchetto Git è stato installato:

root @ ubuntu: ~ # dpkg -l git Desired = Sconosciuto / Installa / Rimuovi / Elimina / Sospendi | Status = Not / Inst / Conf-files / Unpacked / halF-conf / Half-inst / trig-aWait / ➥Trig-pend | / Err? = (Nessuno) / Reinst-required (Status, Err: uppercase = bad) | | / Nome Versione Architettura Descrizione +++ - ======== - ============= - ============= - === ===================================== ii git 1: 1.9.1-1ubun amd64 veloce, scalabile , distribuito ➥revision con

In qualità di amministratore su un sistema basato su Red Hat, puoi utilizzare il rpmcomando per determinare se il pacchetto git è stato installato:

[root @ centos ~] # rpm -q git git-1.8.3.1-6.el7_2.1.x86_64

Se Git non è installato sul tuo sistema, devi accedere come utente root oppure utilizzare sudoo suinstallare il software. Se hai effettuato l'accesso come utente root su un sistema basato su Debian, puoi utilizzare il seguente comando per installare Git:

apt-get install git

Se hai effettuato l'accesso come utente root su un sistema basato su Red Hat, puoi utilizzare il seguente comando per installare Git:

yum installa git

Ottieni più di Git

Considera l'installazione del pacchetto software git-all. Questo pacchetto include alcuni pacchetti di dipendenze aggiuntivi che aggiungono più potenza a Git. Anche se all'inizio potresti non utilizzare queste funzionalità, averle a disposizione quando sei pronto per eseguire funzioni Git più avanzate sarà una buona cosa.

Concetti e funzionalità di Git

One of the challenges to using Git is just understanding the concepts behind it. If you don’t understand the concepts, then all the commands just seem like some sort of black magic. This section focuses on the critical Git concepts as well as introduces you to some of the basic commands.

Git stages

It is very important to remember that you check out an entire project and that most of the work you do will be local to the system that you are working on. The files that you check out will be placed in a directory under your home directory.

To get a copy of a project from a Git repository, you use a process called cloning. Cloning doesn’t just create a copy of all the files from the repository; it actually performs three primary functions:

  • Creates a local repository of the project under the project_name/.git directory in your home directory. The files of the project in this location are considered to be checked out from the central repository.
  • Creates a directory where you can directly see the files. This is called the working area. Changes made in the working area are not immediately version controlled.
  • Creates a staging area. The staging area is designed to store changes to files before you commit them to the local repository.

This means that if you were to clone a project called Jacumba, the entire project would be stored in the Jacumba/.git directory under your home directory. You should not try to modify these directly. Instead, look directly in the ~/Jacumba directory tol see the files from the project. These are the files that you should change.

Suppose you made a change to a file, but you have to work on some other files before you were ready to commit changes to the local repository. In that case, you would stage the file that you have finished working on. This would prepare it to be committed to the local repository.

After you make all changes and stage all files, then you commit them to the local repository. 

Realize that committing the staged files only sends them to the local repository. This means that only you have access to the changes that have been made. The process of checking in the new versions to the central repository is called a push.

Choosing your Git repository host

First, the good news: Many organizations provide Git hosting—at the time of this writing, there are more than two dozen choices. This means you have many options to choose from. That’s the good news … and the bad news.

It is only bad news because it means you really need to spend some time researching the pros and cons of the hosting organizations. For example, most don’t charge for basic hosting but do charge for large-scale projects. Some only provide public repositories (anyone can see your repository) whereas others let you create private repositories. There are many other features to consider.

One feature that might be high on your list is a web interface. Although you can do just about all repository operations locally on your system, being able to perform some operations via a web interface can be very useful. Explore the interface that is provided before making your choice.

At the very least, I recommend considering the following:

  • //bitbucket.org
  • //www.cloudforge.com
  • //www.codebasehq.com
  • //github.com
  • //gitlab.com

Note that I chose Gitlab.com for the examples below. Any of the hosts in the preceding list would have worked just as well; I chose Gitlab.com simply because it happened to be the one I used on my last Git project.

Configuring Git

Now that you have gotten through all the theory, it is time to actually do something with Git. This next section assumes the following:

  • You have installed the git or git-all software package on your system.
  • You have created an account on a Git hosting service.

The first thing you want to do is perform some basic setup. Whenever you perform a commit operation, your name and email address will be included in the metadata. To set this information, execute the following commands:

ocs @ ubuntu: ~ $ git config --global user.name "Bo Rothwell" ocs @ ubuntu: ~ $ git config --global user.email "[email protected]"

Ovviamente sostituirai "Bo Rothwell"con il tuo nome e "[email protected]"con il tuo indirizzo email. Il prossimo passo è clonare il tuo progetto dal servizio di hosting Git. Nota che prima della clonazione, solo un file è nella directory home dell'utente:

ocs @ ubuntu: ~ $ ls first.sh

Il seguente ha clonato un progetto chiamato ocs: