Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
GIT - Concetti Fondamentali
GIT - Concetti Fondamentali
—-
Concetti chiave
Branching
Integrare le modifiche
Best practices
I tre stati in cui si può trovare un file incluso (tracked) in un progetto GIT:
● Modified --->ANCORA SUL WORKING TREE, IL FILE RISULTA MODIFICATO
RISPETTO AL COMMIT CORRENTE (CONTRASSEGNATO COME <HEAD>)
● Staged (Added) ---> IL FILE MODIFICATO E’ STATO INCLUSO DALL’UTENTE NEL
PROSSIMO COMMIT
● Committed ---> IL FILE E’ STATO AGGIUNTO AL REPOSITORY
GIT adotta il concetto di remote repository, per permettere la sincronizzazione tra repository
differenti.
Formalmente, per GIT è ‘remote repo’ ogni repository noto a quello su cui si stia lavorando.
In effetti non esiste alcuno schema gerarchico tra i vari repository, e nulla vieta di lavorare
appoggiandosi esclusivamente ai repository locali dei singoli sviluppatori.
Spesso, comunque, si usa predisporre un repository remoto come “single source of truth”.
In questo caso, tipicamente il repository remoto viene installato come ‘bare repo’, un tipo di
repository speciale che contiene solo la storia dei commit come log dei diff tra commit, ma
non contiene direttamente il codice sorgente.
GIT supporta, oltre al trasferimento locale (due repository sullo stesso computer), tre
protocolli di rete per la sincronizzazione, di conseguenza la URL di un repo non locale può
essere in formato http(s), ssh o git. I protocolli più utilizzati sono https ed ssh.
ESEMPI:
SSH → git remote add origin git@github.com:nodejs/node.git
HTTPS → git remote add origin https://github.com/nodejs/node.git
Il nome di default che GIT assegna al remote di cui viene fatto un clone locale è origin
Per coerenza questo è il nome che si usa assegnare al repository autoritativo remoto.
L’ipotesi è quella in cui si voglia configurare un remote per una cartella di sorgenti già
esistente. In questo caso, dopo aver inizializzato sia il repository locale che quello remoto,
dalla root dei sorgenti in locale, bisognerà eseguire il comando
Per salvare temporaneamente dei cambiamenti la cui sorte sia ancora incerta all’atto del pull
(Es: devo scaricare il master - ho delle modifiche in sospeso di cui non voglio fare il commit),
esiste il comando git stash che salva le modifiche in una sorta di ‘limbo’ da cui poi
possono essere recuperate per riapplicarle allo stato corrente.
La sintassi completa è
Integrare le modifiche
Il comando per integrare le modifiche presenti in due branch differenti è git merge
Il merging è il modo in cui git rimette insieme la storia del codice a seguito di un fork.
Il comando git merge permette di prendere le linee di sviluppo indipendenti create con git
branch e reintegrarle in un unico branch.
Quando il percorso che va dall’ultimo commit del branch corrente al branch target è lineare,
git può eseguire un tipo particolare di merge, cosiddetto fast-forward, in cui semplicemente
sposta il tag HEAD - che identifica il branch e il commit corrente - all’ultimo commit del
branch target.
⟲ undo: annullare le azioni su GIT
GIT offre strumenti estremamente versatili per i casi in cui si debba ritornare su una
decisione presa in precedenza:
git rm [file(s)]
questo comando, senza ulteriori parametri, elimina il file sia dall’index che dal filesystem.
Può verificarsi il caso in cui si voglia escludere un file dal VCS senza eliminarlo dal
filesystem (tipicamente, viene eseguito git add . ma successivamente si realizza che un
dato file (o insieme di file) non va tenuto sotto VCS - es: librerie, file di metadati osx, file di
configurazione IDE … - ma non è stato aggiunto a .gitignore)
In questo caso, la soluzione prevede due passaggi:
Es: Ho creato un progetto git, apro la cartella dei sorgenti con VS Code e modifico
un’impostazione dell’editor salvandola a livello di progetto. VS Code genera quindi una
cartella .vscode che è specifica rispetto alla mia configurazione personale, e
tendenzialmente non vorrò condividere.
Una situazione abbastanza comune si verifica quando uno sviluppatore esegue il commit
troppo presto, magari dimenticando di aggiungere alcuni file o con un messaggio
inadeguato. E’ possibile rieseguire lo stesso commit utilizzando l’opzione --amend
Questo comando utilizza la staging area (index) per il commit. Se non sono state fatte
modifiche dall’ultimo commit, lo snapshot sarà identico, e sarà possibile cambiare il
messaggio. Se sono presenti modifiche, verranno integrate nell’ultimo commit registrato, che
verrà sovrascritto.
Riportare il codice allo stato di un precedente commit
E’ interessante notare che il comando utilizzato per conoscere lo stato del working tree e
della staging area (index) mostra un suggerimento su come annullare i cambiamenti
presenti. Il comando git status risponde così:
$ git add *
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
Se un file è incluso nell’index (staging area) il comando git reset lo riporta nel working
tree mantenendo le modifiche presenti nel codice.
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: README.md -> README
Il comando è:
git checkout -- [file(s)]
Se l’intenzione è quella di annullare in toto l’ultimo commit o anche una porzione di storia, i
due passaggi possono essere ridotti ad uno richiamando git reset con il parametro --hard
e specificando il commit che si vuole ripristinare
Quando git non è in grado di determinare univocamente che operazione compiere su un file,
risponde con un errore:
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.
Se apro il file su cui si è verificato il conflitto troverò che git lo ha modificato inserendo, per la
riga che non sa come risolvere, entrambe le possibilità, quella corrispondente a HEAD (il
branch corrente) e quella relativa al branch da integrare (il parametro del comando git
merge)
In questo caso la risoluzione del conflitto richiede che venga corretto il file rimuovendo le
annotazioni del VCS e scegliendo una delle soluzioni (eventualmente anche riscrivendo la
parte per incorporare entrambe le modifiche).
A modifiche terminate e file salvato, bisognerà aggiungere il file all’INDEX, effettuare il
commit delle modifiche e rilanciare il merge
difftool e mergetool
git prevede due comandi per aiutare nella risoluzione dei conflitti:
Scenario:
- due branch, master e will_conflict
- due file di partenza: asd.txt e file.txt
- su due commit paralleli
- master modifica asd.txt:L1 e file.txt
- will_conflict modifica asd.txt:L1 ed elimina file.txt
in evidenza in giallo i comandi per applicare con un click le modifiche apportate da uno o
dall’altro branch; cliccando su una delle soluzioni il file viene aggiornato rimuovendo le
annotazioni VCS e la versione scartata, e può quindi essere salvato.
git mergetool
Merging:
asd.txt
file.txt
git add .
git commit -am 'merge conflict su asd(modifica x) e su file(keep y)'
git merge will_conflict
Already up to date.
Plugin git per VSCODE
Vs code contiene un pannello per la gestione del VCS git, che tiene traccia delle modifiche
al working tree e ne propone l’integrazione fornendo all’utente un input box per inserire il
messaggio:
i comandi di git sono accessibili dal menu a tendina che si apre cliccando sui tre pallini
Git History ( donjayamanne.githistory )
aggiunge a VSCODE una vista log su tutto il progetto e sul singolo file, accessibile
cliccando l’icona
nel pannello VCS, oppure dall’elenco dei comandi -> CTRL+MAIUSC+P (Win) ||
CMD+MAIUSC+P (OSX/linux)
● an unobtrusive current line blame annotation at the end of the line with detailed blame
information accessible via hovers
● authorship code lens showing the most recent commit and # of authors to the top of files
and/or on code blocks
● a status bar blame annotation showing author and date for the current line
● many rich Side Bar views
○ a Repositories view to visualize, navigate, and explore Git repositories
○ a File History view to visualize, navigate, and explore the revision history of the
current file
○ a Line History view to visualize, navigate, and explore the revision history of the
selected lines of current file
○ a Search Commits view to search and explore commit histories by message, author,
files, id, etc
○ a Compare view to visualize comparisons between branches, tags, commits, and
more
● on-demand gutter blame annotations, including a heatmap, for the whole file
● on-demand gutter heatmap annotations to show how recently lines were changed, relative to
all the other changes in the file and to now (hot vs. cold)
● on-demand recent changes annotations to highlight lines changed by the most recent
commit
● many powerful commands for exploring commits and histories, comparing and navigating
revisions, stash access, repository status, etc
● user-defined modes for quickly toggling between sets of settings
● and so much more
Operazioni da GUI ( VSCODE )
git add .
dal pannello integrato git
Risoluzione conflitti:
se un merge eseguito da VSCODE genera conflitti, il programma apre direttamente la
finestra mergetool sui file in stato conflicted
risolti i conflitti e salvato i file ci si può portare sul pannello integrato git che sarà già
predisposto per concludere il merge
Best practices
da https://git-scm.com/book/it/v2/Per-Iniziare-Una-Breve-Storia-di-Git
Il kernel di Linux è un progetto software open source di grande portata. ... Nel 2002, il
progetto del kernel Linux iniziò ad utilizzare un sistema DVCS proprietario chiamato
BitKeeper. Nel 2005 … fu revocato l’uso gratuito di BitKeeper. Ciò indusse ... a sviluppare
uno strumento proprio …
Obbiettivi del nuovo sistema erano i seguenti:
● Velocità
● Design semplice
● Ottimo supporto allo sviluppo non-lineare (migliaia di rami paralleli)
● Completamente distribuito
● Capacità di gestire, in modo efficiente (velocità e dimensione dei dati), grandi progetti
come il kernel Linux
La grande flessibilità del meccanismo di branching di git ha dato spazio alla definizione di un
certo numero di varianti in relazione alle relative buone prassi.
- MASTER
- DEVELOP
Il principio di base è che, quando uno sviluppatore deve lavorare su una nuova feature, crea
un topic branch a partire da develop, e a lavoro finito esegue il merge del topic branch (o
feature branch) su develop.
Solo quando la feature è testata e funzionante, develop viene integrato con master (che
traccia il codice di produzione).
---
note wip:
https://medium.com/@thomaspoignant/simple-git-flow-who-works-dac82430e484
https://guides.github.com/introduction/flow/
Comandi utili da CLI
stampa il log del branch corrente omettendo gli hash dei commit
stampa il log di tutti i branch mostrando solo il titolo del messaggio di commit ed esponendo
graficamente gli eventuali merge
LINK INTERESSANTI