Create delightful software with Jupyter Notebooks
—
Handle git merge conflicts and notebook-specific version control concerns. nbdev provides specialized tools for managing notebooks in git repositories, resolving merge conflicts, and maintaining clean version control history.
Resolve git merge conflicts in notebook files automatically.
def nbdev_merge():
"""
Merge notebooks with conflict resolution.
Automatically resolves common notebook merge conflicts by:
- Combining cell outputs intelligently
- Resolving execution count conflicts
- Merging metadata changes
- Preserving both sets of changes where possible
"""
def nbdev_fix():
"""
Fix notebook merge conflicts.
Repairs notebook files that have git merge conflict markers,
attempting to create valid notebook JSON while preserving
both versions of conflicting content.
"""Usage Examples:
from nbdev.merge import nbdev_merge, nbdev_fix
# After git merge with conflicts
nbdev_merge() # Attempt automatic resolution
# If manual intervention needed
nbdev_fix() # Fix remaining conflictsHandle code patches and modifications in version control.
def unpatch():
"""
Remove patches from code.
Removes temporary patches or modifications that were applied
for testing or development but shouldn't be permanent.
"""Utilities for handling configuration and merge patterns.
def conf_re():
"""
Configuration regex patterns.
Returns:
Regex patterns for identifying configuration sections
and merge conflict markers in notebook files.
"""nbdev enhances standard git operations for notebooks:
# Before committing
nbdev_clean # Clean notebooks
git add .
git commit -m "Update notebooks"
# After pulling changes
git pull
nbdev_merge # Resolve any notebook conflicts
nbdev_update # Sync notebooks with code changesnbdev_merge() attempts to resolve conflictsnbdev_fix() for stubborn conflictsnbdev_test() to verify functionalityfrom nbdev.merge import nbdev_merge, nbdev_fix
from nbdev.test import nbdev_test
from nbdev.clean import nbdev_clean
def resolve_notebook_conflicts():
"""Complete workflow for resolving notebook merge conflicts."""
print("Attempting automatic merge resolution...")
nbdev_merge()
print("Fixing remaining conflicts...")
nbdev_fix()
print("Cleaning resolved notebooks...")
nbdev_clean()
print("Testing resolved notebooks...")
success = nbdev_test()
if success:
print("✓ Merge conflicts resolved successfully")
else:
print("⚠ Manual review needed - some tests failed")
return success
# Use after git merge conflicts
resolve_notebook_conflicts()Execution Count Conflicts:
<<<<<<< HEAD
"execution_count": 15,
=======
"execution_count": 23,
>>>>>>> branchResolution: Remove execution counts (they're not meaningful)
Cell Output Conflicts:
<<<<<<< HEAD
"outputs": [{"text": "Result A"}],
=======
"outputs": [{"text": "Result B"}],
>>>>>>> branchResolution: Keep both outputs or choose based on context
Metadata Conflicts:
<<<<<<< HEAD
"metadata": {"tags": ["important"]},
=======
"metadata": {"tags": ["test"]},
>>>>>>> branchResolution: Merge metadata or choose appropriate version
nbdev uses intelligent strategies for different conflict types:
Automatically clean notebooks before commits:
# Installed via nbdev_install_hooks()
# Pre-commit hook runs:
nbdev_clean --clear_allAutomatically handle notebook updates after merges:
# Post-merge hook runs:
nbdev_merge
nbdev_updatefrom nbdev.merge import nbdev_merge
from nbdev.export import nb_export
def safe_branch_switch(branch_name):
"""Safely switch branches with notebook handling."""
# Clean current state
nb_export() # Export current work
# Switch branches
import subprocess
subprocess.run(['git', 'checkout', branch_name])
# Handle any conflicts
nbdev_merge()
print(f"Switched to {branch_name} with notebooks updated")
safe_branch_switch('feature-branch')from nbdev.merge import nbdev_fix
from nbdev.clean import nbdev_clean
def maintain_notebook_repo():
"""Maintain notebook repository health."""
# Fix any lingering issues
nbdev_fix()
# Clean all notebooks
nbdev_clean(clear_all=True)
# Verify repository state
import subprocess
result = subprocess.run(['git', 'status', '--porcelain'],
capture_output=True, text=True)
if result.stdout.strip():
print("Repository has changes after maintenance:")
print(result.stdout)
else:
print("✓ Repository clean after maintenance")
maintain_notebook_repo()# Before creating PR
from nbdev.clean import nbdev_clean
from nbdev.export import nb_export
from nbdev.test import nbdev_test
def prepare_pr():
"""Prepare notebooks for pull request."""
# Clean notebooks
nbdev_clean()
# Export to ensure code is up to date
nb_export()
# Run tests
if nbdev_test():
print("✓ Ready for pull request")
return True
else:
print("✗ Tests failed - fix before PR")
return False
prepare_pr()from nbdev.merge import nbdev_merge
from nbdev.sync import nbdev_update
def sync_with_team():
"""Sync notebooks with team changes."""
# Pull latest changes
import subprocess
subprocess.run(['git', 'pull'])
# Resolve any notebook conflicts
nbdev_merge()
# Update notebooks with code changes
nbdev_update()
print("✓ Synced with team changes")
sync_with_team()nbdev_clean()nbdev_test() after conflict resolution# Recommended team workflow
def team_workflow():
"""Recommended workflow for team collaboration."""
# Before starting work
subprocess.run(['git', 'pull'])
nbdev_merge() # Handle any conflicts
nbdev_update() # Update notebooks
# After making changes
nbdev_clean() # Clean notebooks
nb_export() # Export code
nbdev_test() # Test changes
# Before committing
subprocess.run(['git', 'add', '.'])
subprocess.run(['git', 'commit', '-m', 'Update notebooks'])
subprocess.run(['git', 'push'])# Initial repository setup
nbdev_install_hooks # Install git hooks
git config merge.ours.driver true # For binary filesComplete Git Integration Example:
from nbdev.merge import nbdev_merge, nbdev_fix
from nbdev.clean import nbdev_clean
from nbdev.test import nbdev_test
import subprocess
def complete_git_workflow():
"""Complete git workflow with notebook handling."""
print("1. Pulling latest changes...")
subprocess.run(['git', 'pull'])
print("2. Resolving notebook conflicts...")
nbdev_merge()
nbdev_fix()
print("3. Cleaning notebooks...")
nbdev_clean()
print("4. Running tests...")
if not nbdev_test():
print("Tests failed - manual review needed")
return False
print("5. Git workflow complete!")
return True
complete_git_workflow()Install with Tessl CLI
npx tessl i tessl/pypi-nbdev