Ricerca…
repo
Un git repository è una struttura dati su disco che memorizza i metadati per un insieme di file e directory.
Vive nel file .git/ cartella del tuo progetto. Ogni volta che si impegnano i dati per git, vengono memorizzati qui. Inversamente, .git/ contiene ogni singolo commit.
La sua struttura di base è così:
.git/
objects/
refs/
Oggetti
git è fondamentalmente un negozio di valore-chiave. Quando aggiungi dati a git , crea un object e usa l'hash SHA-1 del contenuto object come chiave.
Pertanto, qualsiasi contenuto in git può essere cercato dal suo hash:
git cat-file -p 4bb6f98
Esistono 4 tipi di Object :
-
blob -
tree -
commit -
tag
Testa rif
HEAD è una speciale ref . Punta sempre sull'oggetto corrente.
Puoi vedere dove punta attualmente controllando il file .git/HEAD .
Normalmente, HEAD punta a un'altra ref :
$cat .git/HEAD
ref: refs/heads/mainline
Ma può anche puntare direttamente a un object :
$ cat .git/HEAD
4bb6f98a223abc9345a0cef9200562333
Questo è ciò che è noto come un "head distaccato" - perché HEAD non è attaccato al (indicando) qualsiasi ref , ma piuttosto punta direttamente a un object .
refs
Un ref è essenzialmente un puntatore. È un nome che punta a un object . Per esempio,
"master" --> 1a410e...
Sono memorizzati in `.git / refs / heads / in file di testo semplice.
$ cat .git/refs/heads/mainline
4bb6f98a223abc9345a0cef9200562333
Questo è comunemente ciò che vengono chiamati branches . Tuttavia, noterai che in git non esiste una cosa come un branch : solo un ref .
Ora, è possibile navigare git puramente saltando intorno a objects diversi direttamente dai loro hash. Ma questo sarebbe terribilmente inopportuno. Un ref ti dà un nome conveniente per riferirsi agli objects di. È molto più facile chiedere a git di andare in un posto specifico per nome piuttosto che per hash.
Commit Object
Un commit è probabilmente il tipo di object più familiare per gli utenti git , poiché è ciò che sono abituati a creare con i comandi git commit .
Tuttavia, il commit non contiene direttamente alcun file o dato modificato. Piuttosto, contiene principalmente metadati e puntatori ad altri objects che contengono i contenuti effettivi del commit .
Un commit contiene alcune cose:
- hash di un
tree - hash di un genitore
commit - nome dell'autore / email, nome del committente / email
- messaggio di commit
Puoi vedere il contenuto di qualsiasi commit come questo:
$ git cat-file commit 5bac93
tree 04d1daef...
parent b7850ef5...
author Geddy Lee <[email protected]>
commiter Neil Peart <[email protected]>
First commit!
Albero
Una nota molto importante è che gli oggetti ad tree memorizzano OGNI file nel progetto e memorizza interi file non diff. Ciò significa che ogni commit contiene un'istantanea dell'intero progetto *.
* Tecnicamente, vengono memorizzati solo i file modificati. Ma questo è più un dettaglio di implementazione per l'efficienza. Dal punto di vista del design, un commit dovrebbe essere considerato come contenente una copia completa del progetto .
Genitore
La linea parent contiene un hash di un altro oggetto di commit e può essere pensata come un "indicatore padre" che punta al "commit precedente". Questo forma implicitamente un grafico di commit noto come grafico di commit . In particolare, è un grafico aciclico diretto (o DAG).
Oggetto dell'albero
Un tree rappresenta fondamentalmente una cartella in un filesystem tradizionale: contenitori nidificati per file o altre cartelle.
Un tree contiene:
- 0 o più oggetti
blob - 0 o più oggetti
tree
Proprio come è possibile utilizzare ls o dir per elencare il contenuto di una cartella, è possibile elencare il contenuto di un oggetto ad tree .
$ git cat-file -p 07b1a631
100644 blob b91bba1b .gitignore
100644 blob cc0956f1 Makefile
040000 tree 92e1ca7e src
...
Puoi cercare i file in un commit trovando prima l'hash tree nel commit e poi guardando tree :
$ git cat-file commit 4bb6f93a
tree 07b1a631
parent ...
author ...
commiter ...
$ git cat-file -p 07b1a631
100644 blob b91bba1b .gitignore
100644 blob cc0956f1 Makefile
040000 tree 92e1ca7e src
...
Oggetto Blob
Un blob contiene contenuti di file binari arbitrari. Comunemente, sarà un testo grezzo come il codice sorgente o un articolo del blog. Ma potrebbe essere altrettanto facilmente i byte di un file PNG o di qualsiasi altra cosa.
Se hai l'hash di un blob , puoi guardare i suoi contenuti.
$ git cat-file -p d429810
package com.example.project
class Foo {
...
}
...
Ad esempio, puoi sfogliare un tree come sopra, e poi guardare uno dei blobs in esso.
$ git cat-file -p 07b1a631
100644 blob b91bba1b .gitignore
100644 blob cc0956f1 Makefile
040000 tree 92e1ca7e src
100644 blob cae391ff Readme.txt
$ git cat-file -p cae391ff
Welcome to my project! This is the readmefile
...
Creare nuovi commit
Il comando git commit fa alcune cose:
- Crea
blobsetreesper rappresentare la directory del tuo progetto - archiviata in.git/objects - Crea un nuovo oggetto
commitcon le informazioni dell'autore, il messaggio di commit e l'treeradice del passaggio 1, anch'esso memorizzato in.git/objects - Aggiorna
HEADref in.git/HEADall'hash delcommitappena creato
Ciò si traduce in una nuova istantanea del tuo progetto che viene aggiunto a git che è connesso allo stato precedente.
Moving HEAD
Quando esegui il git checkout su un commit (specificato da hash o ref) stai dicendo a git di far apparire la tua directory di lavoro come quando è stata scattata l'istantanea.
- Aggiorna i file nella directory di lavoro in modo che corrispondano
treeall'interno delcommit - Aggiorna
HEADper puntare all'hash o al ref specificato
Spostando i ref in giro
Esecuzione di git reset --hard sposta i riferimenti all'hash specificato / rif.
Spostando MyBranch su b8dc53 :
$ git checkout MyBranch # moves HEAD to MyBranch
$ git reset --hard b8dc53 # makes MyBranch point to b8dc53
Creare nuovi Ref
Eseguire git checkout -b <refname> creerà un nuovo riferimento che punta al commit corrente.
$ cat .git/head
1f324a
$ git checkout -b TestBranch
$ cat .git/refs/heads/TestBranch
1f324a