# Git Submodules Guide for Ginxsom

This project uses git submodules to include external dependencies that we reference but never modify.

## Current Submodules

- **blossom**: The official Blossom protocol specification and BUD documents
- **nostr_core_lib**: Core nostr functionality for authentication and event validation

## Key Principles

1. **Read-Only**: We never modify submodule content directly
2. **Version Pinning**: Submodules are pinned to specific commits for stability
3. **Upstream Updates**: We periodically update to newer versions when needed

---

## Common Git Submodule Commands

### Initial Setup (for new clones)
```bash
# Clone the main repository
git clone ssh://git@git.laantungir.net:222/laantungir/ginxsom.git

# Initialize and update all submodules
git submodule update --init --recursive
```

### One-Line Clone (includes submodules)
```bash
git clone --recursive ssh://git@git.laantungir.net:222/laantungir/ginxsom.git
```

### Update Submodules to Latest
```bash
# Update to latest commit on default branch
git submodule update --remote

# Update specific submodule
git submodule update --remote blossom
git submodule update --remote nostr_core_lib
```

### Pin Submodule to Specific Version
```bash
# Go into submodule directory
cd blossom

# Checkout specific commit/tag
git checkout v1.2.3  # or specific commit hash

# Go back to main repo
cd ..

# Stage the submodule change
git add blossom

# Commit the pin
git commit -m "Pin blossom submodule to v1.2.3"
```

### Check Submodule Status
```bash
# Show current submodule commits
git submodule status

# Show if submodules have uncommitted changes
git status

# Show submodule branch/commit info
git submodule foreach git log --oneline -1
```

---

## Workflow Best Practices

### Daily Development
1. **Never edit submodule files directly** - they're read-only references
2. **Use `git status` regularly** - it shows submodule state changes
3. **Commit submodule updates separately** - makes history cleaner

### When Submodule Updates Available
```bash
# Check what's new upstream
cd blossom
git fetch
git log HEAD..origin/main --oneline
cd ..

# If updates look good, update the pin
git submodule update --remote blossom
git add blossom
git commit -m "Update blossom submodule to latest"
```

### Team Collaboration
```bash
# After pulling main repo changes
git pull

# Update submodules if they changed
git submodule update --init --recursive

# Or use this one-liner for pulls
git pull --recurse-submodules
```

---

## Common Issues & Solutions

### "Submodule path contains unstaged changes"
```bash
# This means files in submodule were accidentally modified
cd <submodule_path>
git checkout .  # Discard changes
cd ..
```

### "Submodule not initialized"
```bash
# Initialize and update
git submodule update --init <submodule_name>
```

### "Detached HEAD state in submodule"
```bash
# This is normal! Submodules are pinned to specific commits
# Only worry if you need to track a branch instead of a commit
```

### Accidentally Committed Changes in Submodule
```bash
# Go to submodule
cd <submodule_path>

# Reset to the pinned commit
git reset --hard <pinned_commit_hash>

cd ..

# The main repo should now show no changes to submodule
```

---

## Integration with Build System

### Makefile Integration
```makefile
# Ensure submodules are updated before building
build: update-submodules
	# build commands here

update-submodules:
	git submodule update --init --recursive

.PHONY: build update-submodules
```

### CI/CD Integration
```bash
# In your CI/CD pipeline, always initialize submodules
git submodule update --init --recursive
```

---

## Project-Specific Usage

### Blossom Submodule
- **Purpose**: Read BUD specifications and protocol documentation
- **Usage**: Reference only, never modify
- **Update frequency**: When new BUDs are released or existing ones updated

### nostr_core_lib Submodule  
- **Purpose**: Core nostr functionality for ginxsom authentication
- **Usage**: Link against in build process, never modify source
- **Update frequency**: When bug fixes or new features needed

---

## Advanced Submodule Operations

### Change Submodule URL
```bash
# Edit .gitmodules file
vim .gitmodules

# Update git config
git submodule sync

# Update the submodule
git submodule update --init
```

### Remove a Submodule
```bash
# Remove from .gitmodules
git config -f .gitmodules --remove-section submodule.<name>

# Remove from .git/config
git config -f .git/config --remove-section submodule.<name>

# Remove directory
git rm --cached <submodule_path>
rm -rf <submodule_path>

# Commit changes
git add .gitmodules
git commit -m "Remove <name> submodule"
```

### Track a Branch Instead of Commit
```bash
# Edit .gitmodules to add branch
[submodule "blossom"]
    path = blossom
    url = ssh://git@git.laantungir.net:222/laantungir/blossom.git
    branch = main

# Update to track branch
git submodule update --remote --merge
```

---

## Security Considerations

1. **Verify submodule sources** - only use trusted repositories
2. **Pin to specific commits** - avoid automatically tracking latest
3. **Review submodule updates** - check changes before updating pins
4. **Use SSH URLs** - more secure than HTTPS for private repos

---

## Troubleshooting Checklist

- [ ] Did you run `git submodule update --init --recursive` after cloning?
- [ ] Are you trying to edit files in submodule directories? (Don't!)
- [ ] Did you commit submodule changes to the main repository?
- [ ] Are your SSH keys set up for the submodule repositories?
- [ ] Is the submodule URL accessible from your current environment?

---

## Quick Reference

| Action | Command |
|--------|---------|
| Clone with submodules | `git clone --recursive <repo>` |
| Initialize after clone | `git submodule update --init --recursive` |
| Update all submodules | `git submodule update --remote` |
| Update one submodule | `git submodule update --remote <name>` |
| Check status | `git submodule status` |
| Reset submodule | `cd <sub> && git checkout . && cd ..` |

Remember: **Submodules are for code we use but never change!**
