====== GIT ====== Liens: *http://blog.rom1v.com/2012/04/prompt-bash-pour-git/ *http://www.kernel.org/pub/software/scm/git/docs/gittutorial.html *http://linux.efrei.fr/doku.php/tutoriaux/git *http://progit.org/book/ ===== Installation ===== # aptitude install git-core ==== config ==== $ git config --global user.name "Thierry JAOUEN" $ git config --global user.email $ git config --global core.editor vim ===== Bases ===== ==== initialiser depot ==== On va dans un repertoire de developpement: $ cd 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 ..." 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 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 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 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:////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 ( ''git-remote show'' peut maintenant nous montrer ce nom de projet) $ git-merge -s ours --no-commit /master Automatic merge went well; stopped before committing as requested $ git-read-tree --prefix= -u /master ( les fichiers sont là, mais les logs ne sont pas à jour... ) $ git-commit -a -m "fusion avec " $ git-pull -s subtree master ( les logs contiennent aussi ceux du projet importé... ) Et comme on a plus besoin du "remote"... $ git-remote rm Et voila. "" peut être "". ==== publier son git ==== Lien: http://www.bluishcoder.co.nz/2007/09/how-to-publish-git-repository.html