396 lines
12 KiB
Markdown
396 lines
12 KiB
Markdown
# Utilisation de git pour ScoDoc
|
||
|
||
Le dépôt est <https://scodoc.org/git/viennet/ScoDoc>
|
||
|
||
La branche `master` est celle de ScoDoc 9, d'où sont issues les paquets
|
||
distribués (*releases*). Les développements ont lieu sur d'autres branches
|
||
(`api`, `dev92`, `entreprises`, ...) avant d'être intégrés après tests. La
|
||
branche `Scodoc7` était l'ancienne (jusqu'à septembre 2021) version de ScoDoc.
|
||
|
||
Ci-dessous quelques pense-bête qui peuvent servir.
|
||
|
||
## Hot fixes (internes)
|
||
|
||
Pour les développeurs internes (écriture sur le dépôt master), un exemple
|
||
basique illustrant le cycle de développement:
|
||
|
||
```bash
|
||
# Créer une branche
|
||
# si besoin (travail en cours), utiliser git stash avant
|
||
git checkout master
|
||
git branch hotfix
|
||
git checkout hotfix
|
||
... dev, test ...
|
||
git add ...
|
||
git commit -m "fixed ..."
|
||
git checkout master
|
||
git merge hotfix
|
||
git branch -d hotfix
|
||
# publication
|
||
|
||
# éventuellement: git stash pop
|
||
```
|
||
|
||
Dans la plupart des cas, on travaillera sur son propre dépôt (clone du dépôt
|
||
origine), et on proposera une *pull request* (PR, *demande d'ajout* en français).
|
||
|
||
## Mettre à jour votre branche
|
||
|
||
Quand vous travaillez dans votre branche `ma_branche`, pour lui appliquer les
|
||
mises à jour de `master` (remote), faire:
|
||
|
||
```bash
|
||
git pull origin master
|
||
```
|
||
|
||
## Autre exemple
|
||
|
||
Vous travaillez sur un clone du dépôt principal ("origin"), obtenu par exemple via
|
||
|
||
```bash
|
||
git clone https://scodoc.org/git/ScoDoc/ScoDoc.git
|
||
```
|
||
|
||
remplacer par l'URL de votre dépôt sur gitea au besoin. Si vous avez votre
|
||
propre dépôt sur gitea, utilisez deux "remote": l'un pour votre dépôt gitea (ici
|
||
nommé `mon_origin`), l'autre pour le dépôt principal ScoDoc (ici nommé
|
||
`origin`).
|
||
|
||
```bash
|
||
git remote add origin https://scodoc.org/git/viennet/ScoDoc.git
|
||
git remote -v
|
||
mon_origin https://xxx.xxx (fetch)
|
||
mon_origin https://xxx.xxx (push)
|
||
origin https://scodoc.org/git/viennet/ScoDoc.git (fetch)
|
||
origin https://scodoc.org/git/viennet/ScoDoc.git (push)
|
||
```
|
||
|
||
Ensuite, tout est prêt, vous créez votre branche:
|
||
|
||
```bash
|
||
git checkout -b ma_branche
|
||
```
|
||
|
||
et la poussez sur votre dépôt: (remplacer `mon_origin`au besoin)
|
||
|
||
```bash
|
||
git push -u mon_origin ma_branche
|
||
```
|
||
|
||
Ajoutez au fur et à mesure vos commits comme d'habitude. Mais régulièrement
|
||
(chaque jour), mettez à jour pour éviter de diverger de la branche `master` (ou
|
||
autre suivant les cas) de ScoDoc:
|
||
|
||
```bash
|
||
git pull origin master
|
||
```
|
||
|
||
Vous pouvez alors à tout moment soumettre une PR propre.
|
||
|
||
## Commandes utiles, en vrac
|
||
|
||
- `git log -L:fonction_python:fichier.py`
|
||
- Commits locaux: `git log @{u}..`
|
||
|
||
### Refactoring
|
||
|
||
Lint tous les fichiers modifiés:
|
||
|
||
```bash
|
||
git status | grep modified | grep .py | awk '{print $2}' | xargs pylint -E
|
||
```
|
||
|
||
Affiche les variables non définies dans un fichier:
|
||
|
||
```bash
|
||
pylint --disable=all -e E sco_parcours_dut.py | grep undefined-variable | awk '{print $4;}' | sort | uniq | tr -d \'
|
||
```
|
||
|
||
Prépare un sed pour renommer les variables non définies:
|
||
|
||
```bash
|
||
for f in *.py
|
||
do
|
||
pylint --disable=all -e E "$f" | grep undefined-variable | awk '{print "sed -i .bak s/"$4"/scu."$4"/ '$f'";}' | sort | uniq | tr -d \'
|
||
done
|
||
```
|
||
|
||
Restore les modes au besoin (SAMBA les changent parfois):
|
||
|
||
```bash
|
||
git diff -p -R --no-color | grep -E "^(diff|(old|new) mode)" --color=never | git apply
|
||
```
|
||
|
||
Note pour travailler sur VirtualBox:
|
||
|
||
```text
|
||
addgroup scodoc vboxsf
|
||
```
|
||
|
||
## Préparation d'une PR (Pull Request) (niveau avancé)
|
||
|
||
### Principes généraux
|
||
|
||
Les remarques de cette section visent à obtenir une relecture facile de votre
|
||
demande d'ajout (*pull request*, dite "PR"):
|
||
|
||
- Éviter les modifications de forme qui ne changent pas le sens du code. L'utilisation de
|
||
[`black`](https://black.readthedocs.io/) est obligatoire : elle permet de normaliser la présentation
|
||
du code. Cela évite de générer des différences ne représentant que des
|
||
changements de mise en forme (indentation, passages à la ligne). Cela évite
|
||
aussi au développeur d'avoir à y réfléchir, autant de temps gagné !
|
||
|
||
- Avoir un nombre d'étapes de validation faible (idéalement un seul commit pour
|
||
les PR courantes - peu volumineuses).
|
||
|
||
- La PR doit toujours être énoncée par rapport au dernier commit de la branche
|
||
que vous visez (en général `master` du dépôt original).
|
||
|
||
### Manipulations
|
||
|
||
Les manipulations sont décrites selon quatre phases du développement : l'installation,
|
||
la mise en place, le suivi et la livraison.
|
||
|
||
#### L'installation
|
||
|
||
Il est pratique d'avoir en ligne les deux dépôts git distants que vous pouvez
|
||
utiliser : votre dépôt personnel (`https://scodoc.org/git/<user>/<dépôt>.git`) et
|
||
le dépôt officiel (`https://scodoc.org/git/ScoDoc/ScoDoc.git`).
|
||
|
||
pour ajouter une référence (et lui donner un nom) vers un dépôt distant, entrez
|
||
la commande:
|
||
|
||
```bash
|
||
git remote add nom_remote https://scodoc.org/git/ScoDoc/<dépôt>.git
|
||
```
|
||
|
||
Par la suite vous aurez donc une référence vers votre dépôt personnel (`perso`)
|
||
et une référence vers le dépôt officiel (`officiel`). Si vous avez initialement
|
||
cloné l'un des deux dépôts, la référence vers le dépôt d'origine existe et a pour nom
|
||
`origin`.
|
||
|
||
La commande vous exposant tous les dépôts connus est :
|
||
|
||
```bash
|
||
git remote -v
|
||
```
|
||
|
||
### Mise en place
|
||
|
||
L'objectif de ce paragraphe est de créer une branche locale basée sur le master
|
||
du dépôt officiel et bien sur de lui donner un nom.
|
||
|
||
pour cela (**attention cela va écraser les éventuels fichiers modifiés**. Si
|
||
vous souhaitez conserver les modifications en cours, encadrez les lignes
|
||
suivantes par `git stash` (avant) et `git stash apply` (après) :
|
||
|
||
```bash
|
||
git reset --hard officiel/master
|
||
git checkout -b ma_modif
|
||
```
|
||
|
||
À partir de là, vous pouvez modifier, tester, développer et commit votre travail.
|
||
|
||
### Suivi
|
||
|
||
Si votre développement prend plusieurs jours, il est probable que la branche
|
||
principale évolue pendant ce temps.
|
||
|
||
Pour garder la cohérence, il est nécessaire de réintégrer en local les
|
||
modifications de la branche principale. Ceci peut se faire de deux façons.
|
||
|
||
- Une fusion (`merge`) applique toutes les modifications en un seul commit).
|
||
C'est la méthode couramment utilisée.
|
||
|
||
- Un `rebase` rejoue tous les commits de la nouvelle branche par dessus l'état
|
||
le plus à jour de la branche principale (il en résulte un historique plus
|
||
linéaire).
|
||
|
||
Les commandes git correspondantes :
|
||
|
||
```bash
|
||
git pull officiel master
|
||
```
|
||
|
||
ou encore
|
||
```bash
|
||
git fetch officiel
|
||
git merge officiel/master
|
||
```
|
||
|
||
Pour un rebase (à éviter en temps normal):
|
||
|
||
```bash
|
||
git fetch officiel
|
||
git rebase officiel/merge
|
||
```
|
||
|
||
### La livraison
|
||
|
||
Ça y est. Vous avez terminé le développement. IL n'y a plus qu'à demander
|
||
l'intégration. Ceci se fait en plusieurs étapes (vous êtes bien sûr toujours sur
|
||
la branche locale `ma_modif` et toutes vos modifications ont été commitées).
|
||
|
||
#### Étape 1 : faire l'inventaire des fichiers impliqués
|
||
|
||
```bash
|
||
git fetch officiel/master
|
||
git diff --name-only officiel/master
|
||
```
|
||
|
||
#### Étape 2 : passer black sur les fichiers modifiés
|
||
|
||
Cette étape est automatique avec les bons réglages sous VSCode (pas trouvé
|
||
l'équivalent sous *pyCharm*).
|
||
|
||
À défaut les lignes suivantes réalisent le même travail :
|
||
|
||
```bash
|
||
for fn in $(git diff --name-only officiel/master)
|
||
do
|
||
python3 -m black $fn
|
||
done
|
||
```
|
||
|
||
Faire une première lecture rapide pour vérifier qu'il ne reste pas de fichiers
|
||
modifiés accidentellement.
|
||
|
||
Pour obtenir la modification sur un fichier spécifique (`app/fichier.py` par
|
||
exemple):
|
||
|
||
```bash
|
||
git diff officiel/master app/fichier.py
|
||
```
|
||
|
||
Utilisateurs Windows : Vérifiez bien que les réglages de fin de ligne suivent
|
||
bien les règles Linux: pas de retour chariot (noté CR ou `\r`) en fin de ligne
|
||
mais un seul caractère line feed (noté LF ou `\n`). Le cas échéant, réglez
|
||
votre IDE pour cela.
|
||
|
||
À ce niveau là de la procédure, vous n'avez plus dans votre branche locale que
|
||
les différences strictement nécessaires à votre correctif.
|
||
|
||
#### Étape 3 : résumez tous les commits depuis le point de divergence en un seul commit
|
||
|
||
**Rarement nécessaire, uniquement si vous avez de nombreux petits commits.**
|
||
|
||
Repérez le point de divergence de votre branche locale avec officiel/master
|
||
(normalement `git merge-base HEAD officiel/master`)
|
||
|
||
Demander un `rebase` interactif depuis ce point :
|
||
|
||
```bash
|
||
git rebase -i $(git merge-base HEAD officiel/master)
|
||
```
|
||
|
||
*Explications*: Le rebase interactif permet d'enregistrer un suite de
|
||
manipulation de commit dans un seul fichier texte. Le fichier texte qui reprend
|
||
tels quels tous les commits concernés (et donc qui ne fait rien) est préparé par
|
||
la commande `-i` de la commande_ `git rebase`.
|
||
|
||
Vous pouvez ensuite modifier ce fichier dans votre éditeur favori (ou pas) (à
|
||
régler par `git config`) pour décrire_ _votre intention (réordonner, changer le
|
||
message, fusionner, ...) sur l'ensemble des commits.
|
||
|
||
Quand votre édition est terminée, git reprend la main est exécute chacune de vos
|
||
opérations. Il est possible (bien que très rare) que des conflits apparaissent
|
||
à ce moment-là. Les commandes habituelles de correction accompagnées des
|
||
commandes :
|
||
|
||
```bash
|
||
git rebase --continue # pour poursuivre le processus
|
||
git rebase --abort # pour tout abandonner
|
||
```
|
||
|
||
*vous permettront de résoudre ces problèmes exceptionnels*.
|
||
|
||
Application:
|
||
|
||
```bash
|
||
git rebase -i $(git merge-base HEAD officiel/master)
|
||
```
|
||
|
||
Vous devez obtenir dans un éditeur de texte la liste des commits opéré depuis le
|
||
début du développement sous cette forme (c'est un exemple : le nombre de lignes
|
||
peut varier) :
|
||
|
||
```bash
|
||
pick eb8cbec modif 1
|
||
pick 83eb79e modif 2
|
||
|
||
# Rebase 5ffd074..83eb79e onto 5ffd074 (2 commands)
|
||
#
|
||
# Commands:
|
||
# p, pick <commit> = use commit
|
||
# r, reword <commit> = use commit, but edit the commit message
|
||
# e, edit <commit> = use commit, but stop for amending
|
||
# s, squash <commit> = use commit, but meld into previous commit
|
||
# f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
|
||
# commit's log message, unless -C is used, in which case
|
||
# keep only this commit's message; -c is same as -C but
|
||
# opens the editor
|
||
# x, exec <command> = run command (the rest of the line) using shell
|
||
# b, break = stop here (continue rebase later with 'git rebase --continue')
|
||
# d, drop <commit> = remove commit
|
||
# l, label <label> = label current HEAD with a name
|
||
# t, reset <label> = reset HEAD to a label
|
||
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
|
||
# . create a merge commit using the original merge commit's
|
||
# . message (or the oneline, if no original merge commit was
|
||
# . specified); use -c <commit> to reword the commit message
|
||
#
|
||
# These lines can be re-ordered; they are executed from top to bottom.
|
||
#
|
||
# If you remove a line here THAT COMMIT WILL BE LOST.
|
||
#
|
||
# However, if you remove everything, the rebase will be aborted.
|
||
#
|
||
```
|
||
|
||
Vous pouvez réorganiser tous les commits (changer l'ordre, fusionner) en
|
||
changeant la commande pick au début de chaque ligne. L'idée ici est de fusionner
|
||
toutes les lignes avec la première en remplaçant le 'pick' à partir de la ligne
|
||
2 par `fixup`. Au besoin, vous pouvez reformuler le message de commit
|
||
(commande `reword` sur la première ligne).
|
||
|
||
Vous construirez par exemple :
|
||
|
||
```bash
|
||
reword eb8cbec Correctif: Api - gestion des formation
|
||
fixup 83eb79e modif 2
|
||
...
|
||
```
|
||
|
||
Quand vous sortez de l'éditeur, git effectue toutes les opérations demandées.
|
||
|
||
À ce niveau-là de la procédure :
|
||
|
||
- vous avez un seul commit pour l'ensemble du correctif proposé ;
|
||
|
||
- toutes les différences entre officiel/master et votre branche locale sont
|
||
signifiantes.
|
||
|
||
#### Étape 4
|
||
|
||
Vous pouvez maintenant pousser votre branche locale sur votre dépôt personnel
|
||
(vers une branche de même nom):
|
||
|
||
```bash
|
||
git push --set-upstream perso ma_branche
|
||
```
|
||
|
||
Si vous avez déjà fait cette opération auparavant il est possible que le push
|
||
soit refusé (car le rebase a modifié des commits qui avaient déjà été poussés).
|
||
Dans ce cas l'option `--force` du push vous permette de passer outre, mais
|
||
assurez-vous avant d'être le seul à travailler sur cette branche.
|
||
|
||
#### Etape 5 : La dernière étape se passe sur le site [scodoc.org/git](https://scodoc.org/git/)
|
||
|
||
- Identifiez-vous
|
||
|
||
- Placez-vous sur la branche nouvellement créée
|
||
|
||
- À l'aide de l'interface du serveur, vous pouvez comparer l'état de votre
|
||
branche par rapport au master officiel, et si cela vous convient, il vous
|
||
reste à formuler une demande d'intégration (*pull request*). En remplissant
|
||
les informations demandées. |