Non-corso per non prendere a martellate il monitor quando usate Git.
This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License: http://creativecommons.org/licenses/by-sa/4.0/
Questo non è ancora chiaro...
Un sistema di controllo versione distribuito.
Serve per tener traccia dei cambiamenti al proprio codice e per facilitare lo sviluppo condiviso.
Il resto lo spiega meglio Wikipedia: https://it.wikipedia.org/wiki/Git%5F%28software%29
Git non avrà segreti per voi, una volta compreso...
Tutto vero, ma la sua user interface è un mezzo disastro.
Working directory: i file su cui state lavorando
Staging area (o Index): dove mettiamo da parte le modifiche che finiranno nel prossimo commit
Commit: snapshot dello stato in un certo momento
(fare) Checkout: aggiornare i file nella working directory ad un dato branch/commit/...
$ git config --global user.name "Davide Alberani"
$ git config --global user.email da@erlug.linux.it
$ git config --global color.ui auto
Creare un nuovo repository partendo da una directory (vuota o meno):
$ git init
Clonare un repository remoto esistente:
$ git clone https://github.com/user/repo.git
È stata creata la directory .git (il repository); se abbiamo fatto un clone, sono stati aggiunti i riferimenti al remote alla configurazione.
Vedere lo stato del sistema:
$ git status [-s]
Untracked: nuovi file nella working directory, non ancora aggiunti
Unmodified: file che non sono cambiati dal commit precedente
Modified: modificati nella working area e non ancora aggiunti alla staging area
Staged: nella staging area, pronti per il prossimo commit
Modifichiamo un file ed aggiungiamolo alla staging area:
$ git add prova.txt
Committiamolo:
$ git commit [-m "messaggio di commit"]
Abbiamo aggiunto un file alla staging area, per poi salvare uno snapshot del nostro lavoro.
Sono uno snapshot dell'intero stato del sistema in un dato momento, identificati da un hash.
I commit hash sono generati partendo da: messaggio, committer, author, dates, tree, parent hash.
Un tag è un puntatore ad un commit:
$ git tag -a v1.0
$ git log [--stat] [-p] [--graph] [--decorate] [--color] [-2]
Rappresenta la storia dei commit dal punto corrente (o da/a qualsiasi punto indicato).
Si può limitare agli ultimi N commit con -N
Visualizzare solo i commit che hanno coinvolto un dato file:
$ git log -- file.txt
Modifichiamo un file, senza aggiungerlo alla staging area:
$ git diff
Per vedere quanto è stato posto in staging area:
$ git diff --staged
è possibile creare e riapplicare una patch usando i comandi:
$ git format-patch [refs]
$ git apply patch-file.diff
Annotare un file con chi ha effettuato l'ultima modifica riga per riga:
$ git blame file.txt
Modificare l'ultimo commit (ad esempio per aggiungere un file, modificare il commit message o l'autore):
$ git commit --amend [--author="Name Surname <user@example.com>"]
Un file stato aggiunto per sbaglio alla staging area:
$ git reset HEAD -- file
Riportare un file modificato nell'ultimo stato committato/staged:
$ git checkout -- file
Ho fatto un casino nella working directory. Riportiamo tutto allo stato dell'ultimo commit:
$ git reset --hard HEAD
Voglio creare un nuovo commit che annulla le modifiche introdotte da un commit precedente:
$ git revert [-n] <commit>
Capita di dover mettere da parte il lavoro nella directory corrente senza voler committare:
$ git stash
Vedere la lista:
$ git stash list
Riapplicare una modifica messa in stash:
$ git stash pop [stash]
Eliminarne uno:
$ git stash drop stash@{0}
La history mostra solo i commit incluse in in branch.
Per vedere tutto ciò che è successo:
$ git reflog [--relative-date]
Sono puntatori mobili, spostati ad ogni nuovo commit.
Servono a separare diversi filoni di sviluppo e ad integrare i contributi di altri.
Creare un branch:
$ git branch fix/bug-123
Visualizzare tutti i branch:
$ git branch -a
Cancellare un branch locale:
$ git branch -d [--force] fix/bug-123
Spostarsi su un branch:
$ git checkout fix/bug-123
Creare e spostarsi in un singolo comando:
$ git checkout -b fix/bug-123
master è solamente un default
fate caso all'asterisco, è il branch corrente
dare nomi significativi; prefissi: bugfix/, fix/, improvement/, feature/, task/
aggiungere issue di riferimento
refs: nome collettivo per riferirsi ad HEAD, branches, tags
detached HEAD: ci siamo spostati su un commit che non è l'head di un branch
Salire di 3 livelli, seguendo sempre il primo parent commit (in caso di merge):
$ git checkout HEAD~3
Salire di un livello, seguendo il secondo parent commit (in caso di merge):
$ git checkout HEAD^2
Partendo da master:
$ git branch -b fix/bug-123
$ # editiamo nuovofile.txt
$ git add nuovofile.txt
$ git commit
$ git checkout master
$ git merge fix/bug-123
fast-forward! master era più indietro rispetto a fix/bug-123, e quindi abbiamo semplicemente spostato master.
Non è stato neppure creato un nuovo commit.
Il comando commit ha le opzioni --ff-only e --no-ff per decidere come comportarsi.
Partendo da master:
$ git branch -b fix/bug-123
$ # editiamo file.txt
$ git add file.txt
$ git commit
$ git checkout master
$ # editiamo file.txt in maniera differente, sulle stesse righe
$ git add file.txt
$ git commit
Mergiamo:
$ git merge fix/bug-123
$ # risolviamo i conflitti
$ git add file.txt
$ git commit
Cercare sempre tutti i markers <<<<<<<, =======, >>>>>>>
$ git cherry-pick <commit>
$ # in caso di conflitti:
$ git cherry-pick --continue
Si sono prese le modifiche introdotte dai commit elencati, e sono state riapplicate sul branch corrente. Sono stati creati dei nuovi commit.
Ad esempio per backportare un fix su diversi release branch, o se vi siete accorti che un certo commit era da fare su un altro branch.
Poniamoci nella stessa situazione divergente dell'esempio in cui abbiamo usato merge, e poi:
$ git checkout fix/bug-123
$ git rebase master
$ # risolviamo eventuali conflitti
$ git rebase --continue
Abbiamo preso tutti i commit di fix/bug-123 e li abbiamo ri-applicati su master, che nel mentre era andato avanti.
Tutti i commit specifici di fix/bug-123 sono cambiati.
A spostare più commit e/o a porsi nella condizione di fare un merge pulito, mantenendo una history lineare.
MAI MAI MAI rebasare dei commit che sono stati condivisi su altri repositori.
Creiamo un nuovo branch e committiamo 2 o 3 modifiche. Poi:
$ git rebase -i master
Abbiamo accorpato, scartato o invertito l'ordine dei commit.
$ git remote add origin https://github.com/user/repo.git
$ git remote -v
Aggiornare il repository locale con i dati di un remoto:
$ git fetch --prune --tags origin
Differenze tra il master locale e quello remoto:
$ git log master..origin/master
Scaricare gli aggiornamenti dal remoto e mergiare il branch corrente:
$ git pull origin
Aggiungere al repository remoto un branch locale:
$ git push --set-upstream origin local-branch-name
Aggiungiamo i cambiamenti locali ad un branch remoto:
$ git push --tags [origin [master]]
Cosa da non fare MAI (salvo non ne siate davvero convinti): pushare modifiche alla history.
Questo perché se qualcuno sta lavorando sullo stesso branch remoto, romperete tutto.
Gestire file grandi:
Gestire la propria directory /etc: