Skip to content

Latest commit

 

History

History
761 lines (567 loc) · 13.7 KB

File metadata and controls

761 lines (567 loc) · 13.7 KB

Git Atelier

2013-12-02

Anthony Cassaigne

Configuration minimale

git config --global user.name "Prénom Nom"
git config --global user.email mon_email@example.com

Pour lister la configuration

git config --list

On peut également éditer le fichier ~/.gitconfig

Cloner un dépôt

git clone http://url/depot.git

Texte

Cloner un dépôt via ssh

  • En indiquant un chemin absolut.
git clone ssh://gituser@little/home/gituser/anthony_atelier
  • En indiquant un chemin relatif.
git clone gituser@little:anthony_atelier

Attention le prefix ssh n'existe pas dans ce cas !

Travailler localement

Un travail en autonomie

Image

La gestion de l'index

Image

C'est lourd !

Image

Pensez à utiliser

git gui

Il faut un peu de configuration sous OS X

Pourquoi un index ?

  • Pour contrôler ce que l’on commit !
  • Pour commiter des ensembles cohérent.
  • On peut même commiter une partie de fichier.

Petit TP

  • Modifier un fichier et utiliser ces commandes.
git add
git commit –m "message de commit"

Utiliser git status

  • Modifier un fichier
git status
  • Créer un fichier
git status
  • Ajouter à l'index ces deux fichiers et commiter
git add fichier1 fichier2
git commit -m "message"

Synchronisation des dépôts

Commande push

git push

text

Les dépôts sont synchronisés

text

Commit et quelques commandes utiles

Identifier un commit

  • les commits sont identifiable via les SHA1
ba74ed1dae5d2b25618f0a8a43a57218c432da46

C'est un peu long la plupart du temps il suffit d'utiliser la forme courte

ba74ed1

Explorer l'historique

quelques commandes à tester donnant une mise en forme différente.

git log
git log --pretty=oneline
git log --pretty=oneline --abbrev-commit
git log --pretty=oneline --abbrev-commit --decorate

Deux options utile

L'option --stat

git log --stat
...
 blog/Sandro_Mancuso_SCPPP.rst | 17 ++++++++---------
 draft/pelican.rst             | 18 ++++++++++++++++++
 2 files changed, 26 insertions(+), 9 deletions(-)

donne des statistiques en nombre de lignes supprimées et ajoutées pour chaque fichier (texte) du commit.

L'option -p donne les parties du fichier qui sont modifiés.

Comment récuperer une ancienne version du fichier

Voir le contenu d'un fichier à une version donnée :

git show SHA1:./filename.txt

Pour obtenir cette version il faut utiliser la commande checkout

git checkout SHA1 filename.txt

Vous souhaitez obtenir ce fichier avec un autre nom ?

git show SHA1:./filename.txt > toto.txt

GIT DIFF

Petit TP 1/3

  • Partir sur un dépôt dont la commande git status retourne
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)
nothing to commit, working directory clean

Que donne la commande

git diff

?

Suite TP 2/3

Modifier un fichier, que donne la commande

git diff

?

Suite TP 3/3

Mettre le fichier dans l'index ou la zone de staging

git add

Que donne la commande

git diff

?

Quelques explications 1/2

text

Quelques explications 2/2

text

Comparer deux versions d'un fichier

git diff C1 C2

Est différent de

git diff C2 C1
git diff 7904654 62d62b0

text

git diff commit1 commit2

  • Cette commande
git diff 7904654 62d62b0
  • Donne les différences sur tous les fichiers appartenant aux commits.
  • Si l'on ne veut comparer qu'un fichier
git diff 7904654 62d62b0 filename.txt

tooldiff un peu plus d'ergonomie

Pour cela il nous faut configurer l'usage de notre outil préféré. Exemple de configuration sous windows.

[diff]
    tool = winmerge

[difftool "winmerge"]
    cmd = "winmerge.sh \"$LOCAL\" \"$REMOTE\""

[difftool]
  prompt = false

Git quelques bonus...

shortcut pour git add !

   git add -all

Ajouter toutes les modifications et commité !

git ci -a -m "Message de commit"

Annuler...

Retirer un fichier de l'index

git reset --hard HEAD

Annuler toutes les modifications!

ATTENTION PERTE DE DONNEES

git reset --hard HEAD

Rechercher

Au sein des messages de commit ::

git log --grep "<PATTERN>"

Chercher au sein du code ::

git log --stat -G'STRING'
git log -p -S'STRING'

Chercher une chaine de caractères effacée

Chercher une chaine de caractère qui a été effacé au sein du code.

 git log -p -S'STRING' --diff-filter=D

Chercher dans les fichiers du répertoire de travail mais uniquement pour les fichiers sous révision

git grep -e 'STRING'

Le grep pour les fichiers sous révision

Chercher dans les fichiers du répertoire de travail mais uniquement pour les fichiers sous révision

git grep -e 'STRING'

Chercher uniquement dans les fichiers ayant l'extension .c

git grep -e 'STRING' -- '*.c'

Chercher au sein des fichiers stockés dans l'index

git grep --cached -e 'STRING' -- '*.c'

Bonus branche

  • Copier une branche
git branch copie_branche branche_existante
  • Pour créer une branche sur un ancien commit
git branch ma_branche 96a31f2314c091121996

Les Tags

positionner un tag sur le commit courant

 git tag mon_tag

Voir les tags

git tag -n

le -n donne le message associé.

la liste des tags avec le SHA1 ::

git show --summary --oneline --decorate

#Amélioration de l'environnement...

Un prompt sympa et pratique

########################################################################
# Matthew's Git Bash Prompt
########################################################################
        RED="\[\033[0;31m\]"
     YELLOW="\[\033[0;33m\]"
    GREEN="\[\033[0;32m\]"
       BLUE="\[\033[0;34m\]"
  LIGHT_RED="\[\033[1;31m\]"
LIGHT_GREEN="\[\033[1;32m\]"
      WHITE="\[\033[1;37m\]"
 LIGHT_GRAY="\[\033[0;37m\]"
 COLOR_NONE="\[\e[0m\]"

function parse_git_branch {
  git rev-parse --git-dir &> /dev/null
  git_status="$(git status 2> /dev/null)"
  branch_pattern="^# On branch ([^${IFS}]*)"
  remote_pattern="# Your branch is (.*) of"
  diverge_pattern="# Your branch and (.*) have diverged"

  if [[ ! ${git_status}} =~ "working directory clean" ]]; then
    state="${RED}"
  fi
  # add an else if or two here if you want to get more specific
  if [[ ${git_status} =~ ${remote_pattern} ]]; then
    if [[ ${BASH_REMATCH[1]} == "ahead" ]]; then
      remote="${YELLOW}"
    else
      remote="${YELLOW}"
    fi
  fi
  if [[ ${git_status} =~ ${diverge_pattern} ]]; then
    remote="${YELLOW}"
  fi
  if [[ ${git_status} =~ ${branch_pattern} ]]; then
    branch=${BASH_REMATCH[1]}
    echo " (${branch})${remote}${state}"
  fi
}

function git_dirty_flag {
  git status 2> /dev/null | grep -c : | awk '{if ($1 > 0) print "⚡"}'
}

function prompt_func() {
    previous_return_value=$?;
    #The lowercase w is the full current working directory
    #prompt="${TITLEBAR}${BLUE}[${RED}\w${GREEN}$(parse_git_branch)${BLUE}]${COLOR_NONE}"

    #Capital W is just the trailing part of the current working directory
    prompt="${TITLEBAR}${BLUE}[${RED}\W${GREEN}$(parse_git_branch)${BLUE}]${COLOR_NONE}"

    if test $previous_return_value -eq 0
    then
        PS1="${prompt}> "
    else
        PS1="${prompt}${RED}>${COLOR_NONE} "
    fi
}

PROMPT_COMMAND=prompt_func

Autre ressources pour un prompt

  • simple
  • plus évolué

Autre piste oh-my-zsh !!!!

  • A regarder.

##Bon le git add c'est lourd !

  • Essayons git number

##Installation git number

git clone https://github.com/holygeek/git-number
cd git-number
cp git-* ~/bin
vi ~/.bashrc
# alias
alias gn='git number --column'
alias ga='git number add'

#Les branches

##Création d'une branche

git branch ma_branche
  • Maintenant il faut travailler dans la branche
git checkout ma_branche

Merge d'une branche

  • merge de la branche test dans master.
git checkout test
... modifs, commit ...
git checkout master
git merge test

TP

git branch test
git checkout test
vi a.txt
.... modifier le fichier
ga 1
git ci -m "ma modif"
git checkout master
git merge kkk

Stash

##Interruption !

  • Je travail sur une évolution
  • On me demande en urgence un correctif !
  • ha non pas un commit à motié fonctionnel
  • vive git stash
git stash

Une zone de sauvegarde

  • plus exactement une sorte de pile
git stash list
  • récupérer le dernier stash
git stash apply
  • récupérer un stash particulier
git stash apply stash@{2}

Rebase

Rebase 1/2

  • Le premier usage de rebase est de permettre de "rebaser" une branche sur un commit cible. Image

Rebase 2/2

  • Lors du rebase git va rejouer un à un les commits de la branche que l'on rebase.
  • Dans notre exemple l'ensemble des commit qui sont de couleur bleu sur la branche jaune.
  • En cas de conflit il nous faudra comme dans un merge réaliser un choix :
    • prendre la version du fichier de la branche bleue ?
    • prendre la version du fichier de la branche jaune ?
    • ou éditer ce fichier et en faire une autre version.

Mettons en oeuvre

Cet exemple

Image

Exemple de rebase 1/2

Création des commits sur la branche master
Commit C1

echo Hello > a.txt
git add a.txt
git commit -m "Hello"

Commit C2

echo Salut >> a.txt
git add a.txt
git commit -m "Salut"
git branch bleue

Commit C3

echo Bonjour>> a.txt
git add a.txt
git commit -m "Bonjour"

Exemple de rebase 2/2

Création des commits de la branche bleue
Commit B1

git checkout bleue
echo Eau > b.txt
git add b.txt
git commit -m "Eau"

Commit B2

echo Vin >> b.txt
git add b.txt
git commit -m "Vin"

GO pour le rebase

git checkout bleue
git rebase master

et maintenant amenons master au niveau de bleue

git checkout master
git merge bleue 
ou
git rebase bleue

Rebase avec conflit !

Image

#Voici la séquence de commit

  • utiliser le script atelier_git_rebase2.sh
git init .
echo Hello > a.txt
git add a.txt
git commit -m "C1 file a.txt"
echo Salut >> a.txt
git add a.txt
git commit -m "C2 file a.txt"
echo Bonjour >> a.txt
git add a.txt
git commit -m "C3 file a.txt"
git branch bleue HEAD~1
git checkout bleue
echo Eau > b.txt
git add b.txt
git commit -m "B1 file b.txt"
echo Good morning >> a.txt
git add a.txt
git commit -m "B2 file a.txt"

Go pour le rebase

git checkout bleue
git rebase master
...conflit... 
...pour le résoudre utiliser...
...les mêmes outils que le merge...
git status
vi a.txt
git add a.txt
git rebase --continue

Ré-écrire l'histoire

Rebase pour réécrire l'histoire

git init .
echo zzzz > trash.txt
git add trash.txt
git commit -m "Start"
echo Salut > a.txt
git add a.txt
git commit -m "C1 file a.txt"
echo Eau > b.txt
git add b.txt
git commit -m "C2 file b.txt"
echo Bonjour >> a.txt
git add a.txt
git commit -m "C3 file a.txt"
echo Vin >> b.txt
git add b.txt
git commit -m "C4 file b.txt" 

Surnoms aux commits passés

  • Connaissez-vous la notation ?
  • HEAD~1
  • HEAD~2
  • Cela se traduit par HEAD moins un commit pour HEAD1 et HEAD moins deux commits pour HEAD2. Image

Ok réécrivons l'histoire !

  • Pour réécrire l'histoire des quatre derniers commit voici la commande
git rebase -i HEAD~4

Nous entrons dans un mode intéractif. Git crée un fichier quasi identique à un fichier de log où il est possible de choisir les opérations à réaliser.

Rebase -i

Le fichier a ce format

pick 76d2aa4 C1 message de commit
pick dc8f5fe C2 message de commit
pick 81d308a C3 message de commit 
pick 9d58418 C4 message de commit

Opération pick

Image

Opération reword

Image

Opération squash

Image

Opération edit

Image

Le coup du commit vide !

Gloups ! Presque ! D'où le

git init .
git commit --allow-empty -m "Empty commit, it's base commit !"

cherry-pick

  • Réaliser des prélévements de commit.
git checkout bleue
git cherry-pick 427a6e4666466b77e18bcd01b949a3aef8e34bd8
  • On prélève le commit 427a6e4666 (de la branche master) pour le copier sur la branche bleue.

Tester le cherry-pick

  • Lancer le script :
atelier_git_cherry-pick.sh
  • pour se retrouver dans la situation souhaitée

Bien plus à découvrir

  • rebase
  • cherrypick
  • le hunk expliquer
  • configuration des branches distantes : smart, simple etc...
  • rerere
  • plein de workflow possible