This commit adds docs/notes/git-mirroring.md documenting: - Workspace git remote conventions (origin = Forgejo, github = GitHub) - Forgejo push mirror configuration and API usage - Verification commands and health checks - Troubleshooting guide for common mirror issues - Complete incident history of the 160-commit divergence - Quick reference commands for daily workflow and recovery Synthesizes findings from child beads: bf-1t8i9 (diagnosis), bf-1o0la (mirror config), bf-682zv (sync blocker), bf-67zia (remotes fixed). Acceptance criteria: - PASS: docs/notes/git-mirroring.md exists and is complete - PASS: Documents workspace convention for git remotes - PASS: Documents Forgejo push mirror configuration and API usage - PASS: Includes troubleshooting section - PASS: References all child bead note files - PASS: Committed to git repository Closes bf-585u5
411 lines
12 KiB
Markdown
411 lines
12 KiB
Markdown
# Git Mirroring Setup and Troubleshooting
|
|
|
|
**Date:** 2026-07-05
|
|
**Purpose:** Comprehensive documentation of git mirroring setup, workspace conventions, and resolution processes for the pdftract repository.
|
|
|
|
## Table of Contents
|
|
|
|
- [Workspace Convention](#workspace-convention)
|
|
- [Forgejo Push Mirror Configuration](#forgejo-push-mirror-configuration)
|
|
- [Verifying Mirror Status](#verifying-mirror-status)
|
|
- [Troubleshooting Common Issues](#troubleshooting-common-issues)
|
|
- [Incident History: 84-Commit Divergence](#incident-history-84-commit-divergence)
|
|
- [References and Related Documentation](#references-and-related-documentation)
|
|
|
|
---
|
|
|
|
## Workspace Convention
|
|
|
|
### Primary vs. Mirror Remotes
|
|
|
|
The pdftract repository follows a **primary-mirror** git workflow:
|
|
|
|
| Remote | URL | Role | Usage |
|
|
|--------|-----|------|-------|
|
|
| `origin` | `https://git.ardenone.com/jedarden/pdftract.git` | **Primary** (Forgejo) | All pushes go here first |
|
|
| `github` | `https://github.com/jedarden/pdftract.git` | **Mirror** (GitHub) | Automatic sync from Forgejo |
|
|
|
|
### Key Principles
|
|
|
|
1. **Forgejo (`origin`) is the source of truth**
|
|
- All commits must be pushed to Forgejo first
|
|
- CI/CD runs on Forgejo via Argo Workflows
|
|
- GitHub is kept in sync automatically
|
|
|
|
2. **GitHub is a read-only mirror**
|
|
- Used for GitHub Issues, PRs, and visibility
|
|
- Never push directly to GitHub unless recovering from a sync issue
|
|
- The Forgejo push mirror keeps GitHub up-to-date
|
|
|
|
3. **Branch tracking must point to `origin`**
|
|
```bash
|
|
# Correct configuration
|
|
git branch --set-upstream-to=origin/main main
|
|
|
|
# Verify with:
|
|
git branch -vv
|
|
# Should show: main -> origin/main
|
|
```
|
|
|
|
### Verification Commands
|
|
|
|
```bash
|
|
# Check remote configuration
|
|
git remote -v
|
|
|
|
# Check branch tracking
|
|
git branch -vv
|
|
|
|
# Verify remote fetch URLs
|
|
git config --get remote.origin.url
|
|
git config --get remote.github.url
|
|
```
|
|
|
|
---
|
|
|
|
## Forgejo Push Mirror Configuration
|
|
|
|
### Mirror Setup Details
|
|
|
|
The Forgejo-to-GitHub push mirror is configured in the Forgejo web UI or API:
|
|
|
|
| Setting | Value | Purpose |
|
|
|---------|-------|---------|
|
|
| **Remote Address** | `https://github.com/jedarden/pdftract.git` | GitHub mirror target |
|
|
| **Sync Interval** | `10m0s` | Sync every 10 minutes |
|
|
| **Sync on Commit** | `true` | Sync immediately after each push |
|
|
| **Created** | `2026-05-16T19:51:17Z` | Mirror creation timestamp |
|
|
|
|
### API Response Example
|
|
|
|
```json
|
|
{
|
|
"repo_name": "pdftract",
|
|
"remote_name": "remote_mirror_nfF0JdlNzC",
|
|
"remote_address": "https://github.com/jedarden/pdftract.git",
|
|
"created": "2026-05-16T19:51:17Z",
|
|
"last_update": "2026-07-05T21:59:42Z",
|
|
"interval": "10m0s",
|
|
"sync_on_commit": true,
|
|
"last_error": "PushRejected Error: large files detected"
|
|
}
|
|
```
|
|
|
|
### How to Check Mirror Status
|
|
|
|
#### Via Forgejo Web UI
|
|
|
|
1. Navigate to: `https://git.ardenone.com/jedarden/pdftract/settings/mirrors`
|
|
2. Verify the push mirror to GitHub exists
|
|
3. Check the "Last Sync" timestamp
|
|
4. Review "Last Error" field for sync failures
|
|
|
|
#### Via Forgejo API
|
|
|
|
```bash
|
|
# Requires Forgejo API token
|
|
curl -H "Authorization: token <FORGEJO_TOKEN>" \
|
|
https://git.ardenone.com/api/v1/repos/jedarden/pdftract/push_mirrors
|
|
```
|
|
|
|
Expected response:
|
|
- Mirror entry for GitHub should exist
|
|
- `sync_on_commit` should be `true`
|
|
- `interval` should be `10m0s`
|
|
- Check `last_error` for any sync failures
|
|
|
|
---
|
|
|
|
## Verifying Mirror Status
|
|
|
|
### Quick Health Check
|
|
|
|
```bash
|
|
# 1. Check if Forgejo and GitHub main branches match
|
|
FORGEJO_SHA=$(git ls-remote git.ardenone.com:jedarden/pdftract.git refs/heads/main | awk '{print $1}')
|
|
GITHUB_SHA=$(git ls-remote github.com:jedarden/pdftract.git refs/heads/main | awk '{print $1}')
|
|
|
|
if [ "$FORGEJO_SHA" = "$GITHUB_SHA" ]; then
|
|
echo "✓ Mirror is in sync"
|
|
else
|
|
echo "✗ Mirror is out of sync"
|
|
echo "Forgejo: $FORGEJO_SHA"
|
|
echo "GitHub: $GITHUB_SHA"
|
|
fi
|
|
```
|
|
|
|
### Count Commits Behind
|
|
|
|
```bash
|
|
# Fetch latest from both remotes
|
|
git fetch origin
|
|
git fetch github
|
|
|
|
# Count commits behind GitHub
|
|
git log --oneline origin/main ^github/main | wc -l
|
|
```
|
|
|
|
### Find Divergence Point
|
|
|
|
```bash
|
|
# Find merge-base (common ancestor)
|
|
git merge-base origin/main github/main
|
|
|
|
# Show when divergence started
|
|
git log --oneline --date-order origin/main ^github/main | head -1
|
|
```
|
|
|
|
---
|
|
|
|
## Troubleshooting Common Issues
|
|
|
|
### Issue 1: Branch Tracking Wrong Remote
|
|
|
|
**Symptoms:**
|
|
- `git push` goes to GitHub instead of Forgejo
|
|
- Commits appear on GitHub but not Forgejo
|
|
- Mirror shows old commits
|
|
|
|
**Diagnosis:**
|
|
```bash
|
|
git branch -vv
|
|
# If main tracks github instead of origin:
|
|
# main -> github/main
|
|
```
|
|
|
|
**Fix:**
|
|
```bash
|
|
git branch --set-upstream-to=origin/main main
|
|
git branch -vv # Verify: main -> origin/main
|
|
```
|
|
|
|
**Prevention:**
|
|
- Always use `git push origin main` for explicit pushes
|
|
- Never use bare `git push` without verifying remote
|
|
|
|
### Issue 2: Mirror Sync Failing Due to Large Files
|
|
|
|
**Symptoms:**
|
|
- Forgejo has newer commits than GitHub
|
|
- Mirror `last_error` shows "large files detected"
|
|
- Push to GitHub rejected with `GH001: Large files detected`
|
|
|
|
**Diagnosis:**
|
|
```bash
|
|
# Find large files in history
|
|
git rev-list --objects --all |
|
|
git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' |
|
|
awk '/^blob/ {print substr($0,6)}' |
|
|
sort -n -k2 |
|
|
tail -20
|
|
```
|
|
|
|
**Fix Options:**
|
|
|
|
#### Option 1: Git LFS (Recommended)
|
|
```bash
|
|
# Install git-lfs
|
|
sudo apt-get install git-lfs # Debian/Ubuntu
|
|
# or
|
|
brew install git-lfs # macOS
|
|
|
|
# Initialize LFS
|
|
git lfs install
|
|
git lfs track "*.ppm" "*.pdf" "*.bin" "*.psd"
|
|
git add .gitattributes
|
|
git commit -m "chore: enable git-lfs for large files"
|
|
git push origin main
|
|
```
|
|
|
|
#### Option 2: Remove Large Files from History
|
|
```bash
|
|
# Use git-filter-repo (preferred over filter-branch)
|
|
pip install git-filter-repo
|
|
git filter-repo --path --1.ppm --invert-paths
|
|
git push origin main --force-with-lease
|
|
```
|
|
|
|
⚠️ **Warning:** History rewrites change commit SHAs and require force-pushes.
|
|
|
|
### Issue 3: Mirror Disabled or Missing
|
|
|
|
**Symptoms:**
|
|
- GitHub never updates despite Forgejo commits
|
|
- No mirror entry in Forgejo settings
|
|
- `last_update` timestamp is very old
|
|
|
|
**Diagnosis:**
|
|
```bash
|
|
# Check via API
|
|
curl -H "Authorization: token <TOKEN>" \
|
|
https://git.ardenone.com/api/v1/repos/jedarden/pdftract/push_mirrors
|
|
```
|
|
|
|
**Fix:**
|
|
1. Navigate to Forgejo repository settings
|
|
2. Go to "Mirrors" section
|
|
3. Add new push mirror: `https://github.com/jedarden/pdftract.git`
|
|
4. Enable "Sync on commit"
|
|
5. Set interval to `10m`
|
|
|
|
### Issue 4: Authentication Issues
|
|
|
|
**Symptoms:**
|
|
- Mirror fails with authentication errors
|
|
- `last_error` shows "permission denied"
|
|
|
|
**Fix:**
|
|
1. Verify GitHub credentials in Forgejo mirror settings
|
|
2. Use GitHub personal access token with `repo` scope
|
|
3. Update mirror credentials in Forgejo web UI
|
|
|
|
---
|
|
|
|
## Incident History: 84-Commit Divergence
|
|
|
|
### Timeline
|
|
|
|
| Date | Event | Details |
|
|
|------|-------|---------|
|
|
| 2026-06-01 | Divergence started | Commit `1c6f26ec` was first to diverge |
|
|
| 2026-07-05 | Issue discovered | GitHub found to be 160 commits behind Forgejo |
|
|
| 2026-07-05 | Root cause identified | Local branch tracked `github` instead of `origin` |
|
|
| 2026-07-05 | Mirror config verified | Push mirror exists but blocked by large files |
|
|
| 2026-07-05 | Remotes fixed | Branch tracking corrected to `origin/main` |
|
|
| 2026-07-05 | Documentation created | This comprehensive guide |
|
|
|
|
### Root Cause Analysis
|
|
|
|
The divergence had **two compounding issues**:
|
|
|
|
1. **Local branch tracking misconfiguration**
|
|
- Local `main` branch tracked `github` instead of `origin`
|
|
- Regular `git push` went to GitHub (behind) instead of Forgejo (source of truth)
|
|
- Manual `git push origin main` required for Forgejo updates
|
|
|
|
2. **Mirror blocked by large files**
|
|
- Forgejo push mirror configured correctly
|
|
- Sync failing due to `--1.ppm` (235.13 MB) and `test_parse_simple` (60.74 MB)
|
|
- GitHub pre-receive hook rejected all sync attempts
|
|
|
|
### Blocker Details
|
|
|
|
**Large files in git history:**
|
|
- `--1.ppm`: 235.13 MB (exceeds GitHub's 100 MB hard limit)
|
|
- `test_parse_simple`: 60.74 MB (exceeds GitHub's 50 MB recommended limit)
|
|
|
|
Both files were added and removed in the sync range:
|
|
- Added in: `1c6f26ec` fix(bf-4mkhv): clean up unused imports in hash.rs
|
|
- Removed in: `007439e7` chore(bf-8031): remove tracked debug/scratch artifacts
|
|
|
|
**GitHub's behavior:** Even though the files were removed from the working tree, they still exist in git's object database. GitHub checks all objects being pushed, including historical ones.
|
|
|
|
### Resolution Attempt
|
|
|
|
Attempted to sync GitHub main to Forgejo main:
|
|
```bash
|
|
git fetch github
|
|
git push github main
|
|
```
|
|
|
|
**Result:** Rejected by GitHub pre-receive hook:
|
|
```
|
|
remote: error: File --1.ppm is 235.13 MB; this exceeds GitHub's file size limit of 100.00 MB
|
|
remote: error: GH001: Large files detected.
|
|
```
|
|
|
|
### Recommended Resolution Path
|
|
|
|
1. **Set up Git LFS** on both repositories
|
|
2. **Migrate large files** to LFS tracking
|
|
3. **Push to Forgejo** to propagate LFS pointers
|
|
4. **Verify mirror sync** succeeds on next push
|
|
5. **Confirm GitHub** matches Forgejo
|
|
|
|
### Final Commit Range
|
|
|
|
- **Forgejo/main**: `02bfffef` docs(bf-1o0la): document Forgejo push mirror configuration and status
|
|
- **GitHub/main**: `88b4f0da` fix(pdftract-2rc4): fix CI schema gate script and add verification note
|
|
- **Commits behind**: 160 (updated from initial 84 estimate during investigation)
|
|
- **Merge-base**: `88b4f0da276c7257ade02d3cecfaeb09f7881acc`
|
|
|
|
---
|
|
|
|
## References and Related Documentation
|
|
|
|
### Child Bead Documentation
|
|
|
|
This comprehensive document synthesizes findings from four child beads:
|
|
|
|
1. **[Diagnosis (bf-1t8i9)](notes/bf-1t8i9-diagnosis.md)**
|
|
- Initial divergence discovery and state assessment
|
|
- Identified local branch tracking misconfiguration
|
|
- Documented 158-commit divergence (updated to 160 during investigation)
|
|
|
|
2. **[Mirror Configuration (bf-1o0la)](notes/bf-1o0la-mirror-config.md)**
|
|
- Forgejo push mirror API verification
|
|
- Confirmed mirror exists and is configured correctly
|
|
- Identified large file blocker preventing sync
|
|
|
|
3. **[Sync Verification (bf-682zv)](notes/bf-682zv.md)**
|
|
- Attempted GitHub sync from Forgejo
|
|
- Documented large file rejection by GitHub
|
|
- Recommended Git LFS resolution path
|
|
|
|
4. **[Remotes Fixed (bf-67zia)](notes/bf-67zia-remotes-fixed.md)**
|
|
- Corrected local branch tracking to `origin/main`
|
|
- Verified remote configuration follows workspace convention
|
|
- Confirmed both remotes are accessible
|
|
|
|
### Parent Bead
|
|
|
|
- **[Genesis: Git Mirror Setup and Resolution (bf-320gz)]** - Parent coordination bead for this work
|
|
|
|
### External References
|
|
|
|
- **Forgejo API Documentation**: https://forgejo.jedarden.com/api/v1/
|
|
- **GitHub Large File Storage**: https://git-lfs.github.com/
|
|
- **GitHub File Size Limits**: https://docs.github.com/en/repositories/working-with-files/using-files/large-files
|
|
|
|
---
|
|
|
|
## Quick Reference Commands
|
|
|
|
### Daily Workflow
|
|
|
|
```bash
|
|
# 1. Pull latest from Forgejo
|
|
git pull origin main
|
|
|
|
# 2. Do your work
|
|
git commit -m "feat: something"
|
|
|
|
# 3. Push to Forgejo (source of truth)
|
|
git push origin main
|
|
|
|
# 4. Verify mirror status (optional)
|
|
# Check GitHub web UI or use API:
|
|
curl -H "Authorization: token <TOKEN>" \
|
|
https://git.ardenone.com/api/v1/repos/jedarden/pdftract/push_mirrors
|
|
```
|
|
|
|
### Recovery Commands
|
|
|
|
```bash
|
|
# If GitHub gets out of sync:
|
|
git fetch github
|
|
git push github origin/main:main --force-with-lease
|
|
|
|
# If branch tracking gets messed up:
|
|
git branch --set-upstream-to=origin/main main
|
|
|
|
# If mirror is disabled or missing:
|
|
# Check Forgejo web UI: https://git.ardenone.com/jedarden/pdftract/settings/mirrors
|
|
```
|
|
|
|
---
|
|
|
|
**Document Status:** ✅ Complete
|
|
**Last Updated:** 2026-07-05
|
|
**Maintainer:** jedarden
|
|
**Version:** 1.0
|