Browse Source

first draft

Davide Alberani 6 years ago
parent
commit
4a9e07f6f8
2 changed files with 649 additions and 0 deletions
  1. 613 0
      git-crash-course.md
  2. 36 0
      index.html

+ 613 - 0
git-crash-course.md

@@ -0,0 +1,613 @@
+# Git crash course
+
+## Davide Alberani <da@erlug.linux.it>
+
+<br />
+Non-corso per non prendere a martellate il monitor quando usate Git.
+
+<br />
+<br />
+This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License: http://creativecommons.org/licenses/by-sa/4.0/
+
+---
+
+## A chi è rivolto
+
+Questo non è ancora chiaro...
+
+---
+
+## Cosa verrà trattato
+
+* i comandi essenziali (porcelain)
+* come gestire i branch
+* le basi per lavorare con repository remoti
+
+-----
+
+## Cosa NON verrà trattato
+
+* gli internals (plumbing) di Git
+* usi avanzati
+* GitHub (sorry)
+* amministrazione di un repository remoto
+* flame wars sui workflow
+
+---
+
+## Cosa è Git
+
+Un sistema di controllo versione distribuito.
+
+Serve per tener traccia dei cambiamenti al proprio codice e per facilitare lo sviluppo condiviso.
+
+<br />
+Il resto lo spiega meglio Wikipedia: https://it.wikipedia.org/wiki/Git%5F%28software%29
+
+-----
+
+## Cosa NON è Git
+
+* non è Subversion o CVS
+* non è un sistema di backup
+
+-----
+
+## Si dice in giro
+
+*Git non avrà segreti per voi, una volta compreso...*
+
+* ...il data model (objects, trees, commits, refs, tags, ...)
+* ...il fatto che tutto è locale
+* ...che i commit sono in realtà snapshot, e non delta rispetto allo stato precedente
+* ...una qualche astrusa teoria a caso
+
+<br />
+
+### Onestamente?
+
+Tutto vero, ma la sua user interface è un mezzo disastro.
+
+---
+
+## Le basi: definizioni
+
+* **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/...
+
+---
+
+## Le basi: prepariamoci
+
+    $ git config --global user.name "Davide Alberani"
+    $ git config --global user.email da@erlug.linux.it
+    $ git config --global color.ui auto
+
+<br />
+
+### Bonus track
+
+* cercare un esempio di ~/.gitconfig avanzato
+
+---
+
+## Le basi: creare un repository
+
+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
+
+-----
+
+## Le basi: creare un repository
+
+### Cosa è successo?
+
+È stata creata la directory **.git** (il **repository**); se abbiamo fatto un clone, sono stati aggiunti i riferimenti al remote alla configurazione.
+
+<br />
+
+### Bonus track
+
+* i repository remoti vengono creati con **--bare** e sono privi di working directory
+* si può posizionare la directory .git in un altro path con **--separate-git-dir**
+
+---
+
+## Le basi: status
+
+Vedere lo stato del sistema:
+
+    $ git status [-s]
+
+<br />
+
+### Stati dei file
+
+* **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
+
+---
+
+## Le basi: add e commit
+
+Modifichiamo un file ed aggiungiamolo alla staging area:
+
+    $ git add prova.txt
+
+Committiamolo:
+
+    $ git commit [-m "messaggio di commit"]
+
+-----
+
+<br />
+
+### Cosa è successo?
+
+Abbiamo aggiunto un file alla staging area, per poi salvare uno snapshot del nostro lavoro.
+
+<br />
+
+### Bonus track
+
+* git rm, git mv
+* come scrivere un messaggio di commit che non susciti sgomento?
+* le directory vuote non vengono salvate: .gitkeep / .gitignore
+* git add --patch
+
+---
+
+## Cosa sono i commit
+
+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.
+
+<br />
+
+### Bonus track
+
+* .gitignore per ignorare certi file
+* è possibile abbreviarli, purché rimangano univoci.
+* vedere https://blog.thoughtram.io/git/2014/11/18/the-anatomy-of-a-git-commit.html
+* e anche https://git-scm.com/book/it/v2/Git-Internals-Git-References
+
+---
+
+## Le basi: tag
+
+Un tag è un puntatore ad un commit:
+
+    $ git tag -a v1.0
+
+<br />
+
+### Bonus track
+
+* esistono sia i tag lightweight che annotated. La differenza principale è che i primi sono solo dei puntatori, i secondi sono oggetti completi: hanno un author e possono essere firmati.
+
+---
+
+## Le basi: la history
+
+    $ 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**
+
+<br />
+
+### Bonus track
+
+Visualizzare solo i commit che hanno coinvolto un dato file:
+
+    $ git log -- file.txt
+
+---
+
+## Le basi: diff
+
+Modifichiamo un file, senza aggiungerlo alla staging area:
+
+    $ git diff
+
+Per vedere quanto è stato posto in staging area:
+
+    $ git diff --staged
+
+<br />
+
+### Bonus track
+
+è possibile creare e riapplicare una patch usando i comandi:
+
+    $ git format-patch [refs]
+    $ git apply patch-file.diff
+
+---
+
+## Scopriamo chi incolpare!
+
+Annotare un file con chi ha effettuato l'ultima modifica riga per riga:
+
+    $ git blame file.txt
+
+---
+
+## Aggiustare i danni
+
+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>
+
+---
+
+## Mettere il lavoro da parte: stash
+
+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}
+
+---
+
+## Storico dei cambiamenti: reflog
+
+La history mostra solo i commit incluse in in branch.
+
+Per vedere tutto ciò che è successo:
+
+    $ git reflog [--relative-date]
+
+<br />
+
+### Quando usarlo?
+
+* a volte è utile capire come ci siamo mossi tra i branch
+* fondamentale per recuperare i **broken commits** (non referenziati da alcun branch)
+
+---
+
+## Branches: cosa sono e perché usarli?
+
+Sono puntatori mobili, spostati ad ogni nuovo commit.
+
+Servono a separare diversi filoni di sviluppo e ad integrare i contributi di altri.
+
+-----
+
+## Branches: sperimentiamo!
+
+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
+
+-----
+
+## Branches: approfondiamo
+
+* **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
+
+---
+
+## Spostarsi
+
+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
+
+<br />
+
+### Bonus track
+
+* cosa è HEAD: reference al branch (o commit) corrente
+* questi operatori sono concatenabili: HEAD~~^2
+* double/tripe dot ranges: git log master..branch; git log --left-right master...branch
+
+---
+
+## Rimettere insieme i pezzi: merge
+
+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
+
+<br />
+
+### Cosa è successo?
+
+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.
+
+-----
+
+## Risoluzione dei conflitti
+
+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
+
+-----
+
+## Conflict files
+
+Cercare sempre tutti i markers <<<<<<<, =======, >>>>>>>
+
+<br />
+
+### Bonus track
+
+* potete usare **meld** come GUI per risolvere i conflitti
+
+---
+
+## Rimettere insieme i pezzi: cherry-pick
+
+    $ git cherry-pick <commit>
+    $ # in caso di conflitti:
+    $ git cherry-pick --continue
+
+<br />
+
+### Cosa è successo?
+
+Si sono prese le modifiche introdotte dai commit elencati, e sono state riapplicate sul branch corrente.
+Sono stati creati dei nuovi commit.
+
+<br />
+
+### Quando usarlo?
+
+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.
+
+---
+
+## Rimettere insieme i pezzi: rebase
+
+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
+
+<br />
+
+### Cosa è successo?
+
+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.
+
+-----
+
+## Rebase
+
+### Quando usarlo?
+
+A spostare più commit e/o a porsi nella condizione di fare un merge pulito, mantenendo una history lineare.
+
+<br />
+
+### Quando NON usarlo?
+
+MAI MAI MAI rebasare dei commit che sono stati condivisi su altri repositori.
+
+---
+
+## Modificare la history
+
+Creiamo un nuovo branch e committiamo 2 o 3 modifiche.  Poi:
+
+    $ git rebase -i master
+
+<br />
+
+### Cosa è successo?
+
+Abbiamo accorpato, scartato o invertito l'ordine dei commit.
+
+<br />
+
+### Bonus track
+
+* l'opzione nucleare: **filter-branch** per creare script che riscrivono la history.
+
+---
+
+## Lavorare con repository remoti
+
+    $ git remote add origin https://github.com/user/repo.git
+    $ git remote -v
+
+<br />
+
+## Bonus track
+
+* **origin** è solamente un default
+* associazione tra branch remoti e locali
+
+---
+
+## Fetch & pull
+
+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
+
+<br />
+
+### Bonus track
+
+* **git pull** è identico a **git fetch ; git merge**
+
+---
+
+## Push
+
+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]]
+
+<br />
+
+### Bonus track
+
+* git push di default non invia i tags
+
+---
+
+## Parlando della history remota...
+
+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.
+
+---
+
+## Idee sparse
+
+Gestire file grandi:
+* https://git-lfs.github.com/
+* https://git-annex.branchable.com/
+
+Gestire la propria directory /etc:
+* etckeeper
+
+<br />
+
+## Pezzi mancanti
+
+* git submodule
+* git bisect
+* git gui; gitk
+* workflows!
+
+---
+
+## Risorse
+
+### Per imparare
+
+* Pro Git: https://git-scm.com/book/en/v2
+* Reference: https://git-scm.com/docs
+* Learn Git Brancing: http://learngitbranching.js.org/
+* Git ready: http://gitready.com/
+* Git Cookbook: https://git.seveas.net/
+* tutorial di Atlassian: https://www.atlassian.com/git/tutorials
+
+<br />
+
+### Utilità
+
+* bash prompt: https://github.com/magicmonty/bash-git-prompt
+* Meld: http://meldmerge.org/
+

+ 36 - 0
index.html

@@ -0,0 +1,36 @@
+<html>
+	<head>
+		<link rel="stylesheet" href="css/reveal.css">
+		<link rel="stylesheet" href="css/theme/white.css">
+        <title>Git crash course</title>
+	</head>
+	<body>
+		<div class="reveal">
+			<div class="slides">
+                <section data-markdown="git-crash-course.md" data-separator-vertical="^\r?\n-----\r?\n$"></section>
+			</div>
+		</div>
+		<script src="js/head.min.js"></script>
+		<script src="js/reveal.js"></script><script>
+Reveal.initialize({
+    width: "100%",
+	height: "100%",
+	margin: 0.1,
+	minScale: 1,
+	maxScale: 1,
+    slideNumber: true,
+    history: true,
+    center: false,
+    dependencies: [
+		{ src: 'lib/js/classList.js', condition: function() { return !document.body.classList; } },
+		{ src: 'plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+		{ src: 'plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+		{ src: 'plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } },
+		{ src: 'plugin/zoom-js/zoom.js', async: true },
+		{ src: 'plugin/notes/notes.js', async: true },
+		{ src: 'plugin/math/math.js', async: true }
+	]
+});
+		</script>
+	</body>
+</html>