5. Publish the Sales Project with Git

Duration1h AI Banned

Introduction

Your Sales project now contains a meaningful and reproducible first result: uv can recreate its Python environment, VS Code can run its notebook, and the notebook can load the dataset. You will use Git to record this state and GitLab to publish it before continuing the analysis. Git is introduced here because the project now contains work worth preserving and sharing.

Configure your Git identity

Run these commands in the VS Code terminal. Windows users must remain inside WSL.

1
2
git config --global user.name "Your Full Name"
git config --global user.email "your.email@imt-atlantique.net"

Verify the configuration:

1
2
git config --get user.name
git config --get user.email

These values identify the author of future commits. Use an email address associated with your GitLab account when possible.

Configure SSH access to GitLab

Before creating a key, answer this question: do you already use an SSH key to access GitLab, and do you still have the corresponding private-key file? If you are unsure, follow Path B and create a dedicated key for this environment.

GitLab stores only your public key. An existing key can be reused only if you still have both files: the private key, such as id_ed25519, and its public counterpart, such as id_ed25519.pub.

Path A — Import an existing GitLab key

Follow this path if you still have the private key and its matching .pub file. Copy both files into ~/.ssh. The following commands use the default Ed25519 filenames; replace /path/to/key with the directory that currently contains your key:

1
2
3
4
5
6
mkdir -p ~/.ssh
cp -i /path/to/key/id_ed25519 ~/.ssh/
cp -i /path/to/key/id_ed25519.pub ~/.ssh/
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub

The -i option means interactive: cp asks for confirmation before overwriting a file that already exists in ~/.ssh. This prevents you from accidentally replacing another key.

Adapt the filenames if your key has a different name. Then start the SSH agent and import the private key:

1
2
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
Transfer private keys carefully

Never send a private key by email, instant message, or Git. If the key is stored on another computer and you cannot transfer it securely, follow Path B and create a dedicated key instead.

Path B — Create a key for this environment

Follow this path if you have no existing key, or if GitLab contains an old public key but you no longer have its private-key file. Create a new key:

1
ssh-keygen -t ed25519 -C "your.email@imt-atlantique.net"

Accept the proposed location. Then start the SSH agent and add the new private key:

1
2
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519

Display the public key:

1
cat ~/.ssh/id_ed25519.pub

Copy the complete output, open your GitLab account, navigate to Preferences → SSH Keys, and add the key.

Test your GitLab connection

Whichever path you followed, test the connection from WSL:

1
ssh -T git@gitlab.imt-atlantique.fr

Accept the host fingerprint if prompted. A successful response identifies your GitLab account.

Never share a private key

Only copy the file ending in .pub. Never display, send, or commit the corresponding file without .pub, which is your private key.

Decide what Git should track

Create .gitignore at the project root and add:

# Local Python environment
.venv/

# Python-generated files
__pycache__/
*.pyc
*.pyo
*.pyd

# Jupyter-generated files
.ipynb_checkpoints/

# Operating-system files
.DS_Store
Thumbs.db

The * character matches any filename prefix. The three Python rules therefore ignore files ending in .pyc, .pyo, or .pyd, which are compiled or generated Python files. They are sometimes written in the compact form *.py[cod]: [cod] means exactly one character chosen from c, o, or d.

Data and version control

As a general rule, do not commit datasets to Git. Data may be too large, confidential, frequently updated, or distributed under a licence that prevents redistribution. Store such data separately and document how to obtain it.

The Sales dataset is a reasonable exception: it is small, public, stable, and used in a tutorial repository. You may therefore decide whether to include it. Record your decision in README.md and follow one of the two options below.

Option A — Track the demonstration dataset

Keep the current .gitignore unchanged. Git will include data/sales.csv, making this small tutorial immediately reproducible after cloning.

Option B — Keep the dataset outside Git

Add this rule to .gitignore:

# Local datasets
data/*.csv

Create data/README.md and indicate where to download the Sales dataset and that it must be saved as data/sales.csv. Git will track these instructions without tracking the CSV file itself.

Temporary student GitLab

The repositories hosted on gitlab-df.imt-atlantique.fr are purged at the end of the academic year. Whether or not you commit the demonstration dataset, this GitLab instance must not be treated as long-term data storage or as an archive.

Create the first commit

Introduce Conventional Commits

A commit message describes the purpose of a recorded change. If every contributor writes messages differently, the project history quickly becomes difficult to scan and understand. Conventional Commits is a lightweight convention that gives these messages a shared structure. It is not a separate Git command: it is a rule for writing the message passed to git commit.

Using this convention makes the purpose of each change immediately visible, helps contributors find relevant changes in the history, and can later support automated release notes and other project tools. In this course, the main objective is to produce a clear history that another student can understand.

A Conventional Commit starts with a type that describes the purpose of the change, may include a scope that identifies the affected part of the project, and ends with a short description:

1
<type>[optional scope]: <short description>

For example:

1
feat(analysis): compare hourly sales

Here, feat indicates a new project capability, analysis identifies the affected area, and the final words summarize the change. Use lowercase for the type and write a concise description of the completed change. The most useful types for this project are:

  • chore: set up or maintain the project without adding an analytical result;
  • feat: add a new data-processing step, analysis, visualization, or result;
  • fix: correct an error in the project or analysis;
  • docs: change documentation only.

The scope is optional. The full specification also defines commit bodies, footers, and breaking changes; you do not need them yet. Refer to the Conventional Commits 1.0.0 documentation when you need the complete rules and additional examples.

From the sales-analysis project root, initialize Git and inspect the files:

1
2
git init -b main
git status

The -b main option tells git init to name the first branch main. It is the short form of --initial-branch=main.

Confirm that .venv/ and notebook checkpoints are not listed. Then create the first commit:

1
2
3
4
git add .
git status
git commit -m "chore: initialize reproducible sales project"
git log --oneline
Checkpoint 1

git log --oneline displays the initial commit, git status reports a clean working tree, and .venv is not part of the commit. Your choice concerning data/sales.csv is documented in README.md.

Create the GitLab project

On the course GitLab instance:

  1. Select New project → Create blank project.
  2. Use sales-analysis as the project name and slug.
  3. Choose the visibility requested by your instructor.
  4. Do not initialize the GitLab project with a README or other files.

GitLab displays commands for connecting an existing local repository. The SSH remote should look like:

1
2
git remote add origin git@gitlab.imt-atlantique.fr:YOUR_USERNAME/sales-analysis.git
git push -u origin main

Replace YOUR_USERNAME with your GitLab namespace and verify the connection:

1
git remote -v

Open the GitLab project in your browser and confirm that it contains README.md, data/, notebooks/, pyproject.toml, .python-version, and uv.lock, but not .venv/.

Checkpoint 2

The first version of the Sales project is visible on GitLab and contains everything required to recreate the environment and open the notebook.

Use Git during the analysis

Git commits should describe logical progress rather than every saved cell. During the next activity, create a commit after each major stage, for example:

1
2
3
4
feat(data): clean sales transaction data
feat(features): add temporal and geographic variables
feat(analysis): analyze monthly and hourly sales patterns
docs: document main sales findings

Use the same short cycle each time:

1
2
3
4
git status
git add <files>
git commit -m "type(scope): describe the completed analysis step"
git push
Apply the convention

Choose the type according to the purpose of the change, not according to the file extension. Keep one logical change per commit whenever possible.

Activity complete

Your project is now protected by local version history and published on GitLab. Continue to use small, meaningful commits as the notebook and README evolve.