Skip to content

Git Basics

This page covers the essential Git commands you need to start tracking your bioinformatics analysis scripts. You do not need to learn everything at once. These commands will cover 90% of your daily work.

A Git repository is a directory that Git is tracking. You create one by running git init inside your project folder.

Terminal window
mkdir rnaseq-analysis
cd rnaseq-analysis
git init
Initialized empty Git repository in /home/user/rnaseq-analysis/.git/

This creates a hidden .git/ directory that stores the entire history of your project. Run git init once per project. Do not run it inside an existing Git repository.

git status tells you what has changed since the last commit. Run it constantly.

Terminal window
git status
On branch main
No commits yet
nothing to commit (create/copy files and use "git add" to track)

After you create a file:

Terminal window
echo "library(DESeq2)" > deseq2_analysis.R
git status
On branch main
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
deseq2_analysis.R
nothing added to commit but untracked files present (use "git add" to track)

Git sees the new file but is not tracking it yet.

Git manages your files through three states. Understanding these states is the key to understanding Git.

State Location Description
Modified Working directory You changed a file but have not staged it
Staged Staging area You marked a changed file to go into the next commit
Committed Repository The change is safely stored in Git history

The workflow is: edit files, stage the changes you want to keep, then commit them as a snapshot.

git add moves changes from your working directory to the staging area. Think of the staging area as a preparation zone for your next commit.

Terminal window
# Stage one file
git add deseq2_analysis.R
# Stage multiple files
git add deseq2_analysis.R normalize.R
# Stage everything in the current directory
git add .

After staging:

Terminal window
git status
On branch main
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: deseq2_analysis.R

The file is now staged and ready to commit.

git commit takes everything in the staging area and saves it as a permanent snapshot.

Terminal window
git commit -m "Add DESeq2 analysis script"
[main (root-commit) a1b2c3d] Add DESeq2 analysis script
1 file changed, 1 insertion(+)
create mode 100644 deseq2_analysis.R

Every commit gets a unique hash (like a1b2c3d). This hash identifies that exact snapshot forever.

The -m flag lets you write a message describing the change. Always write a message. You will thank yourself later.

git log shows the commit history of your project.

Terminal window
git log
commit a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0
Author: Jane Doe <jane@lab.edu>
Date: Mon Mar 15 10:30:00 2026 +0000
Add DESeq2 analysis script

For a compact view:

Terminal window
git log --oneline
a1b2c3d Add DESeq2 analysis script

This is easier to scan when you have many commits.

git diff shows the exact lines that changed since your last commit.

Terminal window
# See unstaged changes
git diff
# See staged changes (ready to commit)
git diff --staged

Example output after editing a file:

diff --git a/deseq2_analysis.R b/deseq2_analysis.R
index 1234567..abcdefg 100644
--- a/deseq2_analysis.R
+++ b/deseq2_analysis.R
@@ -1 +1,3 @@
library(DESeq2)
+counts <- read.csv("counts.csv", row.names = 1)
+coldata <- read.csv("coldata.csv", row.names = 1)

Lines starting with + were added. Lines starting with - were removed. This is the same format you see on GitHub.

Not everything belongs in version control. Large data files, sensitive information, and generated output should be excluded. Create a .gitignore file to tell Git what to skip.

Terminal window
# .gitignore for a bioinformatics project
# Large sequencing data
*.fastq
*.fastq.gz
*.bam
*.bai
*.cram
# Single-cell data
*.h5ad
*.h5
*.loom
# Output directories
output/
results/
figures/
# R artifacts
.Rhistory
.RData
.Rproj.user/
# Python artifacts
__pycache__/
*.pyc
.venv/
# OS files
.DS_Store
Thumbs.db
# Sensitive data
*.csv
!metadata.csv

Add and commit the .gitignore file itself:

Terminal window
git add .gitignore
git commit -m "Add gitignore for bioinformatics project"

A good commit message tells you what changed and why. Start with a verb. Be specific.

Good messages:

Add DESeq2 differential expression script
Fix off-by-one error in read counting
Update STAR alignment parameters for paired-end data
Remove deprecated normalization step

Bad messages:

updates
fix
stuff
final version

A useful rule: if you read the message six months from now, will you understand what the commit did?

Commit whenever you reach a working state. Here are good moments to commit:

  • You finished writing a new analysis step
  • You fixed a bug in your script
  • You updated parameters after testing
  • You added a new input file or configuration

Do not wait until the end of the day to commit everything at once. Small, frequent commits are easier to understand and easier to undo if something goes wrong.

Here is a complete workflow for a typical analysis session:

Terminal window
# 1. Check your current state
git status
# 2. Work on your analysis (edit files, run scripts)
# 3. Review what you changed
git diff
# 4. Stage the files you want to commit
git add deseq2_analysis.R normalize.R
# 5. Double-check what is staged
git status
# 6. Commit with a descriptive message
git commit -m "Add normalization step before DE analysis"
# 7. Verify the commit
git log --oneline

Repeat this cycle throughout your workday. It becomes second nature quickly.

Everyone makes mistakes. Git provides several ways to recover.

Unstage a file (remove from staging area, keep your edits):

Terminal window
git restore --staged deseq2_analysis.R

Discard changes to a file (revert to last commit):

Terminal window
git restore deseq2_analysis.R

See a previous version of a file:

Terminal window
git show HEAD~1:deseq2_analysis.R

This shows the file as it was one commit ago. HEAD~2 goes two commits back.

  • git init creates a new repository. Run it once per project.
  • git status shows what changed. Run it often.
  • git add stages changes for the next commit.
  • git commit -m "message" saves a snapshot with a description.
  • git log shows commit history. Use --oneline for a compact view.
  • git diff shows exactly what lines changed.
  • .gitignore excludes large data files, generated output, and sensitive information.
  • Commit often in small, logical chunks. Write messages that your future self will understand.