Questions fréquentes



Inscription impossible sur GitLab.

Les accès sont envoyés par email. S’adresser à un administrateur.


Il n'y a aucun projet dans GitLab.

L’utilisateur n’est pas configuré correctement (il manque une attribution au bon groupe). Il faut s’adresser à un administrateur.


Certains gros fichiers sont de simples fichiers textes (Linux).

Cela peut être le cas pour modules/client/exe/SAINETV4.exe. Cela signifie que git-lfs n’a pas été installé correctement. Une fois installé, il faudra supprimer le fichier et le récupérer à nouveau avec la commande suivante:

git checkout .

Voir également cet article à propos de git-lfs.


Commits dans plusieurs branches, mais invisibles sur GitLab

Il faut publier (push) dans toutes les branches modifiées. Par défaut, un git push ne publie que les commits dans la branche courante.


Comment savoir si la branche a été publiée ?

Utiliser la commande suivante:

git status
Switched to branch 'fix/sainet/fix-conflict'
Your branch is ahead of 'origin/fix/sainet/fix-conflict' by 2 commits.
  (use "git push" to publish your local commits)

Dans le cas ci-dessus, il y a 2 commits n’ont pas été publiés.

Lorsque tout est publié, la réponse obtenue est:

Your branch is up-to-date with 'origin/fix/sainet/fix-conflict'.
nothing to commit, working tree clean

Comment annuler des modifications non committées ?

Attention:

Efface les modifications définitivement !

Pour annuler les modifications d’un fichier (qui n’a pas encore été committé):

git checkout <path/to/file>

Pour annuler toutes les modifications d’un répertoire récursivement:

git checkout <path/to/folder>

Merge Request libérée, mais il y a encore des modifications à faire.

Si la Merge Request commence par le préfixe WIP: ou Draft:, alors elle n’est pas libérée et par conséquent il n’y a aucun problème (voir ici).

Si la Merge Request est effectivement libérée, il y plusieurs cas de figures:

  1. La Merge Request/branche existe toujours et il s’agit juste d’une micro-modification à ajouter: il suffit commit puis push la modification. Elle sera automatiquement intégrée dans la Merge Request.
  2. La Merge Request/branche existe toujours et plusieurs modifications sont encore nécessaires: retourner éditer la Merge Request pour ajouter le préfixe Draft: et ainsi éviter qu’elle ne soit intégrée dans le master.
  3. La Merge Request/branche a déjà été intégrée dans le master et il s’agit d’une micro-modification à ajouter: faire la modification, commit puis push. Il faudra réouvrir une Merge Request sur GitLab. La branche n'aura pas les dernières modifications du master.
  4. La Merge Request/branche a déjà été intégrée dans le master et plusieurs modifications sont encore nécessaires: repartir dans le processus standard de création de branche.

Commit dans une branche supprimée (Merge Request fermée).

Lorsqu’une Merge Request est intégrée dans le master, la branche est supprimée sur le serveur. Par contre, il se peut qu’elle soit toujours présente en local sur la machine et que par inadvertance (ou manque de rigueur), il y ait des nouveaux commits à l’intérieur.

Les commits ont été publiés (Synch/push)

Cela va recréer la branche sur le serveur avec vos nouvelles modifications. Il faut donc créer une nouvelle Merge Request pour qu’elles soient intégrées au master.

Les commits n’ont pas été publiés, mais concernent effectivement cette branche

Dans ce cas, le plus simple est effectivement de publier les commits et de recréer la Merge Request sur GitLab.

Les commits ne conernent pas cette branche

Les commits sont sur la mauvaise branche.


Annuler les x derniers commits.

Attention:

Ne fonctionne que pour les commits qui n’ont pas encore été publiés (push) sinon voir ici.

Pour cette opération, il faut ouvrir un console git (Git Shell dans Windows) et aller dans le répertoire du projet.

Pour savoir le nombre de commits qu’il est possible d’annuler:

git status
Your branch is ahead of 'origin/test/reset' by 2 commits.
  (use "git push" to publish your local commits)
nothing to commit, working tree clean

Dans ce cas, la branche est en avance (ahead) de 2 commits (donc ces 2 commits n’ont pas été publiés).

Pour annuler les 2 derniers commits:

git reset HEAD~2

Cela va garder les modifications qui y ont été faites (donc rien ne sera perdu). Il sera ensuite possible de les recommitter ensemble si besoin est.


Annuler les x derniers commit publiés.

Il y a deux possibilités: la première est de créer un commit de revert en effectuant les commande suivantes dans un Git Shell (s'assurer qu'il n'y a pas d'autres changements):

#revert les commits et les ajoute pour le prochain commit
git revert -n <commit1> <commit2> ...

#ces opérations sont optionnelles
#unstage les modifications ajoutées par le revert et voir les diffs
git reset HEAD
git diff

Il est possible de ne pas mettre l’option -n lors du revert, cela provoquera automatiquement un commit d’annulation qui n’aura plus qu’à être publié.

L’autre possibilité est de revenir en arrière et de forcer le push. Cela va remplacer la branche en ligne avec la branche locale.

Attention:

Il y a un risque de perdre des modifications si l’état de la branche n’est pas certain !

# récupération la branche en ligne pour être sur d'avoir la dernière version
git pull

# revenirde 3 commits en arrière
git reset HEAD~3

# force la mise à jour en ligne
git push --force

Modifications (non committées)

Si un git status montre une liste de fichiers modifiés (qu’ils soient en attente de commit -staged- après un git add ou pas), alors il y a des modifications non committées.

Sur le master (à jour)

Dans ce cas, il suffit de créer une branche directement via un git checkout puis committer et publier les modifications.

git checkout -b <branch>
git add <fichiers>
git commit

# à ce moment git indique que la branche n'existe pas et donne la
# commande exact à taper avec l'option --set-upstream
git push

Une fois la branche poussée en ligne, il suffit de rafraîchir GitLab pour qu’il propose automatiquement la création d’une nouvelle Merge Request.

Récupérer le master à jour

Il faut mettre les modifications en attente (les “stasher”), puis mettre à jour le master.

# enregistre les modification en interne dans git, elle ne sont
# plus visibles (temporairement)
git stash

# mise à jour du master
git pull

# réapplication des modifications
git stash pop

A partir de là, les modifications sont (ré)appliquées sur le master. Il suffit de se référer à la partie précédente pour créer une nouvelle branche.

Depuis une autre branche

De même que la partie précédente, il faut simplement “stasher” les modifications, puis se mettre sur le master pour les réappliquer.

git stash

git checkout master
git pull

git stash pop

A partir de là, les modifications sont appliquées sur le master. Il suffit de se référer à la partie précédente pour créer une nouvelle branche.


Commit sur la mauvaise branche.

Suivant l’état dans lequel le repo se trouve (commits publiés ou non), cela va complexifier la tâche. Pour rappel, le 1er point de la checklist !

Committé, mais pas publié

Deux cas possibles:

  1. Il faut garder l’historique: il suffit d’effacer les commits concernés, de changer de branche, puis de refaire un commit.
  2. Il y a plusieurs commits (tous non publiés) et il faut les récupérer dans une nouvelle branche: 2.1 Créer une nouvelle branche 2.2 Sélectionner la branche du point précédent:
git fetch
git checkout <branch-name>

2.3 Récupérer les commits qui ont été faits sur l’autre branche (attention à l’ordre):

git cherry-pick <commit1> <commit2> ...

2.4 Retourner sur la branche originale et annuler les commits du point précédent:

git checkout <orig-branch>
git revert <commit1> <commit2> ...

Ou bien s’il s’agit des n derniers commits:

git checkout <orig-branch>
git reset HEAD~n

Committé et publié

Dans ce cas, impossible d’effacer les commits incriminés. Il va falloir faire des commits d’annulation. En gros, la procédure est la même que ci-dessus, sauf qu’au point 2.4 il faudra forcément faire un git revert.


Comment lancer le ssh-agent/add automatiquement?

Il faut d’abord créer le .bashrc sous le répertoire home.

  • ~ sous linux.
  • C:\Users\<nom d'utilisateur> sous Windows.

La commande echo ~ peut être lancée dans un terminal bash pour voir quel est le répertoire en question. Ensuite, copier-coller le script bash ci-dessous:

# Copied from https://help.github.com/articles/working-with-ssh-key-passphrases
env=~/.ssh/agent.env

agent_load_env () { test -f "$env" && . "$env" >| /dev/null ; }

agent_start () {
    (umask 077; ssh-agent >| "$env")
    . "$env" >| /dev/null ; }

agent_load_env

# agent_run_state: 0=agent running w/ key; 1=agent w/o key; 2= agent not running
agent_run_state=$(ssh-add -l >| /dev/null 2>&1; echo $?)

if [ ! "$SSH_AUTH_SOCK" ] || [ $agent_run_state = 2 ]; then
    agent_start
    echo "Requesting permission for ssh..."
    ssh-add
elif [ "$SSH_AUTH_SOCK" ] && [ $agent_run_state = 1 ]; then
    echo "Requesting permission for ssh..."
    ssh-add
fi

unset env

Il faut faire attention à ce que les variables ne soient pas les mêmes si le .bashrc contient déjà quelque chose. Si la clé privée n’est pas dans le répertoire par défaut ~/.ssh/id_rsa, il faudra explicitement informer SSH où la trouver avec la commande ssh-add:

...
echo "Requesting permission for ssh..."
ssh-add ~/chemin/vers/la/clé
...

Le mot de passe de la clé privée SSH sera demandé lors de la première ouverture du terminal:

> Requesting permission for ssh...
> Enter passphrase for /c/Users/you/.ssh/id_rsa:
> Identity added: /c/Users/you/.ssh/id_rsa (/c/Users/you/.ssh/id_rsa)

À noter que le processus ssh-agent continuera de fonctioner jusqu’à ce que la machine soit éteinte.


La Merge Request m'indique qu'il y a un conflit, que faire ?

Cela signifie que depuis que la branche a été créée, d’autres Merge Request ont été intégrées dans le master et que certains changements entrent en conflits avec ceux de la branche.

Dans GitLab, il y a un bouton dans la Merge Request qui permet de résoudre les conflits directement.


Récupérer des modifs du master.

Il arrive d’avoir besoin d’une modification qui a été mergée sur le master après que la branche a été créée. Dans ce cas, il faut faire un rebase.

Pour faire cela, il faut ouvrir une console et suivre les étapes suivantes:

# 1. mettre à jour la branche master
git checkout master
git pull

# 2. se remettre dans la branche que à modifier
git checkout <branch>

# 3. demander un rebase depuis le master
git rebase origin/master

Cette commande va prendre tous les commits actuels dans la et les réexecuter l’un après l’autre à partir de la dernière version du master. Si cela se passe bien, la commande va montrer ce genre d’output.

Applying: new page to store the initial request of the parents
Applying: wanted errors to make the documentation

Ensuite, si le status (git status) indiquera ceci:

Your branch and 'origin/<branch>' have diverged,
and have 5 and 2 different commits each, respectively.
  (use "git pull" to merge the remote branch into yours)
nothing to commit, working tree clean

Git dit de faire un git pull, mais il ne faut pas le faire ! En faisant cela, le rebase fait précédemment sera “annulé” et la branche locale sera dans un état bizarre qui posera d’autre soucis.

Autre source de méfiance, le status indique Your branch and ‘origin/’ have diverged. Dans le cas d’un rebase, ce message est normal, car le hash des commits a changé (ils ont été “rejoutés”). Si un rebase n’est pas en cours, alors c’est que la branche est dans un état bizarre et il faut annuler ce que qui a été fait !

Pour s’assurer que c’est correct, utiliser la commande git cherry -v master. Cela ne devrait lister que les commits qui ont été faits dans la branche locale (les commits du master ne devraient pas être affichés).

Une fois que le rebase est fait que la branche dans le bon état, alors il est serain de (re)publier la branche. Il faut ajouter l’option –force afin de mettre à jour la branche car les commits ont changés.

git push --force

Mettre à jour sa branche après un rebase.

Lorsque l’historique d’une branche a été modifié et renvoyé en ligne (typiquement par un rebase), si cette branche est en local sur la machine (checkout), alors il va y avoir des conflits. C’est normal car l’historique (donc les hashs des commits) ne sont plus les mêmes et git va dupliquer les commits locaux (ceux présents sur la machine) et ceux en ligne. L’historique local de la branche sera donc complètement aberrant.

Pour mettre à jour la branche locale par rapport à ce qu’il y a en ligne, suivre la procédure suivante:

# se remettre dans le master
git checkout master
git pull

# suppression de la branche locale
git branch -D <branch>

# récupération de la branche en ligne
git checkout <branch>

Une autre possibilité un peu plus brutale est de remettre le HEAD exactement comme celui en ligne, mais cela nécessite de supprimer toutes les modifications locales non committées:

git fetch
git reset --hard origin/<branch>

Réorganiser l'historique des commits

Tant qu’une branche n’a pas été mergée sur le master, il est possible de modifier la liste des commits (changer l’ordre, en supprimer, en combiner plusieurs, etc).

Cela fonctionne de la même manière qu’un rebase, sauf que l’option -i est ajoutée:

#raccourci pour récupérer la dernière version du master
git fetch

#rebase interactif
git rebase -i origin/master

A ce moment, git va ouvrir un éditeur de texte avec la liste des commits que à éditer:

pick 17a1106658 Changelog template update
pick 30799f7ec6 Updates the documentation
pick 56739ab427 Fixes typo

Chaque ligne est composée d’un mot-clé (pick), du commit et du libellé du commit. Il est possible de modifier l’ordre des lignes, d’en supprimer ou encore de changer le mot-clé pour que git s’occupe de réoganiser les commits.

Dans l’exemple ci-dessus, le 3ème commit corrige une typo dans le 1er commit. Etant donné que la Merge Request n’est pas mergée, il est considéré comme inutile et il peut être mergé dans le 1er commit. Le fichier doit donc être modifié de la manière suivante:

pick 17a1106658 Changelog template update
fixup 56739ab427 Fixes typo
pick 30799f7ec6 Updates the documentation

Le mot-clé fixup indique à git de fusionner cette ligne dans la précédente en ignorant le message de commit. Donc, au final c’est comme s’il n’y avait eu qu’un seul commit avec les bonnes modifications.

D’autres mots-clés sont disponibles et expliqués dans le fichier ouvert par git lors du rebase.

Une fois le rebase effectué, la branche aura divergé, il faudra donc appliquer un git push --force pour publier les changements.

Ce mécanisme est extrêmement pratique en terme de maintenance car il évite la surmultiplication de commit dont les changements ne font que corriger des oublis dans les autres commits de la même branche.


Supprimer les branches locales mergées.

Une fois qu’une branche a été mergée, elle peut être supprimée localement (elle est intégrée au master).

# passer sur la branche master
git checkout master

# récupération des branches et suppression de celles dont le remote n'existe plus
git fetch --prune

# suppression des branches qui ont été mergées sauf le master
git branch --merged | grep -v master | xargs git branch -D