Git Tutorial#

CapyMOA uses git for version control and GitHub for hosting the repository. We follow a forking workflow, which is common for open source projects. It allows anyone to contribute changes while keeping the main repository clean and stable. If you’re familiar with git, you can safely skip this guide, as it is intended for beginners.

Contributing Changes#

1. Get Your Own Copy (Forking)#

Before you can work on CapyMOA, you need your own copy to edit. Go to the project’s repository on GitHub and click the Fork button. This creates a complete copy of the project under your own GitHub account (your “fork”). You can make changes here without affecting the original project.

2. Download Your Copy (Cloning) and Set Up Tracking#

Now you’ll download your new fork to your local computer and tell git about the original project.

# Download your fork to your computer (this is your 'origin').
# Replace $USER with your GitHub username and $FORK_MAME with your fork name 
# (probably 'CapyMOA').
git clone https://github.com/$USER/$FORK_MAME.git
# Or using SSH (preferable if you have SSH keys set up):
# git clone git@github.com:$USER/$FORK_NAME.git

cd CapyMOA

# Add a reference to the original repository (this is the 'upstream')
git remote add upstream https://github.com/adaptive-machine-learning/CapyMOA.git
# Or using SSH:
# git remote add upstream git@github.com:adaptive-machine-learning/CapyMOA.git

3. Create a Branch#

You should make changes for each feature on a dedicated ‘feature’ branch. A feature branch is a set of changes that implements a single feature and can be code reviewed reasonably quickly. The bigger your feature the harder it’ll be to review. So keep them small if at all possible.

# Switch to the 'main' branch. This will act as the parent for our feature.
git switch main

# This step ensures that our local 'main' branch is up-to-date.
# If you skip this step you may end up basing your work on an old version of the code.
# This can create conflicts and issues later on.
git pull upstream main

# Create a new branch called 'my-branch' and switch to it immediately.
# Replace `my-branch` with your feature name.
git switch --create my-branch
# Or the older way:
# git checkout -b my-branch

4. Commit Your Changes#

Once you’ve made edits, you need to tell Git what files you changed and other developers why.

# Stage the changes (prepare them to be committed)
git add my_change_file.py another_file.py

# Review the changes
git status

# Commit and add a message ('-m' to set message inline)
git commit -m "My message"

5. Upload Your Changes to Your Fork#

Your changes are still only on your local computer. Now, you need to push them up to your personal fork on GitHub.

git push origin my-feature

This uploads your my-feature branch to your fork on GitHub, making it visible online.

6. Propose Your Changes (Pull Request)#

Your code is now on your fork. The final step is to ask the original project maintainers to review and merge your work. A Pull Request formally proposes your changes and opens a discussion channel for review.

Go to the original project’s GitHub page. GitHub will usually display a banner prompting you to “Compare & pull request.” Click that to open a Pull Request (PR).

It helps to review the diffs to ensure you committed what you wanted to. A clean PR that makes targeted changes is easier to review and is less likely to break things. If you push changes to your branch they will update on GitHub.

A PR may start some automated checks of your proposed changes. If any checks fail you’ll need to add additional commits to fix that.

Staying Current and Resolving Conflicts (Rebasing)#

Sometimes the original project’s main branch will be updated before your changes are accepted. If those changes conflict with yours, you’ll need to update your branch.

# Fetch and apply the latest changes from upstream main onto your current branch
git pull upstream main --rebase

Rebasing is a clean way to update your branch. It takes all of your commits, temporarily removes them, updates your base branch to the latest upstream main, and then reapplies your commits on top of the new code. This keeps your commit history clean and linear.

You must force push the rebase changes to the remote repository. This is because it must override the history. Force pushing can overwrite remote history and cause data loss, especially if others are working on the same branch. This overwrites history so it’s possible to lose work by doing this incorrectly.

git push --force-with-lease origin my-branch

For example, if someone else has pushed new commits to origin/my-branch after you last pulled, git push --force-with-lease will refuse to overwrite those changes, helping prevent accidental data loss. This is safer than --force, which will overwrite the remote branch regardless of any new commits.

Glossary#

  • Fork: Your own copy of a project on GitHub; changes here don’t affect the original.

  • Repository (Repo): Stores all project files, history, and revisions.

  • Clone: Download a remote repo to your computer for local work.

  • Origin: Remote name for your fork on GitHub; where you push changes.

  • Upstream: Remote name for the original project; used to pull updates.

  • Branch: Separate line of development; changes are isolated until merged.

  • Feature Branch: Temporary branch for a specific feature or fix; deleted after merging.

  • Commit: Snapshot of changes with a message explaining why.

  • Staging: Prepares changes (git add) for the next commit.

  • Push: Upload local commits/branches to a remote repo.

  • Pull Request (PR): Request to merge your changes into the original project.

  • Merge: Integrate changes from one branch into another.

  • Rebase: Replay your commits on top of the latest upstream code for a clean history.

  • Conflict: When the same code is changed differently in two branches; needs manual resolution.

Alternative Guides#

Here are some alternative guides that cover forking workflows in Git: