Un cadavre exquis pour découvrir Git

Ce chapitre propose une mise en application de quelques principes centraux du langage Git vus précédemment.

Exercice
Git
Author

Lino Galiana

Published

2024-04-12

Les exercices suivants sont inspirés d’un cours de Git que j’ai participé à construire à l’Insee et dont les ressources sont disponibles ici. L’idée du cadavre exquis est inspirée de cette ressource et de celle-ci.

Cette partie part du principe que les concepts généraux de Git sont maîtrisés et qu’un environnement de travail fonctionnel avec Git est disponible. Un exemple de tel environnement est le JupyterLab ou l’environnement VSCode du SSPCloud où une extension Git est pré-installée :

Onyxia

Outre le chapitre précédent, il existe de nombreuses ressources sur internet sur le sujet, notamment une série de ressources construites pour l’Insee sur ce site et des ressources de la documentation collaborative sur R qu’est utilitR (des éléments sur la configuration et pratique sur RStudio). Toutes les ressources ne sont donc pas du Python car Git est un outil transversal qui doit servir quel que soit le langage de prédilection.

Git fait parti des pratiques collaboratives devenues standards dans le domaine de l’open-source mais également de plus en plus communes dans les administrations et entreprises de la data science.

Ce chapitre propose, pour simplifier l’apprentissage, d’utiliser l’ extension Git de JupyterLab ou de VSCode. Un tutoriel présentant l’extension JupyterLab est disponible ici. VSCode propose probablement, à l’heure actuelle, l’ensemble le plus complet.

Certains passages de ce TD nécessitent d’utiliser la ligne de commande. Il est tout à fait possible de réaliser ce TD entièrement avec celle-ci. Cependant, pour une personne débutante en Git, l’utilisation d’une interface graphique peut constituer un élément important pour la compréhension et l’adoption de Git. Une fois à l’aise avec Git, on peut tout à fait se passer des interfaces graphiques pour les routines quotidiennes et ne les utiliser que pour certaines opérations où elles s’avèrent fort pratiques (notamment la comparaison de deux fichiers avant de devoir fusionner).

Configuration du compte Github

Rappels sur la notion de dépôt distant

Comme expliqué dans le chapitre précédent, il convient de distinguer le dépôt distant (remote) et la copie ou les copies locales (les clones) d’un dépôt. Le dépôt distant est généralement stocké sur une forge logicielle (Github ou Gitlab) et sert à centraliser la version collective d’un projet. Les copies locales sont des copies de travail.

Git est un système de contrôle de version asynchrone, c’est-à-dire qu’on n’interagit pas en continu avec le dépôt distant (comme c’est le cas dans le système SVN) mais qu’il est possible d’avoir une version locale qui se différencie du dépôt commun et qu’on rend cohérente de temps en temps.

Bien qu’il soit possible d’avoir une utilisation hors-ligne de Git, c’est-à-dire un pur contrôle de version local sans dépôt distant, cela est une utilisation rare et qui comporte un intérêt limité. L’intérêt de Git est d’offrir une manière robuste et efficace d’interagir avec un dépôt distant facilitant ainsi la collaboration en équipe ou en solitaire.

Pour ces exercices, il est proposé d’utiliser Github, la forge la plus visible. L’avantage de Github par rapport à son principal concurrent, Gitlab, est que le premier est plus visible, car mieux indexé par Google et concentre, en partie pour des raisons historiques, plus de développeurs Python et R (ce qui est important dans des domaines comme le code où les externalités de réseau jouent).

Première étape: créer un compte Github

Les deux premières étapes se font sur Github.

Deuxième étape: créer un token (jeton) HTTPS

Principe

Git est un système décentralisé de contrôle de version : les codes sont modifiés par chaque personne sur son poste de travail, puis sont mis en conformité avec la version collective disponible sur le dépôt distant au moment où le contributeur le décide.

Il est donc nécessaire que la forge connaisse l’identité de chacun des contributeurs, afin de déterminer qui est l’auteur d’une modification apportée aux codes stockés dans le dépôt distant. Pour que Github reconnaisse un utilisateur proposant des modifications, il est nécessaire de s’authentifier (un dépôt distant, même public, ne peut pas être modifié par n’importe qui). L’authentification consiste ainsi à fournir un élément que seul vous et la forge êtes censés connaître : un mot de passe, une clé compliquée, un jeton d’accès…

Plus précisément, il existe deux modalités pour faire connaître son identité à Github :

  • une authentification HTTPS (décrite ici) : l’authentification se fait avec un login et un mot de passe ou avec un token (un mot de passe compliqué généré automatiquement par Github et connu exclusivement du détenteur du compte Github) ;
  • une authentification SSH : l’authentification se fait par une clé cryptée disponible sur le poste de travail et que GitHub ou GitLab connaît. Une fois configurée, cette méthode ne nécessite plus de faire connaître son identité : l’empreinte digitale que constitue la clé suffit à reconnaître un utilisateur.

La documentation collaborative utilitR présente les raisons pour lesquelles il convient de favoriser la méthode HTTPS sur la méthode SSH.

Créer un jeton

La documentation officielle comporte un certain nombre de captures d’écran expliquant comment procéder.

Nous allons utiliser le credential helper associé à Git pour stocker ce jeton. Ce credential helper permet de conserver de manière pérenne un jeton (on peut aussi faire en sorte que le mot de passe soit automatiquement supprimé de la mémoire de l’ordinateur au bout, par exemple, d’une heure).

L’inconvénient de cette méthode est que Git écrit en clair le jeton dans un fichier de configuration. C’est pour cette raison qu’on utilise des jetons puisque, si ces derniers sont révélés, on peut toujours les révoquer et éviter les problèmes (pour ne pas stocker en clair un jeton il faudrait utiliser une librairie supplémentaire comme libsecrets qui est au-delà du programme de ce cours).

Si vous désirez conserver de manière plus durable ou plus sécurisée votre jeton (en ne conservant pas le jeton en clair mais de manière hashée), est d’utiliser un gestionnaire de mot de passe comme Keepass (recommandé par l’Anssi). Néanmoins, il est recommandé de tout de même fixer une date d’expéritation aux jetons pour limiter les risques de sécurité d’un token qui fuite sans s’en rendre compte.

Premier commit

A ce stade, nous avons configuré Git pour être en mesure de s’authentifier automatiquement et nous avons cloné le dépôt pour avoir une copie locale de travail.

On n’a encore ajouté aucun fichier à Git en supplément de ceux créés en même temps que le dépôt. Nous allons créer ces premiers fichiers

Il est temps de valider notre modification. Cette opération s’appelle commit en langage Git et, comme son nom l’indique, il s’agit d’une proposition de modification sur laquelle, en quelques sortes, on s’engage.

Un commit comporte un titre et éventuellement une description. A ces informations, Git ajoutera automatiquement quelques éléments supplémentaires, notamment l’auteur du commit (pour identifier la personne ayant proposé cette modification) et l’horodatage (pour identifier le moment où cette modification a été proposée). Ces informations permettront d’identifier de manière unique le commit auquel sera ajouté un identifiant aléatoire unique (un numéro SHA) qui permettra de faire référence à celui-ci sans ambiguïté.

Le titre est important car il s’agit, pour un humain, du point d’entrée dans l’histoire d’un dépôt (voir par exemple l’histoire du dépôt du cours. Les titres vagues (Mise à jour du fichier, Update…) sont à bannir car ils nécessiteront un effort inutile pour comprendre les fichiers modifiés.

N’oubliez pas que votre premier collaborateur est votre moi futur qui, dans quelques semaines, ne se souviendra pas en quoi consistait le commit Update du 12 janvier et en quoi il se distingue du Update du 13 mars.

❓ Question : à ce stade, le dépôt du projet sur GitHub (remote) a-t-il été modifié ?

Le fichier .gitignore

Lorsqu’on utilise Git, il y a des fichiers qu’on ne veut pas partager ou dont on ne veut pas suivre les modifications (typiquement les grosses bases de données).

C’est le fichier .gitignore qui gère les fichiers exclus du contrôle de version. Lors de la création du projet sur GitHub, nous avons demandé la création d’un fichier .gitignore, qui se situe à la racine du projet. Il spécifie l’ensemble des fichiers qui seront toujours exclus de l’indexation faite par Git.

Question : que se passe-t-il lorsque l’on ajoute au .gitignore des fichiers qui ont déjà été commit sur le projet Git ?

Premières interactions avec Github depuis sa copie de travail

Jusqu’à présent, après avoir cloné le dépôt, on a travaillé uniquement sur notre copie locale. On n’a pas cherché à interagir à nouveau avec Github.

Cependant, il existe bien une connexion entre notre dossier local et le dépôt Github. Si on utilise la ligne de commande, on peut s’en assurer en tapant dans un terminal

git remote -v

Le dépôt distant s’appelle remote en langage Git. L’option -v (verbose) permet de lister le(s) dépôt(s) distant(s). Le résultat devrait avoir la structure suivante :

origin  https://github.com/<username>/<projectname>.git (fetch)
origin  https://github.com/<username>/<projectname>.git (push)

Plusieurs informations sont intéressantes dans ce résultat. D’abord on retrouve bien l’url qu’on avait renseigné à Git lors de l’opération de clonage. Ensuite, on remarque un terme origin. C’est un alias pour l’url qui suit. Cela évite d’avoir, à chaque fois, à taper l’ensemble de l’url, ce qui peut être pénible et source d’erreur.

fetch et push sont là pour nous indiquer qu’on récupère (fetch) des modifications d’origin mais qu’on envoie également (push) des modifications vers celui-ci. Généralement, les url de ces deux dépôts sont les mêmes mais cela peut arriver, lorsqu’on contribue à des projets opensource qu’on n’a pas créé, qu’ils diffèrent1.

Envoyer des modifications sur le dépôt distant: push

La fonctionnalité pull

La deuxième manière d’interagir avec le dépôt est de récupérer des résultats disponibles en ligne sur sa copie de travail. On appelle cela pull.

Pour le moment, vous êtes tout seul sur le dépôt. Il n’y a donc pas de partenaire pour modifier un fichier dans le dépôt distant. On va simuler ce cas en utilisant l’interface graphique de Github pour modifier des fichiers. On rapatriera les résultats en local dans un deuxième temps.

L’opération pull permet :

  1. A votre système local de vérifier les modifications sur le dépôt distant que vous n’auriez pas faites (cette opération s’appelle fetch)
  2. De les fusionner s’il n’y a pas de conflit de version ou si les conflits de version sont automatiquement fusionnables (deux modifications d’un fichier mais qui ne portent pas sur le même emplacement).

Même tout seul, ne pas se limiter à main

Au début d’une tâche particulière ou d’un projet, il est recommandé d’ouvrir des issues. Prenant la forme d’un espace de discussion, elles correpondront à la fin à des nouvelles fonctionnalités (en anglais, features). Les issues permettent également de signaler des bugs constatés, de se les répartir et d’indiquer s’ils sont réglés ou s’ils ont avancés. Une utilisation intensive des issues, avec des labels adéquats, peut même amener à se passer d’outils de gestion de projets comme Trello.

La branche main est la branche principale. Elle se doit d’être “propre”. Si on veut être rigoureux, on ne pousse pas des travaux non aboutis sur main.

Il est possible de pousser directement sur main dans le cas de petites corrections, de modifications mineures dont vous êtes certains qu’elles vont fonctionner. Mais sachez que dans le cadre de projets sensibles, c’est strictement interdit. N’ayez pas peur de fixer comme règle l’interdiction de pousser sur main, cela obligera l’équipe projet à travailler professionnellement.

Au moindre doute, créez une branche. Les branches sont utilisées pour des travaux significatifs :

  • vous travaillez seul sur une tâche qui va vous prendre plusieurs heures ou jours de travail (vous ne devez pas pousser sur main des travaux non aboutis);
  • vous travaillez sur une fonctionnalité nouvelle et vous souhaiterez recueillir l’avis de vos collaborateurs avant de modifier main;
  • vous n’êtes pas certain de réussir vos modifications du premier coup et préférez faire des tests en parallèle.

L’option de fusion Squash and Merge permet de regrouper tous les commits d’une branche (potentiellement très nombreux) en un seul dans la branche de destination. Cela évite, sur les gros projets, des branches avec des milliers de commits.

Je recommande de toujours utiliser cette technique et non les autres. Pour désactiver les autres techniques, vous pouvez aller dans Settings et dans la partie Merge button ne conserver cochée que la méthode Allow squash merging

Un cadavre exquis pour découvrir le travail collaboratif

Jusqu’à présent, nous avons découvert les vertus de Git dans un projet individuel. Nous allons maintenant aller plus loin dans un projet collectif.

Le workflow adopté

Nous allons adopter le mode de travail le plus simple, le Github Flow. Il correspond à cette forme caractéristique d’arbre:

  1. La branche main constitue le tronc
  2. Les branches partent de main et divergent
  3. Lorsque les modifications aboutissent, elles sont intégrées à main ; la branche en question disparaît :

Il existe des workflows plus complexes, notamment le Git Flow que j’utilise pour développer ce cours. Ce tutoriel, très bien fait, illustre avec un graphique la complexité accrue de ce flow :

Cette fois, une branche intermédiaire, par exemple une branche development intègre des modifications à tester avant de les intégrer dans la version officielle (main).

Méthode pour les merges

Les merges vers main doivent impérativement passer par Github (ou Gitlab). Cela permet de garder une trace explicite de ceux-ci (par exemple ici), sans avoir à chercher dans l’arborescence, parfois complexe, d’un projet.

La bonne pratique veut qu’on fasse un squash commit pour éviter une inflation du nombre de commits dans main: les branches ont vocation à proposer une multitude de petits commits, les modifications dans main doivent être simples à tracer d’où le fait de modifier des petits bouts de code.

Comme on l’a fait dans un exercice précédent, il est très pratique d’ajouter dans le corps du message close #xxxx est le numéro d’une issue associée à la pull request. Lorsque la pull request sera fusionnée, l’issue sera automatiquement fermée et un lien sera créé entre l’issue et la pull request. Cela vous permettra de comprendre, plusieurs mois ou années plus tard comment et pourquoi telle ou telle fonctionnalité a été implémentée.

En revanche, l’intégration des dernières modifications de main vers une branche se fait en local. Si votre branche est en conflit, le conflit doit être résolu dans la branche et pas dans main. main doit toujours rester propre.

Mise en pratique

Git permet donc de travailler, en même temps, sur le même fichier et de limiter le nombre de gestes manuels nécessaires pour faire la fusion. Lorsqu’on travaille sur des bouts différents du même fichier, on n’a même pas besoin de faire de modification manuelle, la fusion peut être automatique.

Git est un outil très puissant. Mais, il ne remplace pas une bonne organisation du travail. Vous l’avez vu, ce mode de travail uniquement sur main peut être pénible. Les branches prennent tout leur sens dans ce cas.

Informations additionnelles

environment files have been tested on.

Latest built version: 2024-04-12

Python version used:

'3.11.6 | packaged by conda-forge | (main, Oct  3 2023, 10:40:35) [GCC 12.3.0]'
Package Version
affine 2.4.0
aiobotocore 2.12.2
aiohttp 3.9.3
aioitertools 0.11.0
aiosignal 1.3.1
alembic 1.13.1
aniso8601 9.0.1
annotated-types 0.6.0
appdirs 1.4.4
archspec 0.2.3
astroid 3.1.0
asttokens 2.4.1
attrs 23.2.0
bcrypt 4.1.2
beautifulsoup4 4.12.3
black 24.3.0
blinker 1.7.0
blis 0.7.11
bokeh 3.4.0
boltons 23.1.1
boto3 1.34.51
botocore 1.34.51
branca 0.7.1
Brotli 1.1.0
cachetools 5.3.3
cartiflette 0.0.2
Cartopy 0.23.0
catalogue 2.0.10
cattrs 23.2.3
certifi 2024.2.2
cffi 1.16.0
charset-normalizer 3.3.2
chromedriver-autoinstaller 0.6.4
click 8.1.7
click-plugins 1.1.1
cligj 0.7.2
cloudpathlib 0.16.0
cloudpickle 3.0.0
colorama 0.4.6
comm 0.2.2
conda 24.3.0
conda-libmamba-solver 24.1.0
conda-package-handling 2.2.0
conda_package_streaming 0.9.0
confection 0.1.4
contextily 1.6.0
contourpy 1.2.1
cryptography 42.0.5
cycler 0.12.1
cymem 2.0.8
cytoolz 0.12.3
dask 2024.4.1
dask-expr 1.0.10
debugpy 1.8.1
decorator 5.1.1
dill 0.3.8
distributed 2024.4.1
distro 1.9.0
docker 7.0.0
duckdb 0.10.1
en-core-web-sm 3.7.1
entrypoints 0.4
et-xmlfile 1.1.0
exceptiongroup 1.2.0
executing 2.0.1
fastjsonschema 2.19.1
fiona 1.9.6
flake8 7.0.0
Flask 3.0.2
folium 0.16.0
fontawesomefree 6.5.1
fonttools 4.51.0
fr-core-news-sm 3.7.0
frozenlist 1.4.1
fsspec 2023.12.2
GDAL 3.8.4
gensim 4.3.2
geographiclib 2.0
geopandas 0.12.2
geoplot 0.5.1
geopy 2.4.1
gitdb 4.0.11
GitPython 3.1.43
google-auth 2.29.0
graphene 3.3
graphql-core 3.2.3
graphql-relay 3.2.0
graphviz 0.20.3
greenlet 3.0.3
gunicorn 21.2.0
h11 0.14.0
hvac 2.1.0
idna 3.6
imageio 2.34.0
importlib_metadata 7.1.0
importlib_resources 6.4.0
inflate64 1.0.0
ipykernel 6.29.3
ipython 8.22.2
ipywidgets 8.1.2
isort 5.13.2
itsdangerous 2.1.2
jedi 0.19.1
Jinja2 3.1.3
jmespath 1.0.1
joblib 1.3.2
jsonpatch 1.33
jsonpointer 2.4
jsonschema 4.21.1
jsonschema-specifications 2023.12.1
jupyter-cache 1.0.0
jupyter_client 8.6.1
jupyter_core 5.7.2
jupyterlab_widgets 3.0.10
kaleido 0.2.1
kiwisolver 1.4.5
kubernetes 29.0.0
langcodes 3.3.0
lazy_loader 0.4
libmambapy 1.5.7
llvmlite 0.42.0
locket 1.0.0
lxml 5.2.1
lz4 4.3.3
Mako 1.3.2
mamba 1.5.7
mapclassify 2.6.1
Markdown 3.6
MarkupSafe 2.1.5
matplotlib 3.8.3
matplotlib-inline 0.1.6
mccabe 0.7.0
menuinst 2.0.2
mercantile 1.2.1
mizani 0.11.1
mlflow 2.11.3
mlflow-skinny 2.11.3
msgpack 1.0.7
multidict 6.0.5
multivolumefile 0.2.3
munkres 1.1.4
murmurhash 1.0.10
mypy 1.9.0
mypy-extensions 1.0.0
nbclient 0.10.0
nbformat 5.10.4
nest_asyncio 1.6.0
networkx 3.3
nltk 3.8.1
numba 0.59.1
numpy 1.26.4
oauthlib 3.2.2
opencv-python-headless 4.9.0.80
openpyxl 3.1.2
outcome 1.3.0.post0
OWSLib 0.28.1
packaging 23.2
pandas 2.2.1
paramiko 3.4.0
parso 0.8.4
partd 1.4.1
pathspec 0.12.1
patsy 0.5.6
Pebble 5.0.7
pexpect 4.9.0
pickleshare 0.7.5
pillow 10.3.0
pip 24.0
pkgutil_resolve_name 1.3.10
platformdirs 4.2.0
plotly 5.19.0
plotnine 0.13.4
pluggy 1.4.0
polars 0.20.18
preshed 3.0.9
prometheus_client 0.20.0
prometheus-flask-exporter 0.23.0
prompt-toolkit 3.0.42
protobuf 4.25.3
psutil 5.9.8
ptyprocess 0.7.0
pure-eval 0.2.2
py7zr 0.20.8
pyarrow 15.0.0
pyarrow-hotfix 0.6
pyasn1 0.5.1
pyasn1-modules 0.3.0
pybcj 1.0.2
pycodestyle 2.11.1
pycosat 0.6.6
pycparser 2.21
pycryptodomex 3.20.0
pydantic 2.7.0
pydantic_core 2.18.1
pyflakes 3.2.0
Pygments 2.17.2
PyJWT 2.8.0
pylint 3.1.0
PyNaCl 1.5.0
pynsee 0.1.7
pyOpenSSL 24.0.0
pyparsing 3.1.2
pyppmd 1.1.0
pyproj 3.6.1
pyshp 2.3.1
PySocks 1.7.1
python-dateutil 2.9.0
python-dotenv 1.0.1
python-magic 0.4.27
pytz 2024.1
pyu2f 0.1.5
pywaffle 1.1.0
PyYAML 6.0.1
pyzmq 25.1.2
pyzstd 0.15.10
QtPy 2.4.1
querystring-parser 1.2.4
rasterio 1.3.9
referencing 0.34.0
regex 2023.12.25
requests 2.31.0
requests-cache 1.2.0
requests-oauthlib 2.0.0
rpds-py 0.18.0
rsa 4.9
Rtree 1.2.0
ruamel.yaml 0.18.6
ruamel.yaml.clib 0.2.8
s3fs 2023.12.2
s3transfer 0.10.1
scikit-image 0.23.1
scikit-learn 1.4.1.post1
scipy 1.13.0
seaborn 0.13.2
selenium 4.19.0
setuptools 69.2.0
shapely 2.0.3
six 1.16.0
smart-open 6.4.0
smmap 5.0.0
sniffio 1.3.1
snuggs 1.4.7
sortedcontainers 2.4.0
soupsieve 2.5
spacy 3.7.4
spacy-legacy 3.0.12
spacy-loggers 1.0.5
SQLAlchemy 2.0.29
sqlparse 0.4.4
srsly 2.4.8
stack-data 0.6.2
statsmodels 0.14.1
tabulate 0.9.0
tblib 3.0.0
tenacity 8.2.3
texttable 1.7.0
thinc 8.2.3
threadpoolctl 3.4.0
tifffile 2024.2.12
tomli 2.0.1
tomlkit 0.12.4
toolz 0.12.1
topojson 1.8
tornado 6.4
tqdm 4.66.2
traitlets 5.14.2
trio 0.25.0
trio-websocket 0.11.1
truststore 0.8.0
typer 0.9.4
typing_extensions 4.11.0
tzdata 2024.1
Unidecode 1.3.8
url-normalize 1.4.3
urllib3 1.26.18
wasabi 1.1.2
wcwidth 0.2.13
weasel 0.3.4
webdriver-manager 4.0.1
websocket-client 1.7.0
Werkzeug 3.0.2
wheel 0.43.0
widgetsnbextension 4.0.10
wordcloud 1.9.3
wrapt 1.16.0
wsproto 1.2.0
xgboost 2.0.3
xlrd 2.0.1
xyzservices 2024.4.0
yarl 1.9.4
yellowbrick 1.5
zict 3.0.0
zipp 3.17.0
zstandard 0.22.0

View file history

SHA Date Author Description
005d89b 2023-12-20 17:23:04 Lino Galiana Finalise l’affichage des statistiques Git (#478)
4c1c22d 2023-12-10 11:50:56 Lino Galiana Badge en javascript plutôt (#469)
1f23de2 2023-12-01 17:25:36 Lino Galiana Stockage des images sur S3 (#466)
a06a268 2023-11-23 18:23:28 Antoine Palazzolo 2ème relectures chapitres ML (#457)
56d092b 2023-11-14 15:43:00 Antoine Palazzolo update readme (#451)
09654c7 2023-11-14 15:16:44 Antoine Palazzolo Suggestions Git & Visualisation (#449)
b6ae3e3 2023-11-14 05:49:42 linogaliana Corrige balise md
ae5205f 2023-11-13 20:35:43 linogaliana précision
428d669 2023-11-13 20:31:11 linogaliana Exo gitignore
66c6a29 2023-11-13 19:53:49 linogaliana jupyter sspcloud credential helper
69d5bc7 2023-11-13 19:44:01 linogaliana mise à jour de quelques consignes
e3f1ef1 2023-11-13 11:53:50 Thomas Faria Relecture git (#448)
ea9400a 2023-11-05 10:54:04 tomseimandi Include VSCode instructions in exogit (#447)
9366e8d 2023-10-09 12:06:23 Lino Galiana Retrait des box hugo sur l’exo git (#428)
a771183 2023-10-09 11:27:45 Antoine Palazzolo Relecture TD2 par Antoine (#418)
f8831e7 2023-10-09 10:53:34 Lino Galiana Relecture antuki geopandas (#429)
5ab34aa 2023-10-04 14:54:20 Kim A Relecture Kim pandas & git (#416)
154f09e 2023-09-26 14:59:11 Antoine Palazzolo Des typos corrigées par Antoine (#411)
b649205 2023-08-28 15:47:09 linogaliana Nice image
9a4e226 2023-08-28 17:11:52 Lino Galiana Action to check URL still exist (#399)
3bdf3b0 2023-08-25 11:23:02 Lino Galiana Simplification de la structure 🤓 (#393)
30823c4 2023-08-24 14:30:55 Lino Galiana Liens morts navbar (#392)
2dbf853 2023-07-05 11:21:40 Lino Galiana Add nice featured images (#368)
34cc32c 2022-10-14 22:05:47 Lino Galiana Relecture Git (#300)
fd439f0 2022-09-19 09:37:50 avouacr fix ssp cloud links
3056d41 2022-09-02 12:19:55 avouacr fix all SSP Cloud launcher links
f10815b 2022-08-25 16:00:03 Lino Galiana Notebooks should now look more beautiful (#260)
12965ba 2022-05-25 15:53:27 Lino Galiana :launch: Bascule vers quarto (#226)
9c71d6e 2022-03-08 10:34:26 Lino Galiana Plus d’éléments sur S3 (#218)
0e01c33 2021-11-10 12:09:22 Lino Galiana Relecture @antuki API+Webscraping + Git (#178)
9a3f7ad 2021-10-31 18:36:25 Lino Galiana Nettoyage partie API + Git (#170)
2f4d390 2021-09-02 15:12:29 Lino Galiana Utilise un shortcode github (#131)
4cdb759 2021-05-12 10:37:23 Lino Galiana :sparkles: :star2: Nouveau thème hugo :snake: :fire: (#105)
7f9f97b 2021-04-30 21:44:04 Lino Galiana 🐳 + 🐍 New workflow (docker 🐳) and new dataset for modelization (2020 🇺🇸 elections) (#99)
36ed7b1 2020-10-07 12:36:03 Lino Galiana Cadavre exquis (#66)
d1ad64c 2020-10-04 14:43:55 Lino Galiana Finalisation de la première partie de l’exo git (#62)
283e8e9 2020-10-02 18:54:30 Lino Galiana Première partie des exos git (#61)
Back to top

Footnotes

  1. Ce cas de figure arrive lorsqu’on contribue à des projets sur lesquels on n’a pas de droit d’écriture. Il est alors nécessaire d’effectuer un fork, une copie de ce dépôt sur laquelle on dispose de droits. Dans ce cas de figure, on rencontre généralement un nouvel alias à côté d’origin. nommé upstream (cf. le tutoriel Github pour mettre à jour un fork et qui pointe vers le dépôt source à l’origine du fork. La création du bouton Fetch upstream par Github facilite grandement la mise en cohérence d’upstream et origin et constitue la méthode recommandée.↩︎

  2. La commande checkout est un couteau-suisse de la gestion de branche en Git. Elle permet en effet de basculer d’une branche à l’autre, mais aussi d’en créer, etc.↩︎

Citation

BibTeX citation:
@book{galiana2023,
  author = {Galiana, Lino},
  title = {Python Pour La Data Science},
  date = {2023},
  url = {https://pythonds.linogaliana.fr/},
  doi = {10.5281/zenodo.8229676},
  langid = {en}
}
For attribution, please cite this work as:
Galiana, Lino. 2023. Python Pour La Data Science. https://doi.org/10.5281/zenodo.8229676.