Skip to content

Instantly share code, notes, and snippets.

@Cerdic
Created February 19, 2011 09:08
Show Gist options
  • Save Cerdic/834948 to your computer and use it in GitHub Desktop.
Save Cerdic/834948 to your computer and use it in GitHub Desktop.
Notes pendant l'atelier #gitattitude
En premier lieu, se faire un prompt git personalisé "qui tue sa mère" :
cedric$ ls /usr/local/git/contrib/completion/
cedric$ cp /usr/local/git/contrib/completion/git-completion.bash ~/.git-completion.bash
nano ~/.profile
et ajouter à la fin les lignes
source ~/.git-completion.bash
export GIT_PS1_SHOWDIRTYSTATE=1 GIT_PS1_SHOWSTASHSTATE=1 GIT_PS1_SHOWUNTRACKEDFILES=1
export PS1='\[\033[35m\u@\h:\033[36m\W\[\033[0m\033[33m$(__git_ps1 " (%s)")\033[0m\$ '
Du coup dans un repo git le prompt indique la branche, l'etat :
cedric@iMac-de-Cedric-2:gitsession (master %)$
master => branche master
% => il y a des fichiers untracked (non versionnés)
* => il y a des fichiers unstaged (versionnés mais pas encore ajoutés)
+ => il y a des fichiers staged (ajoutés à commit)
# => initial import (on vient de faire un gitinit)
$ => indique qu'il y a un stash en cours, à ne pas oublier de rapatrier (cf git help stash)
indique si on est en merging
Le prompt ajoute aussi de la completion ex :
git checkout or+tab => git checkout origin/master
une config git type :
(https://gist.github.com/470582)
[user]
name = Ton Nom
email = ton@email.tld
[color]
diff = auto
status = auto
branch = auto
[alias]
st = status
ci = commit
co = checkout
fp = format-patch
lg = log --graph --pretty=tformat:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%an %cr)%Creset' --abbrev-commit --date=relative
[core]
pager = cat
Le coller dans le fichier.gitconfig dans ~/
Donne des raccourcis st, ci, co, fp, lg
git lg donne un log clair
####
Comit partiel
Ex :
gitsession (master *)$ git diff
diff --git a/README b/README
index 5cbf3c0..b1c9d43 100644
--- a/README
+++ b/README
@@ -1 +1,5 @@
+ici une modif
+
hop trop bien
+
+ici une autre modif
Il est possible de commit une partie du fichier uniquement.
Comment cela se fait-ce ?
on utilise
gitsession (master *)$ git add -i
etat dans l'index v v etat courant, hors de l'index
staged unstaged path
1: unchanged +4/-0 README
*** Commands ***
1: [s]tatus 2: [u]pdate 3: [r]evert 4: [a]dd untracked
5: [p]atch 6: [d]iff 7: [q]uit 8: [h]elp
What now>
On utilise le mode 5 (patch) :
What now> p
staged unstaged path
1: unchanged +4/-0 [R]EADME
Patch update>> 1
staged unstaged path
* 1: unchanged +4/-0 [R]EADME
Patch update>>
diff --git a/README b/README
index 5cbf3c0..b1c9d43 100644
--- a/README
+++ b/README
@@ -1 +1,5 @@
+ici une modif
+
hop trop bien
+
+ici une autre modif
Stage this hunk [y,n,q,a,d,/,s,e,?]? ?
y - stage this hunk
n - do not stage this hunk
q - quit; do not stage this hunk nor any of the remaining ones
a - stage this hunk and all later hunks in the file
d - do not stage this hunk nor any of the later hunks in the file
g - select a hunk to go to
/ - search for a hunk matching the given regex
j - leave this hunk undecided, see next undecided hunk
J - leave this hunk undecided, see next hunk
k - leave this hunk undecided, see previous undecided hunk
K - leave this hunk undecided, see previous hunk
s - split the current hunk into smaller hunks
e - manually edit the current hunk
? - print help
@@ -1 +1,5 @@
+ici une modif
+
hop trop bien
+
+ici une autre modif
Stage this hunk [y,n,q,a,d,/,s,e,?]? s
Split into 2 hunks.
@@ -1 +1,3 @@
+ici une modif
+
hop trop bien
Stage this hunk [y,n,q,a,d,/,j,J,g,e,?]? y
@@ -1 +3,3 @@
hop trop bien
+
+ici une autre modif
Stage this hunk [y,n,q,a,d,/,K,g,e,?]? n
*** Commands ***
1: [s]tatus 2: [u]pdate 3: [r]evert 4: [a]dd untracked
5: [p]atch 6: [d]iff 7: [q]uit 8: [h]elp
What now> s
2 lignes dans l'index 2 lignes hors de l'index
v v
staged unstaged path
1: +2/-0 +2/-0 README
*** Commands ***
1: [s]tatus 2: [u]pdate 3: [r]evert 4: [a]dd untracked
5: [p]atch 6: [d]iff 7: [q]uit 8: [h]elp
Le fichier est maintenant a la fois dans l'index pret a commit les modifs retenues, et a la fois unstage (hors index) pour la partie qu'on a mis en attente :
git st
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: README
#
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: README
#
gitsession (master *+)$ git commit -m'un commit partiel'
==> https://github.com/Cerdic/gitsession/commit/cdf5c84100f9fc779639ea1fa3ffc99c44f80c64
Avoir le log avec les patchs :
gitsession (master *)$ git lg -p
Commit d'un coup tous les fichiers unstaged (modifie et versionne) mais pas untracked (non versionnes) :
gitsession (master *)$ git commit -am'hop la suite'
// git add -u permet de mettre dans l'index (a commit) une liste de fichier qui matchent une expression
### git checkout
git checkout -b nouvellebranche
permet de creer une branche à partir de l'actuelle
git checkout -t origin/xxxx
permet de definir le tracking de la branche pour la relier au depot d'origin et que les pull/push fonctionnent direct avec lui
de meme, au premier git push d'une branche qu'on envoie, il faut faire un
Permet egalement d'expliciter que 'origin/xxxx' est une branche distante, et git créé une branche local homonyme xxxx
git push -u
(-u : upstream) pour relier la branche locale avec le depot origin que l'on envoie car sinon git ne le fait pas par defaut
### git diff
git diff donne la différence entre ce qui est dans l'index (staged) mais pas encore commit, et ce qui n'est pas encore dans l'index (unstaged)
Pour avoir le diff avec le dernier commit il faut faire
git diff HEAD
### git stash
git stash permet de mettre en attente un lot de modif pour pouvoir travailler sur le repo
cas typique : mettre en attente un patch pas fini pour rebasculer tout de suite sur la version prod, corriger un bug urgent, et revenir ensuite sur tes modifs
permet de prendre l'index en cours et le workging tree (donc y compris les fichiers untracked) et de le sauver, puis de revenir sur le HEAD en hard
-> de là on peut travailler sur le head, faire son bugfix urgent
-> puis quand on a finit, on peut recuperer son stash
Exemple
git stash
cree un stash (idem git stash create) :
gitsession (master *)$ git stash
Saved working directory and index state WIP on master: dc86655 hop la suite
HEAD is now at dc86655 hop la suite
gitsession (master $)$
le prompt indique par le $ qu'on a un stash en cours
quand on a fait ses modifs urgentes et qu'on veut revenir a son patch, on ramene le stash :
git stash apply
ramene le stash dans l'index, mais le garde sauvegardé. C'est trompeur car on risque ne ne plus se rappeler si on l'a utilisé ou non.
On préférera :
git stash pop
qui depile le stash pour le ramener dans l'index :
gitsession (master $)$ git stash pop
Auto-merging README
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: README
#
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (16b1f87b400a19e9e0b98f7ec6795171f1fa8c96)
## git stash list
permet d'avoir la liste des stash en cours
gitsession (master *)$ git stash
Saved working directory and index state WIP on master: 93a5468 commit urgent
HEAD is now at 93a5468 commit urgent
gitsession (master $)$ git stash list
stash@{0}: WIP on master: 93a5468 commit urgent
## git stash branch jesaisplustrop
permet de recuperer le stash pour en faire une branche a partir de l'index courant et d'y poper le stash
Mais attention, quand on pop le stash, tout repasse dans le working tree, en unstaged.
Pour recuperer l'index dans l'etat ou on l'avait mis de cote, il faut faire
git stash pop --index
pour restaurer l'index egalement
## git rebase
permet de changer le point de départ d'une liste de commit
ce qui va entrainer le recalcul du SHA de chaque commit concerné
->Ne peut se faire que sur des commits non encore envoyé
git rebase -i
interactif, permet de réécrire l'historique (pour le rendre plus lisible pour les copains, ou avoir l'air moins mauvais :p )
L'interet principal c'est de réordonner, regrouper des comit atomiques en un comit complet qui a sa coherence et permet ensuite de faire un seul cherry-pick pour recuperer une fonction au lieu de devoir naviguer dans un historique embrouillé de oups dans tous les sens.
Si pendant le rebase on se vautre dans un truc qui marche pas, il suffit de faire
git rebase --abort
pour revenir a l'etat courant avant le rebase et recommencer (ou renoncer :p)
## git log (git lg pour le log enrichi du prompt perso)
- filtrer les log sur l'auteur
git lg --author='xxx@xxx'
- limiter le nombre de logs affichés :
git lg -N
- grepper les logs pour trouver un comit
git lg -E -i --grep='regexp'
-E pour utiliser une vreie expression reguliere etendue (et pas du type glob)
-i pour etre insensible a la casse
git log --oneline
seule la premiere ligne du commit (fait par le log perso git lg)
git log -p
donne le patch de chaque commit
Les options de diff peuvent en général être passées à log
## git diff
git diff --stat
donne les stats de chaque commit
git diff --stat HEAD~4
donne les stats de diff avec l'etat 4 commits avant le HEAD
git diff HEAD~100 --dirstat
permet d'avoir les stats de modif reparti par dossiers, ce qui permet de voir l'impact global d'un lot de commit avant d'entrer dans le detail
## designer des revisions facilement
## par date :
git lg --since='{1 hour ago}'
depuis 1 heure
passer une date au format unix, y compris relative
git lg --until='{1 hour ago}'
jusqu'a il y a une heure
## par message :/[debut du message]
## git show
affiche le diff correspondant a un commit
git show fichier
tel qu'il est dans le working tree
git show :0:fichier
tel qu'il est dans l'index
1 à 3 pour l'etat dans un merge
git show :1:fichier
affiche l'ancetre commun a la fusion
git show :2:fichier
affiche son fichier avant le merge
git show :3:fichier
affiche le fichier externe avant le merge
## git diff
git diff
donne le diff de ce qui est modifié mais encore unstaged
(le diff du working tree)
git diff --cached
donne le diff de l'index uniquement, pas du working tree
donc le diff de ce qui est staged a l'instant t
git diff HEAD
donne le diff de l'etat courant par rapport au HEAD,
donc inclue tout ce qui est tracked (staged et unstaged)
git diff -b
permet d'ignorer les différences d'espaces/identation
git diff -w
permet d'ignorer les différences d'espaces/identation au sein de la même ligne,
mais indique quand meme les lignes vides ajoutées/supprimées
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment