Version control for researchers: a practical Git starting guide
You do not need all of Git to do research well. You need a small, steady workflow that records what your code looked like when it produced each result, and keeps data and secrets out.
- Commit what you wrote by hand: code, configuration, environment files and docs. Leave out data, outputs and secrets with a .gitignore from day one.
- A commit message should say why something changed. Tag the commit behind each submitted result.
- Host where collaborators work, then archive a tagged release with a DOI. A hosting platform is not an archive.
Most researchers meet Git at a bad moment. A collaborator sends a link to a repository, a journal asks where the code lives, or a folder full of files called analysis_final_v3_REALLY.R finally becomes impossible to manage. Git then looks like a wall of commands built for professional developers.
It does not have to be. A researcher needs a small part of Git, used consistently. This guide covers that part: what to put under version control, what to leave out, how to write commits you can use later, when branches help, where to host the result, and the mistakes that cause the most trouble.
Why should a researcher use version control at all?
Version control gives you an exact record of what your code looked like when it produced a result. That is the main reason, and it is a scientific one, not a technical one. When a reviewer asks how Figure 3 was made, you can point to a specific commit instead of reconstructing it from memory.
There are practical benefits too:
- Safe experiments. You can try a new approach and return to the working version in seconds.
- One copy of the truth. No more emailing scripts or guessing which folder is current.
- An easy path to sharing. A repository is already in the shape that hosting platforms, archives and journals expect.
- A log of decisions. Good commit messages explain why a parameter changed, which is often the thing nobody remembers six months later.
Git is the de facto standard tool. The official site, git-scm.com, has installers and the free Pro Git book, which is a solid reference once you know the basics.
What is the smallest useful Git workflow?
The smallest useful workflow is four commands: check what changed, stage it, commit it, and push it somewhere safe. Everything else can wait.
git init # once, in the project folder
git status # what has changed?
git add src/clean_data.py # choose what goes into the next commit
git commit -m "Drop sensors with fewer than 30 readings"
git push # send commits to the hosting platform
Run git status often. It tells you which files are modified, which are new and untracked, and which are staged. Most confusion with Git comes from not knowing which of those states a file is in.
Use git log --oneline to see recent history and git diff to see exactly what changed before you commit. Reading your own diff before committing is also the cheapest code review you will ever get.
What should go into the repository?
Commit everything a person would need to rerun your analysis, except the large or sensitive inputs. In practice that means text you wrote by hand.
| Commit it | Usually leave it out |
|---|---|
| Scripts, notebooks and modules | Raw data larger than a few megabytes |
| Configuration files and parameter sets | Generated results, figures and caches |
Environment files (requirements.txt, environment.yml, renv.lock) | Virtual environments and installed packages |
| README, licence, citation file | Passwords, API keys, tokens |
| Small test datasets | Data with personal or confidential information |
| Manuscript source in LaTeX or Markdown | Editor and operating system clutter |
The rule behind the table is simple. If a file can be regenerated by running your code, it does not belong in version control. If it cannot be regenerated and it is small and safe, it probably does.
Data deserves its own home. Large datasets fit better in a data repository or institutional storage, with the README explaining where to get them. A small sample that lets someone check the pipeline runs is worth committing.
How do I keep data and outputs out with .gitignore?
A .gitignore file lists patterns Git should never track. Create it on the first day, before the first git add ., because removing a large file from history later is far harder than never adding it.
# data and outputs
data/raw/
data/processed/
results/
figures/*.png
*.h5
*.parquet
# environments and caches
.venv/
__pycache__/
.ipynb_checkpoints/
.Rproj.user/
.Rhistory
# secrets and local settings
.env
*.key
# operating system clutter
.DS_Store
Thumbs.db
Two details matter. First, .gitignore only affects files that are not yet tracked. If you already committed results/, you need git rm -r --cached results/ to stop tracking it while keeping it on disk. Second, if you want an empty folder to exist in the repository, add a placeholder file such as data/raw/.gitkeep and say in the README what goes there.
A consistent folder layout makes ignore rules short and obvious. We cover one in organising a research project.
What makes a good commit message?
A good commit message says what changed and why, in a line someone can scan. The diff already shows how. The message is for the reason.
Compare these:
- "update" tells you nothing.
- "Fix bug in normalisation" is better, but which bug?
- "Normalise by total counts, not max, to match Methods section" tells a reviewer exactly what happened and links it to the paper.
Some habits that help:
- Keep the first line under about 70 characters and write it as an instruction: "Add", "Fix", "Remove".
- If the reason needs more space, leave a blank line and write a short paragraph.
- Make one logical change per commit. A commit that fixes a bug, renames ten variables and reformats a file is hard to understand and hard to undo.
- Commit when something works, even if it is small. Several small commits a day is normal.
When a result goes into a paper, tag that commit, for example git tag -a v1.0-submission -m "Code as submitted". A tag is a named, fixed point you can cite and archive.
Do I need branches?
For a single researcher, branches are optional. For a group, a light branching habit prevents most collisions. Do not adopt a complex branching model designed for software teams shipping releases.
A workable pattern for research:
- Keep
mainin a state that runs. - Create a short-lived branch for anything that might break things, such as
try-mixed-modelorrefactor-loader. - Merge it back when it works, or delete it if the idea failed. A failed branch is still useful history, so you can keep it if you prefer.
git switch -c try-mixed-model # create and move to a new branch
# ...edit, commit...
git switch main
git merge try-mixed-model
In a group, pair branches with pull requests or merge requests on your hosting platform. That gives every change a place for a colleague to look before it lands, which is a gentle start to code review. Our post on code review in research groups goes further.
Where should I host the repository?
Host where your collaborators already are, then archive a fixed copy for the long term. Hosting and archiving solve different problems.
- GitHub is the largest public platform and the one most readers will know.
- GitLab is available as a hosted service and as software many universities run themselves, which helps when data or code must stay on institutional infrastructure.
- Institutional or national services may exist at your organisation. Ask your research computing or RSE group.
Whichever you choose, a hosting platform is not an archive. Accounts close, projects get renamed and services change their terms. For the version cited in a paper, deposit a release in a service built to last, such as Zenodo, which issues a DOI, or Software Heritage, which preserves public source code. Our guide to archiving code with a DOI walks through the steps.
Private repositories are fine while work is in progress. Plan the moment you will make it public, usually at submission or preprint, and check the history for secrets and sensitive data before you do.
What are the most common mistakes?
Most Git problems in research come from a handful of repeated mistakes. All of them are avoidable.
- Committing data or outputs. The repository grows to gigabytes and becomes slow to clone. Prevent it with
.gitignorefrom day one. - Committing secrets. Deleting a password in a later commit does not remove it from history. If a secret is committed, treat it as leaked and change it.
- Using Git as a backup only. One giant commit a month called "weekly changes" is a backup, not a history. Commit smaller and more often.
- Working outside the repository. Copying scripts to a cluster and editing them there breaks the link between results and code. Clone on the cluster and pull changes instead.
- Not recording which commit produced a result. Write the commit hash into output logs or file metadata. A line like
git rev-parse --short HEADin your script costs nothing. - Fear of breaking things. Almost nothing in Git is truly lost once committed. Committing early is the safe option.
What should I do this week?
Pick one active project and put it under version control properly. Do not try to convert every old folder at once.
- Run
git initin the project folder and add a.gitignorebefore anything else. - Make a first commit of scripts, environment file and a short README.
- Push it to a private repository on the platform your group uses.
- For the next five working days, commit at least once a day with a message that says why.
- When the paper is submitted, tag the commit and archive the release.
If you want guided practice, The Carpentries run workshops and publish an open Git lesson written for researchers. One afternoon with it will cover everything in this guide, with exercises.
Questions
Should I put my data in Git?
Usually not, unless the files are small and safe to share. Large or sensitive data belongs in a data repository or institutional storage, with the README explaining how to get it. A small sample for testing is worth committing.
I committed a password by mistake. Is deleting it enough?
No. The password stays in the repository history. Treat it as leaked: change it straight away, then clean the history if needed. Keep secrets in files listed in .gitignore.
GitHub or GitLab?
Either works. Choose the one your collaborators and institution use. What matters more is archiving the version cited in your paper in a long-term service such as Zenodo or Software Heritage.
Do I need branches if I work alone?
Not necessarily. A single main branch with frequent, clear commits is enough for many solo projects. Short-lived branches help when you try something that might break a working analysis.
Keep reading. More from the desk.
How to organise a research project folder so others can follow it
A research project that only its author can navigate is hard to review, hard to hand over and hard to reproduce. A simple, consistent folder layout fixes most of that, and it takes an afternoon to set up.
Reproducible environments for research code
Sharing your code is step one. Making sure it still runs on someone else's machine, next year, is step two. The tools are mature. The hard part is choosing the right level of effort.
Teaching researchers to code: what works
Most researchers learn to code by copying a colleague's script and hoping. There are better ways. This guide covers the teaching approaches that have proven themselves in research settings and how to start one where you work.