Table of Contents

    Git and Version Control for ML Projects

    Machine Learning Project Management

    Git and Version Control for ML Projects

    Learn how to track source-code changes, collaborate safely, manage experiments, protect sensitive information, and create reproducible Machine Learning projects using Git.

    Introduction

    A Machine Learning project changes continuously. Developers update Python scripts, notebooks, feature logic, configuration files, evaluation code, documentation, and deployment components. Without version control, it becomes difficult to identify what changed, understand why a result changed, restore a previous working state, or collaborate safely with other contributors.

    Git is a distributed version control system. It records changes to files as a sequence of commits. Each contributor can maintain a local copy of the repository, create branches, review differences, combine approved changes, and synchronize work with a remote repository.

    Git is highly effective for source code and small text-based files. However, Machine Learning projects may also contain large datasets, trained models, experiment outputs, and generated artifacts. These files usually require additional storage and versioning strategies rather than being committed directly to a normal Git repository.

    Simple definition: Git helps teams record, review, share, and restore changes made to an ML project's source code, configurations, documentation, and other suitable files.

    Learning Objectives

    By the End of This Lesson

    • Explain version control and the purpose of Git
    • Distinguish Git from remote hosting platforms
    • Configure Git and create a repository
    • Understand working-directory, staging, and commit states
    • Create meaningful commits and branches
    • Synchronize work with a remote repository
    • Create an ML-specific .gitignore file
    • Organize a reproducible Machine Learning repository
    • Understand which files should and should not be committed
    • Recognize the roles of Git LFS, DVC, and experiment trackers
    • Protect secrets, credentials, private data, and model artifacts
    • Apply a collaborative Git workflow to an ML project

    Prerequisites

    Recommended Knowledge

    • Basic understanding of files and directories
    • Basic command-line or terminal navigation
    • Basic familiarity with Python project files
    • Awareness of datasets, models, and experiment outputs

    Required Tools

    • Git installed on the local computer
    • A terminal, command prompt, or Git Bash
    • A code editor such as Visual Studio Code
    • A remote Git service account when remote collaboration is required
    • Python and a virtual environment for the example ML project
    Command-highlighting note: The terminal examples use plain code blocks so they work with your existing Highlight.js setup without requiring an additional Bash language script.

    What Is Version Control?

    Version control is a system for recording changes to files over time. It creates a structured history that helps developers inspect previous work, compare revisions, restore earlier versions, and collaborate without replacing one another's changes accidentally.

    Without Version Control

    • Files may be copied with unclear names
    • Changes can be overwritten accidentally
    • Previous working versions may be lost
    • Experiment differences are difficult to trace
    • Team collaboration becomes risky

    With Version Control

    • Changes are recorded as commits
    • Differences can be reviewed
    • Earlier versions can be restored
    • Branches isolate work safely
    • Contributors can collaborate through reviews
    Poor Practice model_final.py, model_final_new.py, model_final_latest.py, model_final_latest_fixed.py
    Better Practice Keep one clearly named source file and use Git commits, branches, tags, and release information to record its history.

    Git vs Remote Git Platforms

    Git and a remote repository platform are related but different. Git is the version control software. A platform such as GitHub, GitLab, Azure Repos, or Bitbucket can host remote Git repositories and provide collaboration features.

    Technology Primary Role Examples of Capabilities
    Git Distributed version control Commits, branches, merging, tags, and local history
    Remote Git Platform Repository hosting and collaboration Pull requests, access control, issue tracking, and automation
    Remember: You can use Git locally without a remote platform. A remote repository becomes important when sharing, backing up, reviewing, or automating project work.

    Important Git Concepts

    Concept Meaning
    Repository A project directory whose selected files and history are managed by Git
    Working Directory The current files available for editing
    Staging Area The selected changes prepared for the next commit
    Commit A recorded snapshot of staged changes with an identifier and message
    Branch An independent line of development
    Merge The operation that combines changes from different branches
    Remote A named connection to another Git repository
    Clone A local copy of an existing repository and its history
    Push Sends local commits to a remote repository
    Fetch Downloads remote history without automatically integrating it
    Pull Fetches remote changes and integrates them into the current branch
    Tag A human-readable reference commonly used to identify an important version
    HEAD A reference to the currently checked-out commit or branch position

    The Basic Git Workflow

    Local Change Workflow
    Modify → Review → Stage → Commit → Push
    1

    Modify Files

    Create or update project files in the working directory.

    2

    Review Changes

    Inspect changed files and exact line-level differences before preparing a commit.

    3

    Stage Selected Changes

    Add only the logically related changes that belong in the next commit.

    4

    Create a Commit

    Record the staged changes with a concise message explaining their purpose.

    5

    Push to the Remote

    Share the local commits through an authorized remote repository.

    Configure Git

    Git associates an author name and email address with commits. Configure the identity required for the repositories you are authorized to use.

    git config --global user.name "Your Name"
    git config --global user.email "you@example.com"
    git config --global init.defaultBranch main

    Review the current Git configuration:

    git config --list
    Identity note: Use the appropriate email address and identity for the repository. Organizational repositories may require a work identity, approved authentication method, or additional contribution policy.

    Create a New ML Repository

    Create a project directory and initialize it as a Git repository.

    mkdir customer-churn-ml
    cd customer-churn-ml
    git init

    Check the repository status:

    git status

    Git creates a hidden .git directory containing the repository metadata and history. Do not manually edit or delete this directory unless you fully understand the consequences.

    Expected Result The directory is now a local Git repository, but no project files have been committed yet.

    Recommended ML Project Structure

    A consistent repository structure helps contributors locate source code, configuration, tests, notebooks, documentation, and generated outputs.

    customer-churn-ml/
    |
    |-- README.md
    |-- .gitignore
    |-- requirements.txt
    |-- pyproject.toml
    |-- configs/
    |   `-- baseline.yaml
    |-- data/
    |   |-- raw/
    |   |-- interim/
    |   `-- processed/
    |-- models/
    |-- notebooks/
    |   `-- 01_exploration.ipynb
    |-- reports/
    |   |-- figures/
    |   `-- metrics/
    |-- src/
    |   |-- __init__.py
    |   |-- data.py
    |   |-- features.py
    |   |-- train.py
    |   `-- evaluate.py
    |-- tests/
    |   |-- test_data.py
    |   `-- test_features.py
    `-- scripts/
        `-- run_training.py
    Path Purpose Typical Git Treatment
    README.md Explains setup, usage, data expectations, and project purpose Track
    configs/ Stores non-secret experiment and model configurations Track
    src/ Contains reusable application and ML source code Track
    tests/ Contains automated tests Track
    notebooks/ Contains exploration and demonstration notebooks Track carefully
    data/ Contains datasets or data references Usually ignore actual data files
    models/ Contains generated model artifacts Usually ignore or use artifact versioning
    reports/ Contains generated metrics, figures, or reports Track selected outputs only

    Create an ML-Specific .gitignore

    A .gitignore file contains patterns for intentionally untracked files that Git should ignore. It is commonly committed so everyone using the repository shares the same ignore rules.

    # Python bytecode and caches
    __pycache__/
    *.py[cod]
    *$py.class
    
    # Virtual environments
    .venv/
    venv/
    env/
    
    # Environment variables and secrets
    .env
    .env.*
    !.env.example
    *.pem
    *.key
    secrets/
    
    # Testing and coverage
    .pytest_cache/
    .coverage
    htmlcov/
    
    # Type checker and linter caches
    .mypy_cache/
    .ruff_cache/
    
    # Jupyter temporary files
    .ipynb_checkpoints/
    
    # IDE and operating-system files
    .vscode/
    .idea/
    .DS_Store
    Thumbs.db
    
    # Logs and temporary files
    *.log
    *.tmp
    *.temp
    tmp/
    cache/
    
    # Build and package outputs
    build/
    dist/
    *.egg-info/
    
    # Local datasets
    data/raw/*
    data/interim/*
    data/processed/*
    
    # Keep documentation files inside data directories
    !data/raw/README.md
    !data/interim/README.md
    !data/processed/README.md
    
    # Generated model artifacts
    models/*
    !models/README.md
    *.pkl
    *.joblib
    *.h5
    *.keras
    *.onnx
    *.pt
    *.pth
    *.ckpt
    
    # Generated experiment outputs
    runs/
    outputs/
    artifacts/
    mlruns/
    
    # Large array and archive files
    *.npy
    *.npz
    *.parquet
    *.zip
    *.tar
    *.gz
    Never Commit Passwords, API keys, access tokens, connection strings, private keys, unrestricted personal data, or confidential datasets.
    Commit Instead Commit a safe template such as .env.example containing variable names and non-secret placeholder values.
    Important: Adding a path to .gitignore does not remove a file that Git already tracks. The tracked file must be removed from the Git index separately, and any exposed secret must be revoked or rotated.

    Create the First Commit

    Create the initial project files, review them, and add selected changes to the staging area.

    git status
    git add README.md .gitignore requirements.txt pyproject.toml
    git status

    Review the staged differences:

    git diff --staged

    Create the first commit:

    git commit -m "Initialize ML project structure"

    Review the commit history:

    git log --oneline --decorate --graph
    A commit should represent one understandable change. Small, focused commits make review, troubleshooting, and rollback easier.

    Write Meaningful Commit Messages

    A useful commit message explains the purpose of a change. It should enable another contributor to understand the project history without opening every modified file.

    Weak Messages

    • update
    • changes
    • fixed stuff
    • final model
    • new code

    Better Messages

    • Add stratified train-test split
    • Prevent leakage in scaling pipeline
    • Add recall metric to churn evaluation
    • Document dataset schema and target definition
    • Add tests for missing-value transformation
    Commit-Message Pattern
    Action + Changed Component + Purpose When Needed

    Work with Branches

    A branch provides an independent line of development. It allows a contributor to work on a feature, experiment, correction, or documentation update without immediately changing the main branch.

    Create and switch to a feature branch:

    git switch -c feature/add-baseline-model

    After making and reviewing the changes:

    git status
    git add src/train.py tests/test_train.py
    git commit -m "Add baseline logistic regression model"

    Switch back to the main branch and merge the feature:

    git switch main
    git merge feature/add-baseline-model

    Delete the local feature branch after the change has been merged and is no longer needed:

    git branch -d feature/add-baseline-model

    Example Branch Names

    • feature/add-data-validation
    • feature/train-random-forest
    • fix/prevent-target-leakage
    • docs/update-training-guide
    • test/add-pipeline-tests
    • refactor/split-feature-module

    Connect to a Remote Repository

    After creating an authorized empty remote repository, connect the local project to it.

    git remote add origin REMOTE_REPOSITORY_URL
    git remote -v
    git push -u origin main

    The -u option establishes an upstream relationship between the local and remote branches. Later pushes can normally use:

    git push

    To copy an existing repository:

    git clone REMOTE_REPOSITORY_URL
    cd REPOSITORY_DIRECTORY
    Security note: Use your organization's approved authentication method. Do not place passwords, access tokens, or private keys directly inside repository URLs, scripts, notebooks, or committed configuration.

    Collaborative Git Workflow

    1

    Update the Local Main Branch

    git switch main
    git pull
    2

    Create a Focused Branch

    git switch -c feature/add-model-evaluation
    3

    Make and Test the Changes

    Update the relevant files and run the required tests, formatting, linting, and evaluation checks.

    4

    Review and Commit

    git status
    git diff
    git add src/evaluate.py tests/test_evaluate.py
    git diff --staged
    git commit -m "Add classification evaluation report"
    5

    Push the Branch

    git push -u origin feature/add-model-evaluation
    6

    Request Review

    Open a pull request or merge request according to the hosting platform and team workflow. Include the purpose, testing evidence, affected components, and any important limitations.

    7

    Merge Approved Changes

    Merge after required reviews and automated checks have passed. Do not bypass repository protections without authorization.

    Resolve Merge Conflicts

    A merge conflict can occur when Git cannot automatically combine competing changes. The developer must inspect the affected file, choose the correct final content, test the result, and complete the merge.

    git status

    After editing and testing the conflicted files:

    git add PATH_TO_RESOLVED_FILE
    git commit

    Conflict-Resolution Practices

    • Read both versions before selecting the final content
    • Understand the intent of each contributor's change
    • Do not remove code simply to eliminate conflict markers
    • Run tests after resolving the conflict
    • Review the final diff before committing
    • Ask the original contributors when the correct result is unclear

    Use Tags for Important Versions

    A tag can mark an important repository state, such as a validated model release, experiment milestone, or deployment version.

    git tag -a model-v1.0.0 -m "Validated baseline model"
    git push origin model-v1.0.0

    List available tags:

    git tag
    ML release note: A Git tag identifies the source-code state. Reproducing an ML release may also require the exact dataset version, configuration, dependency environment, model artifact, and experiment metadata.

    Why Git Alone Is Not Enough for ML

    Traditional software repositories primarily contain source code and small configuration files. Machine Learning projects introduce additional versioned components.

    ML Component Why It Matters Possible Versioning Approach
    Source Code Defines preprocessing, training, evaluation, and inference Git
    Configuration Defines hyperparameters and experiment settings Git
    Dataset Determines the examples from which the model learns Data-versioning or managed storage system
    Model Artifact Contains the trained parameters used for inference Model registry or artifact storage
    Environment Defines libraries and execution dependencies Git-tracked dependency specification and environment image
    Experiment Metadata Connects inputs, parameters, metrics, and outputs Experiment-tracking system
    Documentation Explains purpose, limitations, and usage Git
    Reproducible ML Version
    Code Version + Data Version + Configuration + Environment + Model Artifact → Reproducible Result

    Managing Large Data and Model Files

    Large datasets and model binaries can make a normal Git repository slow and difficult to maintain. They may also contain confidential information that must not be stored in a source-code repository.

    Store in Git

    • Python source files
    • Small configuration files
    • Dependency specifications
    • Tests and documentation
    • Data schemas and validation rules
    • Small safe sample data when permitted

    Usually Store Elsewhere

    • Large raw datasets
    • Confidential or personal data
    • Generated model binaries
    • Large experiment outputs
    • Training checkpoints
    • Temporary caches and logs

    Git Large File Storage

    Git Large File Storage, commonly called Git LFS, replaces selected large files in the repository with lightweight pointer files while storing the actual content in LFS-managed storage.

    git lfs install
    git lfs track "*.onnx"
    git lfs track "*.pt"
    git lfs track "*.joblib"
    git add .gitattributes
    git commit -m "Configure Git LFS for model artifacts"

    Data Version Control

    A data-versioning tool such as DVC can track metadata in Git while keeping large datasets and model artifacts in separate local or remote storage.

    Selection principle: Choose the storage and versioning approach according to file size, data sensitivity, access requirements, organizational policy, collaboration needs, and reproducibility requirements.

    Version ML Experiments

    A commit records file changes, but it does not automatically record every detail of an experiment. A reproducible experiment should connect the source-code version with its data, configuration, environment, metrics, and outputs.

    Experiment Detail Example
    Git Commit Unique source-code revision
    Data Version Dataset snapshot or managed-data identifier
    Features Feature names and transformation version
    Algorithm Random forest, logistic regression, or neural network
    Hyperparameters Learning rate, depth, or number of estimators
    Random Seed Seed used for applicable randomized operations
    Environment Python and library versions
    Metrics Accuracy, recall, F1 score, MAE, or RMSE
    Artifact Trained model or evaluation report
    Recommended Store non-secret experiment configurations as text files, commit them with the relevant source code, and connect the Git commit to the experiment-tracking record.
    Avoid Using filenames such as best_model_final_latest_really_final.pkl as the only model-versioning strategy.

    Version Jupyter Notebooks Carefully

    Jupyter notebooks are useful for exploration and communication, but they can create large and noisy Git differences because they contain code, outputs, execution counts, and metadata in one JSON document.

    Notebook Practices

    • Use notebooks for exploration, explanation, and demonstrations
    • Move stable reusable logic into Python modules
    • Run cells in a clear top-to-bottom order
    • Remove unnecessary output before committing
    • Avoid embedding confidential data in output cells
    • Use descriptive notebook filenames
    • Review notebook differences before committing
    • Consider notebook-diff and output-cleaning tools when appropriate
    Pipeline Risk Keeping all production preprocessing and training logic only inside an exploratory notebook.
    Better Structure Move stable logic into tested Python modules and use the notebook to call those reusable functions.

    Protect Secrets and Sensitive Data

    A Git repository must not be treated as a secret store. Removing a secret in a later commit does not automatically remove it from earlier repository history.

    Security Checklist

    • Never commit passwords, API keys, or access tokens
    • Never commit private keys or certificates containing secrets
    • Keep secret files in .gitignore
    • Use approved environment variables or secret-management systems
    • Commit only safe placeholder templates
    • Review staged changes before every commit
    • Use secret-scanning tools where available
    • Restrict repository access according to least privilege
    • Rotate an exposed credential immediately
    • Follow the required incident-response process
    Unsafe Python
    API_KEY = "real-secret-value"
    DATABASE_PASSWORD = "real-password"
    Safer Python Pattern
    import os
    
    api_key = os.environ["API_KEY"]
    database_password = os.environ["DATABASE_PASSWORD"]
    If a secret is committed: Treat it as exposed. Revoke or rotate it immediately, notify the appropriate owner, and follow the required repository-history and security-response procedure.

    Inspect and Undo Changes Safely

    Inspect Changes

    git status
    git diff
    git diff --staged
    git log --oneline --graph --decorate

    Unstage a File

    git restore --staged PATH_TO_FILE

    Discard an Uncommitted File Change

    git restore PATH_TO_FILE

    Revert a Committed Change

    git revert COMMIT_IDENTIFIER
    Warning Commands that discard local changes or rewrite history can cause data loss. Review the command, repository state, and collaboration impact before running them.
    Safer Shared-History Practice When reversing a commit already shared with others, creating a new reverting commit is often safer than rewriting published history.

    Stash Temporary Work

    Git stash can temporarily store uncommitted tracked-file changes when the developer needs a clean working directory.

    git stash push -m "Temporary feature-engineering work"
    git stash list
    git stash pop
    Important: A stash is temporary local storage, not a replacement for a clear commit, remote backup, experiment tracker, or long-term work record.

    Pull Request Review Checklist

    Code and Repository Review

    • The branch contains one clear and focused change
    • Commit messages describe the intent
    • No secrets or confidential data are included
    • Generated files and large artifacts are excluded appropriately
    • Tests pass and new logic has suitable test coverage
    • Formatting and linting checks pass
    • Documentation and configuration are updated
    • The final diff has been reviewed by the author

    Machine Learning Review

    • The target and prediction point are documented
    • Features use only information available at prediction time
    • Training and evaluation data remain separated
    • Preprocessing is fitted using training data only
    • Random seeds are recorded where appropriate
    • Metrics match the objective and error costs
    • Data and model versions are traceable
    • Known limitations are documented

    Common Git Mistakes in ML Projects

    Mistake Committing a Python virtual environment.
    Better Approach Ignore the environment directory and commit a dependency specification that allows the environment to be recreated.
    Mistake Committing large datasets directly to the source repository.
    Better Approach Use approved data storage and record a safe, traceable data-version reference.
    Mistake Committing passwords or tokens in notebooks and configuration files.
    Better Approach Use an approved secret-management approach and commit only safe configuration templates.
    Mistake Combining unrelated code, data, documentation, and formatting changes in one commit.
    Better Approach Create small commits that each represent one logical change.
    Mistake Committing notebook outputs containing confidential records.
    Better Approach Clear unnecessary output and inspect the notebook diff before committing.
    Mistake Treating a Git commit as a complete ML experiment record.
    Better Approach Connect the commit to the data version, configuration, environment, metrics, and model artifact.

    Essential Git Command Reference

    Command Purpose
    git init Initialize a repository
    git clone Create a local copy of an existing repository
    git status Show the state of working and staged files
    git diff Show unstaged differences
    git add Add selected changes to the staging area
    git commit Record staged changes
    git log Display commit history
    git switch Switch branches or create a branch with the proper option
    git branch List, create, or delete branches
    git merge Combine changes from another branch
    git fetch Download remote references and history
    git pull Fetch and integrate remote changes
    git push Send local commits to a remote repository
    git remote -v List configured remote repositories
    git tag Create or display tags
    git restore Restore working-tree or staged-file state
    git revert Create a commit that reverses an earlier commit
    git stash Temporarily store selected uncommitted changes

    Hands-On Practice

    1

    Create the Repository

    Create a small ML repository containing a README, source directory, tests directory, configuration directory, and .gitignore file.

    2

    Create the First Commit

    Stage only the intended project files, review the staged diff, and create a focused initialization commit.

    3

    Create a Feature Branch

    Create a branch for adding a baseline training script and commit the change with a meaningful message.

    4

    Test the .gitignore

    Create a virtual environment, temporary dataset, and example environment file. Verify that Git does not stage them.

    5

    Merge the Feature

    Return to the main branch and merge the completed feature after reviewing its changes.

    6

    Create a Tag

    Create an annotated tag for the validated baseline source-code version.

    Knowledge Check

    1

    What is the primary purpose of Git?

    Explain how Git records changes and supports collaboration, inspection, and restoration.

    2

    What is a Git commit?

    Explain how a commit records staged changes with an identifier and descriptive message.

    3

    What is the staging area?

    Explain how it allows a developer to choose which changes belong in the next commit.

    4

    Why are branches useful?

    Explain how a branch isolates a feature, experiment, correction, or documentation change.

    5

    What is the purpose of .gitignore?

    Explain how it defines intentionally untracked files that Git should ignore.

    6

    Why should large datasets not normally be committed directly?

    Consider repository performance, storage, privacy, sharing, and access-control requirements.

    7

    Why is a Git commit insufficient for complete ML reproducibility?

    Consider data, model artifacts, configurations, random seeds, dependencies, and experiment metrics.

    8

    What should happen if a secret is committed?

    Explain why the credential should be treated as exposed and immediately revoked or rotated.

    Lesson Summary

    Concept Main Point
    Version Control Records changes to project files over time
    Git A distributed version control system
    Commit A recorded snapshot of staged changes
    Branch An independent line of development
    Remote Repository A shared repository used for synchronization and collaboration
    .gitignore Defines intentionally untracked files that Git should ignore
    Git LFS Manages selected large files through pointer-based storage
    Data Versioning Connects code with traceable dataset versions stored appropriately
    Experiment Tracking Records parameters, metrics, environments, and artifacts
    Reproducibility Requires code, data, configuration, environment, and artifact traceability
    Security Secrets and sensitive data must not be committed
    Collaboration Branches, reviews, tests, and focused commits support reliable teamwork

    Key Takeaway

    Git provides a traceable history of source code, configuration, tests, and documentation. In Machine Learning projects, reliable versioning goes beyond source code. Teams must also connect each experiment and release to the correct data, environment, configuration, metrics, and model artifact while keeping secrets, sensitive data, generated outputs, and unsuitable large files out of the normal Git repository.

    Get Machine Learning updates by email

    Short, practical lessons and course updates from Rumman Ansari. No spam.