Git è un'applicazione software per il controllo di versione distribuito utilizzabile da interfaccia a riga di comando, creato da Linus Torvalds nel 2005.
Git (che nello slang britannico significa idiota) nacque per essere un semplice strumento per facilitare lo sviluppo del kernel Linux ed è diventato uno degli strumenti di controllo versione più diffusi. La sua progettazione si ispirò ad analoghi strumenti, allora proprietari, come BitKeeper e Monotone.
Storia Lo sviluppo di Git è iniziato dopo che molti sviluppatori del kernel di Linux sono stati costretti ad abbandonare l'accesso al codice sorgente tramite il sistema proprietario BitKeeper. La possibilità di utilizzare BitKeeper gratuitamente era stata ritirata dal detentore dei diritti d'autore Larry McVoy dopo avere sostenuto che Andrew Tridgell aveva effettuato il reverse engineering dei protocolli.
Alla conferenza Linux.Conf.Au del 2005, Tridgell dimostrò nel suo intervento che il procedimento di reverse engineering che aveva usato era semplicemente collegarsi con telnet alla porta appropriata di un server Bitkeeper e digitare "help".
Torvalds voleva un sistema distribuito che potesse usare come BitKeeper, ma nessuno dei sistemi disponibili gratuitamente soddisfaceva i suoi bisogni, particolarmente il suo bisogno di velocità. mentre stava scrivendo il primo prototipo:
Linus aveva vari criteri di progettazione:
Prendi CVS come esempio di che cosa non fare; se hai un dubbio, fai l'esatto contrario. Per citare Linus, che parlava un po' ironicamente: “Per i primi 10 anni di manutenzione del kernel, usavamo letteralmente tarball (archivi compressi) e patch, che è un sistema di gestione del codice sorgente molto migliore di CVS. Poi ho finito per usare CVS per 7 anni in un'azienda [presumibilmente Transmeta] e lo odio appassionatamente. Quando dico che odio CVS appassionatamente, devo anche dire che se ci sono utenti SVN (Subversion) tra il pubblico, potreste volervene andare. Perché a causa del mio odio di CVS ritengo Subversion il progetto meno sensato che sia mai cominciato. Per un po' lo slogan di Subversion era ‘CVS fatto bene’, o qualcosa di simile, e se incominci con quel tipo di slogan, non puoi andare da nessuna parte. Non c'è modo di fare CVS bene.” Supporto di un flusso di lavoro distribuito, simile a BitKeeper. Come BitKeeper, Git non usa un server centralizzato. “BitKeeper non è solamente il primo sistema di controllo dei sorgenti che abbia mai pensato che valesse la pena usare; è stato anche il sistema che mi ha fatto capire perché ce ne sia effettivamente bisogno, e come si possa operare in modo efficace. Perciò, sebbene da un punto di vista tecnico Git sia molto diverso da BitKeeper (il che era un altro obiettivo di progettazione, perché volevo rendere chiaro che non era un clone di BitKeeper), molti dei procedimenti che usiamo con Git vengono direttamente dai procedimenti che abbiamo imparato da BitKeeper.” Salvaguardia dalla corruzione dei dati, sia accidentale che intenzionale Altissime prestazioni
I primi tre criteri non erano soddisfatti da alcun preesistente sistema di controllo versione eccetto Monotone, e il quarto ha escluso anche Monotone. Perciò, immediatamente dopo lo sviluppo della versione 2.6.12-rc2 del kernel di Linux, si è dedicato a scrivere il suo.
Lo sviluppo di Git è cominciato il 3 aprile 2005. Il progetto è stato annunciato il 6 aprile 2005, ed è stato usato per gestire il proprio sorgente a partire dal 7 aprile 2005. La prima fusione di più branch in uno è stata fatta il 18 aprile 2005. Torvalds ha raggiunto i suoi obiettivi in termini di prestazioni: il 29 aprile 2005, Git riusciva ad applicare 6 o 7 patch a Linux in un secondo. Il 16 giugno 2005 è stata pubblicata la versione 2.6.12 del kernel di Linux, la prima gestita con Git.
Sebbene fortemente influenzato da BitKeeper, Torvalds ha deliberatamente tentato di evitare approcci convenzionali, il che ha prodotto un sistema molto innovativo.
Torvalds ha sviluppato il sistema fino a quando è diventato usabile da utenti tecnici; poi, il 26 luglio 2005, ha ceduto la manutenzione a Junio Hamano, un importante contributore al progetto. Hamano è stato il responsabile della versione 1.0, pubblicata il 21 dicembre 2005, e rimane oggi il manutentore.
Descrizione Caratteristiche Il progetto di Git è la sintesi dell'esperienza di Torvalds nel mantenere un grande progetto di sviluppo distribuito, della sua intima conoscenza delle prestazioni del file system, e di un bisogno urgente di produrre un sistema soddisfacente in poco tempo. Queste influenze hanno condotto alle seguenti scelte implementative: Forte supporto allo sviluppo non lineare. Git supporta diramazione e fusione (branching and merging) rapide e comode, e comprende strumenti specifici per visualizzare e navigare una cronologia di sviluppo non lineare. Un'assunzione centrale in Git è che una modifica verrà fusa più spesso di quanto sia scritta, dato che viene passata per le mani di vari revisori. Torvalds stesso fa la maggior parte delle fusioni e una piccola parte delle correzioni dirette al codice, perciò egli stesso ha dimostrato che questo aspetto funziona bene. Sviluppo distribuito. Similmente a Bazaar, Darcs, BitKeeper, Mercurial, SVK, e Monotone, Git dà a ogni sviluppatore una copia locale dell'intera cronologia di sviluppo, e le modifiche vengono copiate da un tale repository a un altro. Queste modifiche vengono importate come diramazioni aggiuntive di sviluppo, e possono essere fuse allo stesso modo di una diramazione sviluppata localmente. I repository possono essere pubblicati facilmente tramite HTTP, FTP, ssh, rsync, o uno speciale protocollo git. Git ha anche un'emulazione del server CVS, che consente di usare gli esistenti client CVS e plugin per IDE per accedere ai repository Git. Gestione efficiente di grandi progetti. Git è molto veloce e scalabile. È tipicamente un ordine di grandezza più veloce degli altri sistemi di controllo versione, e due ordini di grandezza più veloce per alcune operazioni, observing that "git log" is 100x faster than "svn log" because the latter has to contact a remote server.. Autenticazione crittografica della cronologia. La cronologia di Git viene memorizzata in modo tale che il nome di una revisione particolare (secondo la terminologia Git, una "commit") dipende dalla completa cronologia di sviluppo che conduce a tale commit. Una volta che è stata pubblicata, non è più possibile cambiare le vecchie versioni senza che ciò venga notato. (Anche Monotone ha questa proprietà.) Progettazione del toolkit. Git è un insieme di programmi di base scritti in linguaggio C, e molti script di shell che forniscono comodi incapsulamenti. È facile concatenare i componenti per fare altre cose utili. Strategie di fusione intercambiabili. Come parte della progettazione del suo toolkit, Git ha un modello ben definito di una fusione incompleta, e ha più algoritmi per tentare di completarla. Se tutti gli algoritmi falliscono, tale fallimento viene comunicato all'utente e viene sollecitata una fusione manuale. Pertanto è facile sperimentare con nuovi algoritmi di fusione. La spazzatura si accumula fino a quando viene raccolta. Quando si abortisce un comando o si scartano delle modifiche si lasciano degli oggetti inutilizzabili nel database. Tipicamente, questi sono solo una piccola parte della cronologia continuamente crescente degli oggetti utili, ma il comando di recupero dello spazio, git gc --prune, può richiedere parecchio tempo.
Una proprietà di Git che ha prodotto considerevoli controversie è il fatto che prende istantanee di interi alberi di directory di file invece che di singoli file. I primi sistemi di controllo versione del codice sorgente, SCCS and RCS, lavoravano su singoli file, e vantavano il risparmio di spazio ottenibile dalla codifica delta delle versioni simili. I successivi sistemi di controllo versione mantennero questo concetto di identità dei file al variare delle revisioni di un progetto.
Git rifiuta questo concetto e non registra esplicitamente le relazioni di revisione di file a nessun livello all'interno dell'albero del codice sorgente. Ciò comporta conseguenze rilevanti: È effettivamente leggermente più costoso esaminare la cronologia di modifiche di un singolo file rispetto a quella dell'intero progetto. Per ottenere la cronologia delle modifiche che riguardano un dato file, Git deve ripercorrere la cronologia complessiva e poi determinare quali modifiche hanno riguardato quel file. Questo metodo di esaminare la cronologia, comunque, permette a Git di produrre con altrettanta efficienza una singola cronologia che mostra le modifiche a un arbitrario insieme di file. Per esempio, una sottodirectory dell'albero dei sorgenti più un file di intestazione (header) globale a loro associato. I cambiamenti di nome di file e directory vengono gestiti in modo implicito invece che esplicito. Una grossa lamentela degli utenti di CVS è che usa il nome di un file per identificare la sua cronologia di revisioni, perciò non è possibile spostare un file o cambiargli nome senza interrompere la sua cronologia, così come cambiare nome alla cronologia rendendola inaccurata. La maggior parte dei sistemi di controllo versioni successivi a CVS risolvono questo problema dando a ogni file un nome interno univoco di lunga vita che sopravvive al cambiamento di nome. Git non memorizza un identificatore di questo genere, e questo viene descritto come un vantaggio. I file di codice sorgente vengono talvolta spezzati o fusi oltre che semplicemente cambiati di nome, e memorizzare tali modifiche come un semplice cambiamento di nome congelerebbe per sempre nella cronologia una descrizione inaccurata di quello che è successo. Git affronta la questione rilevando i cambiamenti di nome mentre sfoglia la cronologia delle istantanee invece di memorizzarli quando si prende un'istantanea. (In breve, dato un file alla revisione N, un file con lo stesso nome alla revisione N-1 è il suo antenato di default. Tuttavia, quando non ci sono file dal nome simile alla versione N-1, Git cerca un file che esisteva solamente alla versione N-1 e che abbia un contenuto molto simile a quello del nuovo file.) Questo richiede più lavoro di CPU ogni volta che si esamina la cronologia, e alcune opzioni per calibrare l'euristica.
Inoltre, gli utenti talvolta sono turbati dal modello di immagazzinamento: Impacchettamento esplicito periodico degli oggetti. Git immagazzina ogni nuovo oggetto in un file distinto. Sebbene tale file sia in un formato compresso, può occupare parecchio spazio ed essere inefficiente. Questo problema è risolto dall'uso di "impacchettamenti" ("packs") che immagazzinano molti oggetti in un solo file (o in un flusso di dati via rete), che hanno essi stessi una compressione delta. Gli impacchettamenti vengono compressi con l'euristica che i file con lo stesso nome sono probabilmente simili, funzionano correttamente anche se questa supposizione non è valida. Gli oggetti appena creati (cioè appena aggiunti alla cronologia) sono ancora immagazzinati singolarmente, e per mantenere l'efficienza si dovrebbe effettuare periodicamente un impacchettamento.
Git implementa varie strategie di fusione; in fase di fusione si può scegliere un comportamento diverso da quello di default: risolvi (resolve): Questo è l'algoritmo tradizionale di fusione a 3 vie. ricorsivo (recursive): Questo è l'algoritmo di default quando si estrae o si fonde un ramo, ed è una variante dell'algoritmo di fusione a 3 vie. "Quando ci sono più antenati comuni che possono esser usati per una fusione a 3 vie, crea un albero di fusione degli antenati comuni e lo utilizza come albero di riferimento per la fusione a 3 vie. Questo risulta produrre meno conflitti di fusione senza provocare mal-fusioni dalle prove effettuate su effettive fusioni di rilascio prese dalla cronologia di sviluppo del kernel Linux 2.6. Inoltre, questo può rivelare e gestire i cambiamenti di nome."