>
<>
<>
= Introduzione =
Il comando '''commit''' è l'azione che nel software [[Programmazione/Git|Git]] permette di aggiungere, rimuovere e modificare i file del repository. Nella seguente pagina viene mostrato come utilizzarlo e come monitorare lo stato del repository attraverso un esempio pratico.
= Stato iniziale =
Lo stato del repository e ulteriori informazioni sono consultabili tramite i comandi:
* '''git status'''
* '''git log'''
* '''git lg''' (alias del comando '''log''' [[Programmazione/Git#alias|precedentemente]] creato)
Supponendo di aver creato il progetto '''gitproject''' come [[Programmazione/Git#creare|mostrato]] in precedenza e di essersi spostati al suo interno:{{{
cd gitproject
}}}
* Il comando:{{{
git status
}}}restituirà inizialmente le seguenti stringhe:{{{
Sul branch master
Non ci sono ancora commit
non c'è nulla di cui eseguire il commit (crea/copia dei file e usa "git add" per tracciarli)
}}}Il comando dice che non c'è niente da ''committare'' perché non è stata eseguita nessuna modifica.
* Il comando:{{{
git log
}}}restituirà:{{{
fatal: il tuo branch corrente 'master' non ha ancora commit
}}}Il comando da errore perché essendo il repository appena creato non esiste ancora un log.
= Creazione primo file =
0. Creare il primo file del progetto digitando:{{{
echo Inizio progetto > README
}}}
0. Eseguire il comando:{{{
git status
}}}verrà restituito il messaggio:{{{
Sul branch master
Non ci sono ancora commit
File non tracciati:
(usa "git add ..." per includere l'elemento fra quelli di cui verrà eseguito il commit)
README
non è stato aggiunto nulla al commit ma sono presenti file non tracciati (usa "git add" per tracciarli)
}}}'''Git''' avvisa che è presente un nuovo file nella cartella, ma che è nello stato '''untracked''', ovvero che non viene tenuto in conto dal repository.
= Aggiungere il file al repository =
0. Il nuovo file deve essere aggiunto manualmente al repository attraverso il comando:{{{
git add README
}}}
0. Eseguire quindi lo status:{{{
git status
}}}ottenendo:{{{
Sul branch master
Non ci sono ancora commit
Modifiche di cui verrà eseguito il commit:
(usa "git rm --cached ..." per rimuovere gli elementi dall'area di staging)
nuovo file: README
}}}Adesso il file si trova nello stato di '''stage''', ovvero è pronto per essere committato all'interno del repository. In breve i file in stato '''stage''' sono quelli pronti per essere committati, le cui modifiche verranno salvate nel repository.
= Effettuare il commit =
Per applicare le modifiche fatte si utilizza il comando '''commit''' con i seguenti falg:
* '''-a''' per committare tutti i files in stato stage;
* '''-m''' per inserire il messaggio associato al commit che altrimenti verrebbe richiesto in una finestra interattiva.
Procedere quindi con il commit.
0. Digitare:{{{
git commit -a -m "README aggiunto"
}}}Si visualizzerà il messaggio:{{{
[master (commit radice) ba12845] README aggiunto
1 file changed, 1 insertion(+)
create mode 100644 README
}}}
0. Controllare lo '''status''':{{{
git status
}}}che restituirà:{{{
Sul branch master
non c'è nulla di cui eseguire il commit, l'albero di lavoro è pulito
}}}Lo stato è in '''clean''', ovvero la nostra cartella adesso è allineata col repository (dato che si sono appena sincronizzati).
= Controllo del log =
Il controllo del log è possibile attraverso il comando standard '''git log''', tuttavia viene qui mostrata l'utilità di aver creato l'alias '''git lg'''.
* Controllare il log con il '''comando alias''':{{{
git lg
}}}Si visualizzerà:{{{
* ba12845 (HEAD -> master) - Mario Rossi : README aggiunto (4 minuti fa)
}}}Il log contiene la lista dei commit. Avendo fatto solamente un commit abbiamo un'unica riga dove sono rappresentati:
* '''SHAID''': ogni commit e' identificato da un checksum SHA. Questa e' una particolarità di '''Git''' che lo differenzia da molti altri prodotti simili. Semplificando si può dire che è un ID univoco per ogni commit che permette di distinguerlo dagli altri. L'ID è molto lungo ma in genere viene mostrata solo una piccola parte.
* '''Branch''': quando si crea un repository, viene creato un branch di default chiamato '''master'''. Qua viene scritto il nome del branch cui appartiene il commit. '''HEAD''' è un segnaposto che indica in che punto ci troviamo nel repository. Dato che abbiamo appena committato, HEAD coincide col nostro stato (verrà mostrato avanti a cosa serve).
* '''Nome utente''': il nome dell'utente che ha eseguito il commit. Collaborando con altri utenti verrà mostrato l'identificativo di ognuno.
* '''Messaggio''': è il messaggio scritto nel commit. In particolare è solo la prima riga nel caso in cui il messaggio sia composto da più righe.
* '''Timestamp''': mostra a quando risale il commit.
* Controllare il log con '''comando standard''':{{{
git log
}}}Il messaggio visualizzato:{{{
Author: Mario Rossi
Date: Sat Feb 17 00:58:10 2024 +0100
README aggiunto
}}}Come è possibile immaginare, quando si hanno lunghi log il comando customizzato si rivela molto utile (oltre al fatto, come verrà mostrato, che rappresenta graficamente il branching).
= Aggiunta di altri file =
Vengono qui aggiunti ulteriori file al progetto come un file sorgente minimale ~/gitproject/src/main.cpp e un makefile ~/gitproject/Makefile.
== Creazione file ==
0. Digitare i seguenti comandi (ogni blocco rappresenta un unico comando):{{{
mkdir src
}}}{{{
printf '#include \nint main() {\n\tstd::cout << "Benvenuti su Git!" << std::endl;\n\treturn 0;\n}\n' > src/main.cpp
}}}{{{
echo 'vpath %.cpp ./src'$'\n'$'\n''src = main.cpp'$'\n\n''objects = $(patsubst %.cpp,obj/%.o,$(src))'$'\n\n''$(objects): | obj'$'\n\n''obj:'$'\n\t''@mkdir -p $@'$'\n\n''obj/%.o : %.cpp'$'\n\t''@echo $<'$'\n\t''@$(CXX) $(CXXFLAGS) -c $< -o $@'$'\n\t''mkdir bin'$'\n\t''@$(CXX) $(LDFLAGS) -o bin/main $(objects)'$'\n\n''clean:'$'\n\t''rm -fr bin/ obj/'$'\n' > Makefile
}}}
0. Il comando:{{{
ls -altr
}}}dovrebbe riportare la seguente situazione:{{{
totale 24
-rw-rw-r-- 1 mario mario 16 feb 17 00:51 README
drwxrwxr-x 8 mario mario 4096 feb 17 00:59 .git
drwxr-x--- 27 mario mario 4096 feb 17 01:04 ..
drwxrwxr-x 2 mario mario 4096 feb 17 01:10 src
-rw-rw-r-- 1 mario mario 258 feb 17 01:11 Makefile
drwxrwxr-x 4 mario mario 4096 feb 17 01:11 .
}}}
0. Creare l'eseguibile digitando i comandi:{{{
make
}}}
0. Il comando:{{{
bin/main
}}}dovrebbe restituire il messaggio:{{{
Benvenuti su Git!
}}}
0. Visualizzare il nuovo status digitando:{{{
git status
}}}verrà visualizzato:{{{
Sul branch master
File non tracciati:
(usa "git add ..." per includere l'elemento fra quelli di cui verrà eseguito il commit)
Makefile
bin/
obj/
src/
non è stato aggiunto nulla al commit ma sono presenti file non tracciati (usa "git add" per tracciarli)
}}}Dato che non sono stati modificati file pre-esistenti, ma creati di nuovi ('''Git''' sta mostrando le cartelle create), dobbiamo come nel caso precedente aggiungere a mano i file che ci servono.
In questo caso per i fini del progetto non serve aggiungere tutti i file. I file ''object'' infatti non servono, dato che vengono creati ogni volta dalla compilazione, così come l'eseguibile. Non ha senso metterli sotto configurazione ed è anche dannoso (a lungo andare i file binari aumenteranno le dimensioni del repository).<
>È possibile cancellarli a mano, ma andrebbe fatto ogni volta. Oppure potrebbero essere non aggiunti al repository, ma rimarrebbero sempre in mezzo.
'''Git''' permette di '''filtrare''' i file che non vogliamo, utilizzando '''.gitignore''' nel prossimo paragrafo.
== .gitignore ==
Questo file permette di specificare quali file devono essere esclusi dal repository. È un semplice file di testo con un pattern per riga. Deve essere creato nella root del repository, dove si trova `.git`. I pattern possono essere file o cartelle. Nel nostro caso escluderemo la cartella `bin` e i file oggetto `.o`.
0. Creare il file: {{{
echo 'bin/'$'\n''*.o'$'\n' > .gitignore
}}}
0. Il comando:{{{
cat .gitignore
}}}dovrebbe restituire le seguenti stringhe:{{{
bin/
*.o
}}}Nella prima riga viene esclusa la cartella `bin` (per escludere cartelle occorre mettere '''/''' alla fine), e tutti i file con estensione `.o`.
0. Analizzare lo status:{{{
git status
}}}Risulterà:{{{
Sul branch master
File non tracciati:
(usa "git add ..." per includere l'elemento fra quelli di cui verrà eseguito il commit)
.gitignore
Makefile
src/
non è stato aggiunto nulla al commit ma sono presenti file non tracciati (usa "git add" per tracciarli)
}}}in cui si vede come ora siano assenti i file inclusi in `.gitignore`.
== Modifiche al repository ==
0. Aggiungere tutti i file. Per evitare di scrivere a mano ogni file, è possibile utilizzare il simbolo "'''.'''" per indicarli tutti:{{{
git add .
}}}
0. Eseguire il commit:{{{
git commit -a -m "Aggiunti sorgenti e Makefile"
}}}verrà restituito il seguente output{{{
[master b7c1ae2] Aggiunti sorgenti e Makefile
3 files changed, 28 insertions(+)
create mode 100644 .gitignore
create mode 100644 Makefile
create mode 100644 src/main.cpp
}}}
0. Lo status:{{{
git status
}}}restituisce le seguenti stringhe:{{{
Sul branch master
non c'è nulla di cui eseguire il commit, l'albero di lavoro è pulito
}}}
0. Il log:{{{
git lg
}}}ha come output:{{{
* b7c1ae2 (HEAD -> master) - Mario Rossi : Aggiunti sorgenti e Makefile (2 minuti fa)
* ba12845 - Mario Rossi : README aggiunto (27 minuti fa)
}}}Il contenuto della cartella è sincronizzato col repository, ed è stato aggiunto il commit fra i log.
== Modifiche a file esistenti ==
Viene qui modificato il file `~/gitproject/src/main.cpp`, già presente nel repository.
0. Digitare il seguente comando in modo che venga mostrata la data nel messaggio:{{{
sed -i "s/Benvenuti/`date`: Benvenuti/" src/main.cpp
}}}
0. Per avere conferma digitare:{{{
cat src/main.cpp
}}}il cui output sarà tipo:{{{
#include
int main() {
std::cout << "sab 17 feb 2024, 01:26:54, CET: Benvenuti su Git!" << std::endl;
return 0;
}
}}}
0. Digitare quindi i comandi:{{{
make clean
make
}}}
0. Eseguendo:{{{
bin/main
}}}verrà stampato il messaggio di benvenuto:{{{
sab 17 feb 2024, 01:26:54, CET: Benvenuti su Git!
}}}
== Nuovo commit e nuova situazione ==
0. Verificare la nuova situazione di partenza:{{{
git status
}}}il risultato sarà:{{{
Sul branch master
Modifiche non nell'area di staging per il commit:
(usa "git add ..." per aggiornare gli elementi di cui sarà eseguito il commit)
(usa "git restore ..." per scartare le modifiche nella directory di lavoro)
modificato: src/main.cpp
nessuna modifica aggiunta al commit (usa "git add" e/o "git commit -a")
}}}Il file `src/main.cpp` è stato modificato ma le modifiche non sono ancora state registrate nel repository. Per farlo, occorre committare il file (si evita di parlare dello ''stash'' in questa fase).
0. Eseguire il commit:{{{
git commit -a -m "Aggiunta data in stampa."
}}}che restituirà:{{{
[master 5b235ad] Aggiunta data in stampa.
1 file changed, 1 insertion(+), 1 deletion(-)
}}}
0. Controllare lo stato del repository:{{{
git status
}}}il cui output risulta:{{{
Sul branch master
non c'è nulla di cui eseguire il commit, l'albero di lavoro è pulito
}}}
0. In fine consultare il log:{{{
git lg
}}}che riporta:{{{
* 5b235ad (HEAD -> master) - Mario Rossi : Aggiunta data in stampa. (68 secondi fa)
* b7c1ae2 - Mario Rossi : Aggiunti sorgenti e Makefile (8 minuti fa)
* ba12845 - Mario Rossi : README aggiunto (34 minuti fa)
}}}Il repository è ora sincronizzato col contenuto della cartella e il commit con le modifiche è stato aggiunto.
= Ulteriori risorse =
* [[Programmazione/Git|Guida a Git]]
----
CategoryProgrammazione