Uso di git

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

  1. Aggiungere un remote al repository
    git remote add nomeRepo urlRepo
  2. Fare il push sul remote aggiunto
    git push nomeRepo
  3. 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]
Aggiungi ai preferiti : permalink.

I commenti sono chiusi.