Branching and Collaboration
Last updated on 2026-08-24 | Edit this page
Estimated time: 40 minutes
Overview
Questions
- How do I use branches for parallel experiments?
- How do I tag versions for publications?
- How do I collaborate with others using Git?
- When should I NOT use Git?
Objectives
- Use branches to explore different analysis approaches
- Tag specific commits as publication versions
- Collaborate using shared repositories and pull requests
- Recognize when to not use Git (large data files, sensitive data)
Using Branches for Experiments
Branches are where Git becomes powerful for research.
Scenario: Trying New Analysis Approaches
You have a working analysis on main. You want to try a
different statistical test without breaking the working code:
Naming Branches
Use a convention:
main # Production / paper version
develop # Working version
feature/add-confidence-intervals
experiment/logistic-regression
bugfix/date-parsing-error
The Flow
BASH
# Start with main (stable)
git checkout main
# Create feature branch for new work
git checkout -b feature/confidence-intervals
# Make changes, test, commit
echo "confidence interval code" >> src/analyze.py
git add src/analyze.py
git commit -m "Add confidence interval calculation
Using scipy.stats.t.ppf for parametric intervals and
scipy.stats.bootstrap for non-parametric bootstrapped CIs."
# When satisfied, merge to main
git checkout main
git merge feature/confidence-intervals
git branch -d feature/confidence-intervals
Comparing Approaches
Branches let you compare analysis approaches:
BASH
# Compare two methods
git log main...feature/logistic-regression --oneline
# See what figures changed
git diff main feature/logistic-regression -- results/
# See what the code difference is
git diff main feature/logistic-regression -- src/analyze.py
This is documentation of your scientific decision-making process.
Tagging: Versions for Publications
Tag specific commits as versions:
BASH
# Tag the version submitted to journal
git tag v1.0-submitted
# Tag revisions
git tag v1.1-revision-1
# Create an annotated release
git tag -a v2.0-published -m "Final published version"
Later, you can easily return to the published version:
Or compare:
Collaborating with Git
Shared Repository Workflow
Your lab shares a private GitHub repository:
BASH
# Clone the repository
git clone git@github.com:mylab/project.git
cd project
# Create a feature branch
git checkout -b feature/new-analysis
# Make changes, commits
git add src/
git commit -m "Add new statistical test"
# Push to GitHub
git push origin feature/new-analysis
# Open a Pull Request on GitHub
# Lab members review, discuss, approve
# Merge to main when ready
When NOT to Use Git
Large Data Files
Git stores the entire history of every file. If you commit a 100 MB data file, then delete it, Git still stores it. Your repository becomes bloated.
Solution: Don’t track raw data. Document how to obtain it.
Binary Data
If you have large neuroimaging files (.nii), genomic data (.bam, .vcf), or simulation output (.pkl, .h5), Git diffs are meaningless for these. Document in README how to regenerate or where to find them.
Best Practices: Research Git Workflow
-
Initialize early: Start a project with
git initon day one - Commit often: Don’t wait for “finished” work. Commit incremental progress
- Meaningful messages: Document why you made changes
- Use branches: Experiment without breaking the main analysis
- Tag releases: Mark versions submitted to journals, published versions, etc.
-
Ignore appropriately: Use
.gitignorefor raw data and large intermediate files - Protect main: Use GitHub rules to prevent accidental commits to main
- Document decisions: In commit messages and in ANALYSIS_PLAN.md or README
Step 1: Create Two Feature Branches
BASH
# From main, create an analysis branch
git checkout -b feature/add-analysis
cat > src/analyze.py << 'EOF'
"""Example analysis script."""
print("Running analysis...")
EOF
git add src/analyze.py
git commit -m "Add initial analysis script"
# Go back to main, create a test branch
git checkout main
git checkout -b feature/add-tests
cat > src/test_analyze.py << 'EOF'
"""Tests for analysis."""
def test_imports():
import src.analyze
print("Import successful!")
EOF
git add src/test_analyze.py
git commit -m "Add test suite"
BASH
$ git log --graph --all --decorate --oneline
* h8i9j0k (HEAD -> feature/add-tests) Add test suite
| * d4e5f6g (feature/add-analysis) Add initial analysis script
|/
* a1b2c3d (main) Initialize project structure
$ git checkout main
$ git merge feature/add-analysis
Updating a1b2c3d..d4e5f6g
Fast-forward
src/analyze.py | 2 ++
1 file changed, 2 insertions(+)
$ git log --oneline
d4e5f6g (HEAD -> main) Add initial analysis script
a1b2c3d Initialize project structure
The graph view shows how each branch diverged from main
independently. The merge brought the analysis branch back into main via
fast-forward, while the tests branch remains separate.
- Branches let you explore different analysis approaches without breaking working code
- Tag versions for submissions, revisions, and publications
- Collaborate using shared repositories, feature branches, and pull requests
- Git history demonstrates reproducibility: others can see exactly what changed and when
- Don’t track large data, binary files, or sensitive information in Git