Git commands

Git

Qualche breve appunto personale per l'utilizzo di GIT  dalla console GIT  BASH Git è un sistema di controllo di versione libero e open source. E' diventato uno standard per il controllo di versione, assieme ad altri sistemi come Subversion e CVS

  • Per usare git:
Scarica git per OSX,Windows o Linux
 
  • Per l'aiuto in linea del programma:
$ git help <verb>
$ git <parola> --help
$ man git-<verb>

  • per creare un nuovo repository git, eseguire la console con permessi di amminsitratore,  creare una nuova directory, entrare ed eseguire
$ git init
  • Importazione in locale dei file di un progetto (SVN checkout ):

creare una copia di un repository locale:

$ git clone /percorso/del/repository

ad esempio:

$ git clone git@bitbucket.org:percorso/del/repository.git
 
$ git clone nomeutente@host:/percorso/del/repository

Se il server remoto è protetto da credenziali, il comando sarà:

 $ git clone https://nomeutente:password@host/percorso/del/repository

E' possibile generare una chiave SSH in locale, da copiare poi sul server per evitare che ogni volta venga richiesta la password ( https://git-scm.com/book/it/v1/Git-sul-Server-Generare-la-Propria-Chiave... )

Attenzione, clonando il repo con l'http, ( clone https://..... ) verrà sempre richiesta la password: è necessario clonare il repo con l'ssh ( git@bitbucket.org:....)

L'ambiente di lavoro di git è diviso in tre 'sezioni': la prima è la Directory di lavoro che contiene i files attuali. Il secondo è l'Index o STAGE che fa da spazio di transito per i files e per finire l'HEAD che punta all'ultimo commit fatto.

I file modificati passano allo stage, e per essere mandati sul repository devono essere 'commitati' nell'HEAD. Dall'HEAD vengono poi PUSHati su.

Per avere lo stato del progetto locale rispetto al repository

$ git status

Per spostarsi da un branch all'altro ( svn switch )

$ git checkout existingbranch 
  • aggiungere e validare modifiche (aggiungendole all'Index, ossia in 'stage for commit'):
$ git add <nomedelfile>

es: git add . alla radice del progetto oppure

$ git add *
  • Per validare le modifiche fatte:
$ git commit -m "Descrizione della commit"
  • Si può anche fare in un unico comando l'add e la commit:
$ git commit -a -m 'commento della commit'
Ora il file è nell'HEAD, ma non ancora nel server remoto.
  • Per inviare queste modifiche al repository remoto ( svn commit )
$ git push origin master
  • per aggiornare il tuo repository locale alla commit più recente ( svn update ): 
$ git pull
  • revert di modifiche in locale:
Puoi eliminare i cambiamenti fatti in locale a un file:
$ git checkout -- <nomedelfile>
  • Per eliminare tutti i cambiamenti fatti in locale, recupera l'ultima versione dal server: ( svn revert )
$ git fetch origin

$ git reset --hard origin/master

 

Risoluzione dei Conflitti.

Per risolvere i conflitti è necessario intervenire con un editor. Ad esempio quando in due 'rami' viene apportata una modifica nella stessa linea ma qualcun'altro apporta una modifica differente sulla stessa riga e si ha un Conflitto di unione su cui bisogna intervenire a mano. Il comando git status ci da informazioni sul conflitto:


# On branch branch-b
# You have unmerged paths.
#   (fix conflicts and run "git commit")
#
# Unmerged paths:
#   (use "git add ..." to mark resolution)
#
# both modified:      test.md
#
no changes added to commit (use "git add" and/or "git commit -a")

Aprendo il file in conflitto troveremo dei marker che indicano dove inizia il conflitto, la parte che riguarda la nostera modifica e la parte che invece riguarda la modifica del nostro collega:


the number are
<<<<<<< HEAD
nine
=======
eight
>>>>>>> branch-a

Nel branch-a voi avete scritto nine, mentre il collega ha scritto eight. Il marcatore per la zona del conflitto  

inizia con

<<<<<<< 

 e finisce con  

>>>>>>>

I due blocchi in conflitto sono contraddistinti da un

=======

A questo punto ci sono diverse possibilità. E' possibile mantenere entrambe le modifiche, tenere solo le proprie o tenere solo quelle del collega.In ogni caso è necessario intervenire per rimuovere il conflitto.

Ad esempio realizzare una riga che tenga conto di entrambe le modifiche, come ad esempio

the number are nine, or eight, depending on who you ask.

Risolvere un conflitto di cancellazione di un file.

Succede quando viene cancellato un file ma qualcun'altro apporta un amodifica allo stesso file e GIT non sa se tenere il file con la modifica o cancellarlo. 

Nel primo caso, prima è necessario risolvere il conflitto mantenendo le nuove modifiche.

 

CONFLICT (modify/delete): README.md deleted in HEAD and modified in branch-b. Version branch-b of README.md left in tree.
Automatic merge failed; fix conflicts and then commit the result.

$git status
# On branch branch-c
# You have unmerged paths.
#   (fix conflicts and run "git commit")
#
# Unmerged paths:
#   (use "git add/rm ..." as appropriate to mark resolution)
#
# deleted by us:      README.md
#
no changes added to commit (use "git add" and/or "git commit -a")

Una volta eliminati i demarcatori del conflitto, si aggiunge il file e si committa di nuovo. 

 

$git show | head

mostra lo stato del merge.

Nel caso si voglia risolvere il conflitto rimuovendo il file, invece 

 

CONFLICT (modify/delete): README.md deleted in HEAD and modified in branch-c. Version branch-c of README.md left in tree.
Automatic merge failed; fix conflicts and then commit the result.

$git status
# On branch branch-d
# You have unmerged paths.
#   (fix conflicts and run "git commit")
#
# Unmerged paths:
#   (use "git add/rm ..." as appropriate to mark resolution)
#
#   deleted by us:      README.md
#
no changes added to commit (use "git add" and/or "git commit -a")

E' necessario utilizzare il comando git rm

 

$git rm README.md
 README.md: necessità si fondono
 rm 'README.md'
git add README

E dopo commitare con un messaggio:

 

$git commit
[branch-d 6f89e49] Merge branch 'branch-c' into branch-d

$git show | head
commit 6f89e49189ba3a2b7440fc434f351cb041b3999e
Merge: 211261b fcc1093
Author: tekkub :bear:  
Date:   Sat Jun 1 18:43:01 2013 -0700

    Merge branch 'branch-c' into branch-d
>
    Conflicts:
        README.md

 

Nel caso si debba correggere una commit, se non si sono fatte altre modifiche, si fa l'amend:

$ git commit --amend

viene aperto un editor in cui cambiare la commit dopo è necessario mandare su la modifica. Se si cerca di pushre normalemente, git ci avvisa che è necessario prima fare una pull, perché vede che è cambiato lo STORICO. Ma se è cambiato solo lo storico ( vale anche per lo squash delle commit ) non si deve fare la pull ( che causerebbe un MERGE ) ma forzare la push con il -f ( force )

$ git push origin hotfix/TM2-1803 -f

Per spostarsi tra i branch, e scaricare le ultime modifiche di quel branch:

$ git fetch && git checkout master

Capitolo a parte le cofigurazioni: nome utente, editor ecc sono configurabili con il comando config: per averne la lista:

$ git config --list

Per cambiarem, ad esempio, l'editor che si apre in caso di conflitti o merge

$ git config --global core.editor "'C:/Program Files/Notepad++/notepad++.exe' -multiInst -nosession"

Squash / rebase

$git rebase -i HEAD~2

( unire le ultime 2 commit ) si apre l'editor, si tiene in pick la commit che si vuole tenere mentre le altre si cambiano in squash

pick 01d1124 Adding license
squash 6340aaa Moving license into its own file
squash ebfd367 Jekyll has become self-aware.
squash 30e0ccb Changed the tagline in the binary, too.

quella in cima è la prima commit, l'ultima è in basso l'editor ci propone un nuovo messaggio per la query, poi si deve pushare con forza ( push -f ) per forzare git ad accettare il cambiamento. Se si decide di abbandonare lo squash:

$git rebase --abort

Reset

Il reset si fa quando il locale è modificato rispetto al repository e dobbiamo annullarle. Possiamo pensare al git revert come un modo "sicuro" di annullare le modifiche, mentre il git reset è uno dei pochi comandi git capace di cancellare effettivamente il lavoro: è quindi da usare con cautela.

git reset <file>

Rimuove il file specificato dalla zona di stage ma lascia la directory di lavoro invariata. Questo togle dallo stage un file senza sovrascriverne le modifiche.

git reset

Ripristina la zona di stage in modo che corrisponda alla più recente commit, ma lasciare la directory di lavoro invariato. Questo toglie dallo stage  tutti i file senza sovrascrivere eventuali modifiche, dandovi l'opportunità di ri-costruire un istantanea dello stage ripartendo da zero.

git reset --hard

Ripristinare la zona di stage e la directory di lavoro in modo che corrisponda alla commit più recente .

Oltre alle modifiche non in stage, il  --hard dice a Git di sovrascrivere tutte le modifiche nella directory di lavoro, anche, ossia, cancella tutte le modifiche  in modo da assicurarsi che si vuole veramente di buttare via i vostri sviluppi locali prima di utilizzarlo.

 git reset <commit>

Sposta il "puntatore" dalla cima del ramo corrente indietro per reimpostare l'area di stage. Tutte le modifiche apportate dal risiederanno nella directory di lavoro, che consente di ri-committare la storia del progetto.

git reset --hard 

Spostare il puntatore dal ramo corrente indietro per ripristinare sia l'area di stage che la directory di lavoro in modo che corrispondano. Questo cancella non solo le modifiche ma anche le commit dopo la <commit> indicata.