Git workflows and best practices for the Research Project Template
Quick Reference: Contributing | Workflow | Best Practices
This guide provides best practices for using Git version control with the Research Project Template, including workflows, branching strategies, commit guidelines, and collaboration patterns.
Effective version control is essential for maintaining code quality, enabling collaboration, and tracking project evolution. This guide covers Git best practices specifically tailored for research projects using this template.
Recommended workflow:
# 1. Update local main
git checkout main
git pull origin main
# 2. Create feature branch
git checkout -b feature/new-feature
# 3. Make changes
# ... edit files ...
# 4. Stage changes
git add .
# 5. Commit with clear message
git commit -m "feat: add feature"
# 6. Push branch
git push origin feature/new-feature
# 7. Create pull request
# ... via GitHub UI ...Follow these principles:
- Always work on feature branches
- Keep main branch stable
- Commit frequently with clear messages
- Review before merging
- Test before pushing
Recommended branching:
main (production-ready)
├── develop (integration)
│ ├── feature/new-feature
│ ├── feature/another-feature
│ └── fix/bug-description
Branch naming conventions:
feature/- featuresfix/- Bug fixesdocs/- Documentation updatesrefactor/- Code refactoringtest/- Test improvementschore/- Maintenance tasks
Creating branches:
# Feature branch
git checkout -b feature/add-statistics-module
# Bug fix branch
git checkout -b fix/pdf-generation-error
# Documentation branch
git checkout -b docs/update-api-referenceUpdating branches:
# Update from main
git checkout feature/my-feature
git merge main
# Or rebase
git rebase mainCleaning up:
# Delete local branch after merge
git branch -d feature/merged-feature
# Delete remote branch
git push origin --delete feature/merged-featureFollow conventional commit format:
<type>(<scope>): <subject>
<body>
<footer>
Types:
feat- featurefix- Bug fixdocs- Documentationstyle- Formattingrefactor- Code restructuringtest- Testschore- Maintenance
Examples:
# Feature
git commit -m "feat(quality): add readability analysis"
# Bug fix
git commit -m "fix(build): resolve PDF generation error"
# Documentation
git commit -m "docs(api): update function documentation"
# Test
git commit -m "test(example): add edge case tests"Write good commit messages:
- Use present tense: "add feature" not "added feature"
- Be specific and clear
- Keep subject line under 50 characters
- Include body for complex changes
- Reference issues when applicable
Good examples:
feat(scripts): add parallel PDF generation
Implements parallel building of individual PDFs using
xargs and background processes. Reduces build time
from 35s to 20s for PDF generation stage.
Closes #123Bad examples:
# Too vague
git commit -m "fix stuff"
# Too long subject
git commit -m "fix: resolve issue with PDF generation when using special characters in markdown that causes pandoc to fail"
# Missing context
git commit -m "update"Version format: MAJOR.MINOR.PATCH
- MAJOR - Breaking changes
- MINOR - features (backward compatible)
- PATCH - Bug fixes
Examples:
0.1.0- Initial release0.2.0- features0.2.1- Bug fixes1.0.0- Stable release
Tag releases:
# Annotated tag (recommended)
git tag -a v0.2.0 -m "Release version 0.2.0"
# Lightweight tag
git tag v0.2.0
# Push tags
git push origin v0.2.0
# Push all tags
git push origin --tagsTag best practices:
- Use annotated tags for releases
- Include release notes in tag message
- Tag after successful build
- Tag stable versions only
Release workflow:
# 1. Update version
# Edit pyproject.toml (CHANGELOG.md to be created)
# 2. Commit changes
git commit -m "chore: bump version to 0.2.0"
# 3. Create tag
git tag -a v0.2.0 -m "Release 0.2.0"
# 4. Push everything
git push origin main
git push origin v0.2.0
# 5. Create GitHub release
# ... via GitHub UI ...Best practices:
- Update frequently from main
- Keep branches short-lived
- Communicate with team
- Review changes before merging
When conflicts occur:
# 1. Update local branch
git checkout feature/my-feature
git merge main
# 2. Resolve conflicts
# Edit conflicted files
# Remove conflict markers
# 3. Stage resolved files
git add resolved-file.py
# 4. merge
git commit -m "merge: resolve conflicts with main"Conflict markers:
<<<<<<< HEAD
# Your changes
=======
# Incoming changes
>>>>>>> mainResolution:
# Keep both, one, or create new solution
# Final codeConfigure merge tool:
# Set merge tool
git config --global merge.tool vimdiff
# Use merge tool
git mergetoolCreating pull requests:
- Push branch -
git push origin feature/my-feature - Create PR - Via GitHub UI
- Review - Address feedback
- Merge - After approval
PR best practices:
- Clear title and description
- Reference related issues
- Include test results
- Request specific reviewers
Review checklist:
- Code follows style guidelines
- Tests pass with required coverage (90% project, 60% infra)
- Documentation updated
- No breaking changes
- Follows thin orchestrator pattern
Review comments:
- Be constructive and specific
- Suggest improvements
- Explain reasoning
- Acknowledge good work
Working with others:
- Communicate changes
- Update frequently
- Review thoroughly
- Test before requesting review
- Respond to feedback promptly
Clean up commit history:
# Rebase last 3 commits
git rebase -i HEAD~3
# Actions:
# pick - Use commit
# reword - Change message
# edit - Modify commit
# squash - Combine with previous
# drop - Remove commitUse cases:
- Clean up commit history
- Combine related commits
- Fix commit messages
- Remove accidental commits
Save work in progress:
# Stash changes
git stash
# Stash with message
git stash save "WIP: working on feature"
# List stashes
git stash list
# Apply stash
git stash apply
# Apply and remove
git stash pop
# Drop stash
git stash dropApply specific commits:
# Apply commit from another branch
git cherry-pick <commit-hash>
# Apply multiple commits
git cherry-pick <hash1> <hash2>
# Apply range
git cherry-pick <hash1>..<hash2>Configure Git:
# User information
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"
# Editor
git config --global core.editor "vim"
# Default branch name
git config --global init.defaultBranch main
# Push behavior
git config --global push.default simple
# Rebase on pull
git config --global pull.rebase trueCreate aliases:
# Short status
git config --global alias.st status
# Last commit
git config --global alias.last "log -1 HEAD"
# Unstage
git config --global alias.unstage "reset HEAD --"
# View graph
git config --global alias.graph "log --oneline --graph --all"Template .gitignore:
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
.venv/
venv/
ENV/
# Output (disposable)
output/
*.pdf
*.tex
*.html
# IDE
.vscode/
.idea/
*.swp
*.swo
# OS
.DS_Store
Thumbs.db
# Testing
.pytest_cache/
.coverage
htmlcov/
# Build
*.egg-info/
dist/
build/Best practices:
- Ignore generated files
- Ignore IDE files
- Ignore OS files
- Commit .gitignore early
Solution:
# Remove from history
git filter-branch --force --index-filter \
"git rm --cached --ignore-unmatch sensitive-file" \
--prune-empty --tag-name-filter cat -- --all
# Force push (coordinate with team)
git push origin --force --allSolution:
# Find lost commits
git reflog
# Recover commit
git checkout <commit-hash>
git checkout -b recovered-branchSolution:
# Move commits to correct branch
git stash
git checkout correct-branch
git stash pop
git commitVersion control best practices:
- Workflow - Use feature branches
- Commits - Clear, conventional messages
- Branches - Descriptive names, short-lived
- Tags - Semantic versioning for releases
- Collaboration - Clear PR process, thorough reviews
- Configuration - Proper Git setup
- Ignoring - .gitignore
See Also:
- Contributing Guide - Contribution workflow
- Workflow - Development process
- Best Practices - Code quality practices