Table des matières
GIT
Liens:
Installation
# aptitude install git-core
config
$ git config --global user.name "Thierry JAOUEN" $ git config --global user.email <adresse_email@xxxxxx.fr> $ git config --global core.editor vim
Bases
initialiser depot
On va dans un repertoire de developpement:
$ cd <PATH>
Et puis:
$ git init Initialized empty Git repository in /home/thierry/devel/c/test/.git/
Un coup d'oeil:
$ git status # On branch master # # Initial commit # nothing to commit (create/copy files and use "git add" to track)
Bah oui, y a rien.
ajouter fichiers
$ touch reappro.c $ touch Makefile $ git add reappro.c Makefile
On aurait pu faire:
$ git add *
ou
$ git add .
Un coup d'oeil:
$ git status # On branch master # # Initial commit # # Changes to be committed: # (use "git rm --cached <file>..." to unstage) # # new file: Makefile # new file: reappro.c #
premier commit
$ git commit
(commentaire du commit
grace à vim)
Created initial commit 5d5dfef: My first commit 0 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 Makefile create mode 100644 reappro.c
Un coup d'oeil:
$ git status # On branch master nothing to commit (working directory clean)
Ok, il est content.
modification
On modifie le fichier “reappro.c” … mais bien que git sait que le fichier est modifié, il ne l'incluera pas automatiquement dans le prochain commit …
Donc, aprés modif, soit:
$ git add <le_nom_du_fichier_modifié>
Ce qui n'est pas génial…
Sinon, y a mieux: ajouter -a
au commit
. Exemple:
$ git commit -a -m "seconde version" Created commit 7bb4fe4: seconde version 1 files changed, 13 insertions(+), 0 deletions(-)
( -m
permet de se passer de vim pour mettre un commentaire )
annuler
vite
On souhaite retrouver un fichier dans l'etat du dernier commit
:
$ git checkout <nom_du_fichier>
Mais aussi (et ca s'applique a tout les fichiers modifiés) :
$ git reset --hard
un etat precis
Avec git-log
, on retrouve le “sha” du “commit”. Par exemple:
... commit b2a6c281ed5fcf3b5a8185bb041e732acc54e0a2 Author: Thierry JAOUEN <mymail@myfai.fr> Date: Sat Dec 12 01:03:01 2009 +0100 ...
On y revient, en effacant tout ce qui n'existait à cette époque:
$ git-reset --hard b2a6c281ed5fcf3b5a8185bb041e732acc54e0a2
log
Simple:
$ git log
Avec les differences:
$ git log -p
Un peu moins:
$ git log --stat --summary
A savoir
Branches
bases
Par défaut, on est dans la branche master :
$ git branch * master
On va creer une nouvelle branche:
$ git branch experimental
Voyons ça:
$ git branch experimental * master
On est toujours dans la branche master…
Changeons de branche pour experimental :
$ git checkout experimental Switched to branch "experimental" $ git branch * experimental master
Et voila.
Faire les modifs dans la branche experimental …
Faire un commit a partir de cette branche:
$ git commit -a -m "dans ma branche experimentale"
Et revenir a la branche master :
$ git checkout master
fusion
fusionner la branche courante avec une autre branche:
$ git merge experimental
S'il n'y a pas de conflit, c'est bien.
Sinon, il faut etudier les conflits comme cela:
$ git diff
Corriger les conflits, commit
des changements et refaire un merge .
suppression
Couper (supprimer) une branche, en verifiant (au passage) quelle est bien “mergé” :
$ git branch -d experimental Deleted branch experimental.
Couper (supprimer) une branche sans condition :
$ git branch -D experimental Deleted branch experimental.
clone
simple
On va cloner pour travailler sur le projet…
$ git-clone ssh://<USER@MACHINE>/<PATH>/monprojet ./monprojet
Et voila, le projet est cloné dans le répertoire: monprojet
Modifier le projet…
Y a t'il eu des modifications à la source ?
$ git-pull Already up-to-date.
Non, aucune.
“commiter” ses modifications…
Et puis “push”:
$ git-push Counting objects: .... Compressing objects: .... Writing objects: .... Total ....
Ok.
Mais comment le “distant” sait que j'ai fait une modif ???
En fait git-status
dit ce qui a été modifié.
Alors j'ai fait:
$ git-reset --hard
Et voila…
Mais il doit y avoir plus simple…?
La réponse est là: http://git.or.cz/gitwiki/GitFaq#Whywon.27tIseechangesintheremoterepoafter.22gitpush.22.3F
En résumé: la mise a jour n'est pas faite a cause des conflits toujours possibles avec les modifications faites en local. Sinon, voir “post-update hook” and Co.
en fait, il faut utiliser une repository “bare” (voir plus loin) , qui peut être modifier a loisir sans risque d'interference local |
origin
$ git-remote show origin thierry@xxxxxxxxxx's password: * remote origin URL: ssh://thierry@xxxxxxxxxx/~/devel/yyyyy/labo/kkkkkk Remote branch merged with 'git pull' while on branch master master Tracked remote branch master
bare
voir “git-clone –bare” pour creer un “pur” repository .
Lien: http://www.moroblog.info/Git-via-ssh.html
Vite dit:
Soit un repository classique dans "./myproject"
On clone avec “bare”, ca créé un repertoire de données git.
$ git-clone --bare ./myproject ./myprojet.git
On peut maintenant venir tirer et pousser des documents dans “./myprojet.git”.
Il n'y a pas de risque de conflit sur le repertoire de travail (avec les documents) puisqu'il n'existe pas.
Cela permet de travail vraiment sur un repository a partir de plusieurs sites, y compris en local. (mais toujours en usant de “git-pull git-commit git-push” and so on)
exclude
Il y a plusieurs façons de faire…
La doc:
$ man gitignore
.gitignore
Dans son repertoire de travail, créer un fichier .gitignore
et mettre dedans les repertoires ou les fichiers (pattern) a exclure.
Exemple:
$ cat .gitignore # ---------------- obj/ samples/ # ----------------
Et puis finalement:
$ git add .gitignore
Parce qu'il fait aussi partie du projet, finalement.
Et voila, la commande git-status
devrait ignorer les répertoires.
fusion
(Et non pas “merge”, qui induit une faille spatiotemporelle dans mon cerveau)
Lien: http://www.kernel.org/pub/software/scm/git/docs/howto/using-merge-subtree.html
On veut “fusionner” 2 partie d'un même projet, mais qui ce sont developpé independament.
Par sécurité, j'ai fait ça dans un clone . Ce n'est que tout à la fin, une fois satisfait du résultat, que j'ai fait un push |
Dans le répertoire du projet receveur:
$ git-remote add -f <un_nom_de_projet> <chemin_repo>
( git-remote show
peut maintenant nous montrer ce nom de projet)
$ git-merge -s ours --no-commit <un_nom_de_projet>/master Automatic merge went well; stopped before committing as requested $ git-read-tree --prefix=<subdir/> -u <un_nom_de_projet>/master
( les fichiers sont là, mais les logs ne sont pas à jour… )
$ git-commit -a -m "fusion avec <un_nom_de_projet>" $ git-pull -s subtree <un_nom_de_projet> master
( les logs contiennent aussi ceux du projet importé… )
Et comme on a plus besoin du “remote”…
$ git-remote rm <un_nom_de_projet>
Et voila.
“<subdir>” peut être “<un_nom_de_projet>”.