Git via shell
Di seguito la procedura per copiare in locale (in modo da lavorarci) un proprio repository git già esistente su Github.
- Creazione cartella
mkdir prova cd prova/
- Inizializzazione git
git init
- Aggiunta remote
git remote add origin https://userid@github.com/userid/nomeRepository.git
- Questi comandi per non dover fare ogni volta git push origin master ma solo git push
git config branch.master.remote origin git config branch.master.merge refs/heads/master
- Scaricamento files
git pull
- Impostazione eventuali permessi (se sono root)
cd ../ chown -R apache:apache prova/ chmod -R 775 prova/
- Modifica file del progetto e conferma commit
git add * git commit -m "Initial commit"
- Caricamento file
git push
- Revert changes to modified files
git reset --hard
- Remove all untracked files and directories
git clean -fd
Git pull automatico
Una cosa utile potrebbe essere predisporre un file .php da richiamare via web quando si vuole fare un git pull, in questo caso è possibile creare il file updategit.php nella directory del repository git, contenente:
<?php echo nl2br(shell_exec('git pull 2>&1')); ?>
Devono essere concessi all’utente del server web i permessi in scrittura sulla directory (vedi questo post).
Appunti corso git
Comandi base
- Inizializza il repository
git init
- Stato del repository
git status
- File da utilizzare per specificare file da non versionare
.gitignore
Commit e gestione repository
- Elenco dei diff (aggiungendo l’opzione –cached otteniamo anche i diff in cache)
git diff [--cached]
- Creazione di un commit aggiungendo tutti i file modificati
git commit -A
- Lista dei commit
git log
- Togliere le modifiche dall’area di stage (riportare il file all’ultimo commit)
git checkout -- nomeFile
- Vedere i dettagli delle modifiche (chi ha fatto il commit, quando, su quale riga
git annotate nomeFile
- Unire lo staging al commit precedente, viene creato un nuovo commit e cambiata la history
git commit --amend
Rimozioni e reset
- Rimozione file dal repository e dal file system (è possibile rimuoverlo dalla history ma è un comando sconsigliato e invasivo)
git rm nomeFile
- Rimozione file dal repository
git rm --cached nomeFile
- Togliere un file dallo staging
git reset HEAD nomeFile
- Muovere il puntatore HEAD e BRANCHCORRENTE(MASTER) sul commit passato
Facendo poi un nuovo commit si perdono le modifiche effettuate in precedenza e non committate (il garbage collectore eliminerà poi i file non referenziati)
3 modalità di reset: hard, soft, mixed
git reset
Tagging
Branch e tag non si sincronizzano tramite i push: branch e tag locali cancellati, non vengono eliminati in remoto tramite un push normale
- Aggiungere un tag all’ultimo commit (nomeTag deve essere univoco, possono esserci più tag per un commit)
git tag nomeTag
- Aggiungere tag a un commit
git tag -a nomeTag idCommit
- Vedere l’elenco dei tag (eventualmente filtrandoli)
git tag git tag -l filterName
- Rimuovere un tag
git tag -d nomeTag
Branching
- Crea un nuovo branch dal corrente (il branch non è altro che un puntatore al commit corrente, HEAD è il puntatore al branch corrente)
git branch nomeBranch
- Passare a un altro branch (in generale il comando checkout fa passare da un puntatore all’altro, navigando nella storia del repository e spostando lo HEAD)
git checkout nomeBranch
- Unire un branch verso il master (se ci sono conflitti è segnalato)
git checkout master git merge nomeBranchConModificheDaImportare
- In caso di conflitti viene segnalato (e i file non sono committati, sono messi in staging i file senza conflitti mentre gli altri vanno sistemati) e posso scegliere se tenere la versione corrente, tenere l’incoming o vagliare le modifiche andando a editare il file (togliendo le parti tra << e >>)
Sistemati i conflitti si lanciano i comandi seguenti e si chiude il merge
git add nomeFileConflittoFree git commit
- Rimuovere un branch
git branch -d nomeBranch
Lavorare con remoto
- Clonare il repository remoto in locale
git clone urlRepository
- Scaricare il repository soltanto (non la working copy)
git fetch
- Scaricare il repository remoto e fare merge con il locale (fetch + merge)
git pull
- Aggiornare il repository remoto con i dati del locale
Si può fare solo se il locale e il remoto sono sincronizzati (dopo un pull di allineamento)
Se non specifico il remote e il branche è fatto sul corrente
git push remote branchName
- Una pull (merge) request si fa tramite web gui da un branch a un altro e prende tutti i commit del branch di provenienza, dopo che è stata approvata viene fatto il merge
- In caso di conflitti su push:
- si fa prima un pull
- si lancia uno status
- si tolgono i conflitti
- si fa il commit
- si fa push nuovamente
- …e cosi via finchè non è segnalato niente
- Se in locale è creato un branch va fatto il push con un’opzione in più per crearlo in remoto
git push -u origin branchName
Stash
- Inserire le modifiche in corso in un’area di stash e passare a fare altro
git stash push
- Rimettere le modifiche dallo stage nell’area di working
git stash pop
- Vedere gli stash
git stash list
Rebase e flusso di lavoro
Il rebase riscrive la storia dei commit del repository, ossia sposta i commit del branch attuale davanti al branch master
Vengono quindi importate nel branch attuale le modifiche fatte sul branch master, i conflitti vengono così sistemati sul branch attuale e non sul master. Poi vengono spostati i commit del branch attuale davanti al master.
git rebase
Si usa per tenere pulito il master e tenere la history lineare (conflitti risolti sui branch)
In caso ci sia divergenza è possibile fare:
- il pull, il merge e sistemare poi le cose e poi fare commit e push
- oppure fare pull e rebase per sistemare le cose in locale in modo da tenere pulita la history
git pull --rebase
in questo caso il commit locale viene messo davanti ai commit remoti uno alla volta (davanti al primo commit remoto e viene verificato il conflitto, davanti al II ecc… fino all’ultimo), se c’è un conflitto si ferma l’operazione, va sistemato il conflitto e poi si prosegue con
git add nomeFileConflittoFree git rebase --continue
e così via
Forking
Si usa sui progetti opensource per aggiungere feature o fare fix
- Aggiungere un remote al repository
git remote add nomeRepo urlRepo
- Fare il push sul remote aggiunto
git push nomeRepo
- Fare la pull request (PR) via web gui
Se nel mentre vengono fatte modifiche nel repository originale prima che la PR venga mergiata, devo fare sul fork personale (della feature/modifica)
git pull --rebase
e poi lanciare un push (eventualmente potrebbe essere necessario forzarlo, si può fare con tranquillità essendo un fork personale)
git push [--force]