# Codeberg & git mirror (de) ...
... PULL & PUSH, Remote Cherry Picking & more
english version - comming soon
[toc]
*Stand: Dezember 2025*
## Einleitung
Git-Mirroring ist eine häufig missverstandene Praxis. Während viele Entwickler Repositories einfach "spiegeln" wollen, gibt es fundamentale Unterschiede zwischen verschiedenen Mirror-Strategien - und diese haben direkte Auswirkungen auf Plattform-Policies und Community-Praktiken. Dieses Paper beleuchtet die Evolution der Codeberg Mirror-Policies, erklärt die technischen Grundlagen und gibt einen Ausblick auf föderierte Forge-Systeme.
## Die Policy-Geschichte: Warum PULL Mirrors verschwanden
### Der Ausgangspunkt (ca. 2019-2020)
Codeberg startete mit offenen Arms: Sowohl PULL als auch PUSH Mirrors waren möglich und einfach zu erstellen. Die Idee war, GitHub-Projekte unkompliziert auf die FOSS-Plattform zu bekommen.
### Das Ressourcen-Problem
Was folgte, war ein klassisches Tragedy-of-the-Commons-Szenario:
**Das Problem in Zahlen:**
- User erstellten massenhaft automatische PULL Mirrors (teilweise 100+ pro User)
- Häufig die größten Repositories: Linux Kernel, GitLab CE, Electron, Chromium
- Mirrors wurden nach kurzem Test-Drive nie gelöscht
- Automatische Updates liefen im Hintergrund weiter
**Die Ressourcen-Explosion:**
```
Beispiel: Linux Kernel Mirror
- Repository-Größe: ~3.5 GB
- Tägliche Updates: mehrmals
- Traffic pro Mirror: ~100 MB/Tag
- 50 User mit diesem Mirror: 5 GB Traffic/Tag
- Nur für EIN Repo!
```
### Codebergs Antwort (ca. 2020/2021)
Die Entscheidung war drastisch aber notwendig:
**Was deaktiviert wurde:**
- ❌ Erstellung neuer **automatischer PULL Mirrors** komplett gesperrt
- ❌ Web-Interface für PULL Mirror Setup entfernt
- ✅ Bestehende Mirrors liefen weiter (kein Breaking Change)
- ✅ Manuelle Mirrors über `git push --mirror` weiterhin möglich
**Wichtig:** PUSH Mirrors waren und sind uneingeschränkt erlaubt!
### Die Philosophie dahinter
Der Policy-Wandel reflektiert Codebergs Grundprinzip:
> **Codeberg will Primary Home sein, nicht Backup-Service**
```
PULL Mirror (disabled):
GitHub ──auto-fetch──> Codeberg
"Ich teste mal Codeberg, aber bleibe auf GitHub"
⚠️ Verbraucht Codeberg-Ressourcen
⚠️ Oft abandoned
PUSH Mirror (allowed):
Codeberg ──auto-push──> GitHub
"Ich bin auf Codeberg, Mirror für Reichweite"
✅ User kontrolliert Updates
✅ Aktive Projekte
```
## PULL vs PUSH: Die technischen Grundlagen
### Was ist ein PULL Mirror?
Ein PULL Mirror **zieht** regelmäßig Änderungen von einer Quelle:
```bash
# Konzeptionell (Server-Seite):
while true; do
git fetch origin
git reset --hard origin/main
sleep 3600 # stündlich
done
```
**Charakteristika:**
- Server entscheidet, wann gefetcht wird
- Läuft automatisch im Hintergrund
- Keine Kontrolle durch Repository-Owner
- Verbraucht kontinuierlich Ressourcen
**Use Case (ursprünglich):**
- GitHub-Projekt auf Codeberg verfügbar machen
- "Insurance Copy" bei Plattform-Problemen
- Erhöhte Sichtbarkeit
### Was ist ein PUSH Mirror?
Ein PUSH Mirror **schiebt** bei Events Änderungen an Ziele:
```bash
# Konzeptionell (User-Seite):
git commit -m "Update"
git push origin main # Primary
git push mirror-github main # Automatisch via Hook
```
**Charakteristika:**
- Wird durch Commits getriggert
- Owner kontrolliert Timing
- Nur bei aktiven Projekten Traffic
- Codeberg muss nur weiterleiten
**Use Case:**
- Codeberg ist Primary Development Platform
- GitHub/GitLab als Mirror für Sichtbarkeit
- Single Source of Truth auf Codeberg
### Codeberg PUSH Mirror einrichten
**In Codeberg Repository Settings:**
1. **Settings** → **Repository** → **Mirror Settings**
2. **Add Push Mirror:**
- Git Remote Repository URL: `https://github.com/username/repo.git`
- Authorization Username: Dein GitHub Username
- Password/Token: GitHub Personal Access Token
- ✅ "Sync when new commits are pushed" aktivieren
- (Optional) Periodic sync Intervall setzen
**Was wird synchronisiert:**
- ✅ Git commits, branches, tags
- ❌ Issues, Pull Requests, Releases, Wikis
**GitHub Token Permissions:**
Minimal benötigt: `repo` (Full control of private repositories)
### Das GitHub-Ende vorbereiten
**Wichtig für Mirror-Setup:**
```markdown
# README.md auf GitHub (ganz oben!)
# 🪞 This is a READ-ONLY Mirror
**Primary Repository:** https://codeberg.org/user/repo
This GitHub repository is an automated mirror for visibility only.
**All activity happens on Codeberg:**
- ✅ Issues → [Open on Codeberg](https://codeberg.org/user/repo/issues)
- ✅ Pull Requests → [Open on Codeberg](https://codeberg.org/user/repo/pulls)
- ✅ Discussions → [Join on Codeberg](https://codeberg.org/user/repo)
*The real FLOSS way* 🚀
```
**GitHub Repository Settings deaktivieren:**
- Issues
- Projects
- Wiki
- Discussions
- (Optional) Pull Requests - siehe nächster Abschnitt
## Das Pull Request Problem
### Die Herausforderung
Push Mirrors sind unidirektional. Aber was passiert, wenn jemand:
1. Dein GitHub Mirror forkt
2. Änderungen macht
3. Einen Pull Request öffnen will?
**Das Dilemma:**
- Contributor hat Arbeit investiert
- Will nicht zu Codeberg wechseln
- Frustrierendes Erlebnis wenn PRs disabled
### Lösungsansätze
**Option 1: Konsequent (empfohlen für FOSS-First Projekte)**
```markdown
# CONTRIBUTING.md (auf GitHub Mirror)
⚠️ **This is a READ-ONLY mirror**
## To contribute:
1. Go to primary repository: https://codeberg.org/user/repo
2. Create an account on Codeberg (it's free and FOSS!)
3. Fork the repository there
4. Make your changes
5. Open a Pull Request on Codeberg
## Already made changes on GitHub?
No problem! You can push your branch to Codeberg:
\`\`\`bash
# Add Codeberg as remote
git remote add codeberg https://codeberg.org/user/repo.git
# Push your branch
git push codeberg your-branch-name
# Then open PR via Codeberg web interface
\`\`\`
## Why Codeberg?
- 🔓 100% Open Source (AGPLv3)
- 🇪🇺 GDPR compliant, hosted in EU
- 💚 Non-profit, community-driven
- 🚫 No tracking, no ads, no corporate control
Join us on the real FLOSS platform! 🎉
```
**GitHub Settings:**
- ❌ Issues disabled
- ❌ Pull Requests disabled
- README.md mit großem Banner
**Option 2: Pragmatisch (für Übergangszeit)**
- Pull Requests auf GitHub **offen** lassen
- Template mit Auto-Response
- Maintainer cherry-pickt manuell nach Codeberg
- Oder bittet Contributors freundlich, PR auf Codeberg neu zu erstellen
**Option 3: Semi-Automatisch**
```bash
# Als Maintainer: GitHub PR nach Codeberg übernehmen
# GitHub-Fork als Remote hinzufügen
git remote add contributor https://github.com/contributor/repo.git
# Branch fetchen
git fetch contributor feature-branch
# Nach Codeberg cherry-picken
git checkout -b contributor-feature
git cherry-pick contributor/feature-branch
# Auf Codeberg pushen
git push origin contributor-feature
# PR auf Codeberg öffnen
```
### Remote Cherry Picking: Der Workflow
Cherry-Picking von Remote Repositories ist die Brücke zwischen Plattformen:
```bash
# Komplettes Beispiel:
# Ein GitHub-User hat in seinem Fork Änderungen gemacht
# 1. GitHub-Fork als Remote hinzufügen
git remote add github-fork https://github.com/someuser/repo.git
# 2. Alle Branches fetchen
git fetch github-fork
# 3. Commits identifizieren
git log github-fork/feature-branch
# 4. Einzelne Commits cherry-picken
git cherry-pick abc123def456
# 5. Oder ganze Branch-Range
git cherry-pick upstream/main..github-fork/feature-branch
# 6. Auf Codeberg pushen
git push origin main
```
**Vorteile:**
- Keine direkte GitHub-Integration nötig
- Du kontrollierst, was merged wird
- Commit-History bleibt sauber
- Funktioniert auch bei privaten Repos (mit Token)
**Attribution erhalten:**
```bash
# Cherry-Pick behält Original-Author
git cherry-pick -x abc123def456 # Adds "cherry picked from commit..."
# Oder manuell im Commit-Message
git commit --amend
# Füge hinzu:
# "Originally contributed by @username on GitHub"
```
## Multi-Remote Workflows
### Die Kraft mehrerer Remotes
Git erlaubt beliebig viele Remotes - nutze das!
```bash
# Standard-Setup
git remote -v
origin https://codeberg.org/user/repo.git (fetch)
origin https://codeberg.org/user/repo.git (push)
# GitHub-Mirror hinzufügen
git remote add github https://github.com/user/repo.git
# GitLab-Mirror hinzufügen
git remote add gitlab https://gitlab.com/user/repo.git
# Alle auf einmal pushen
git remote add all https://codeberg.org/user/repo.git
git remote set-url --add --push all https://codeberg.org/user/repo.git
git remote set-url --add --push all https://github.com/user/repo.git
git remote set-url --add --push all https://gitlab.com/user/repo.git
# Dann:
git push all main # Pushed zu allen drei!
```
### Selektives Pushen
```bash
# Nur zu Codeberg (Primary)
git push origin main
# Nur zu GitHub Mirror (für Tags z.B.)
git push github v1.0.0
# Zu allen außer GitLab
git push origin main && git push github main
```
### Branch-Protection mit Remotes
```bash
# Experimental-Branch nur auf Codeberg
git checkout -b experimental
git push origin experimental
# Wenn stabil, dann auch mirrors
git push github experimental
git push gitlab experimental
```
## Best Practices für Mirror-Setups
### 1. Single Source of Truth
**Regel:** Es gibt IMMER eine Primary Platform.
```
✅ Codeberg Primary → GitHub/GitLab Mirrors
❌ GitHub ←→ Codeberg bidirektional (Konflikt-Hölle!)
```
### 2. Klare Kommunikation
**In JEDEM Mirror-Repository:**
- README.md Banner (prominent!)
- CONTRIBUTING.md mit Primary-Link
- Issues/PRs disabled oder Template mit Redirect
### 3. Automatisierung wo sinnvoll
**Codeberg Push Mirror für:**
- Stable Releases
- Main/Master Branch
- Tagged Versions
**Manuell für:**
- Experimental Branches
- WIP Features
- Private/Sensitive Branches
### 4. Token-Management
```bash
# Verschiedene Tokens für verschiedene Zwecke
~/.git-credentials
codeberg.org:....token-full-access
github.com:.....token-push-only
gitlab.com:.....token-push-only
# Oder per Git Config
git config credential.https://github.com.username youruser
```
### 5. Mirror-Monitoring
Regelmäßig checken:
- Sind Mirrors noch sync?
- Funktionieren Push Hooks?
- Sind Mirror-READMEs aktuell?
```bash
# Quick-Check Script
#!/bin/bash
git fetch origin
git fetch github
git fetch gitlab
# Compare commit hashes
ORIGIN=$(git rev-parse origin/main)
GITHUB=$(git rev-parse github/main)
GITLAB=$(git rev-parse gitlab/main)
if [ "$ORIGIN" = "$GITHUB" ] && [ "$ORIGIN" = "$GITLAB" ]; then
echo "✅ All mirrors in sync"
else
echo "⚠️ Mirrors out of sync!"
fi
```
## Aktuelle Codeberg-Richtlinien (Stand 2024/2025)
### Was ist erlaubt
**PUSH Mirrors:**
- ✅ Unbegrenzte Anzahl von Push-Mirror-Zielen
- ✅ Zu jeder Git-Plattform (GitHub, GitLab, Gitea, etc.)
- ✅ Automatische Synchronisation via Web-Interface
- ✅ Manuelle `git push --mirror` jederzeit
**Manuelle PULL:**
- ✅ `git pull` von externen Repos (lokal auf deinem Rechner)
- ✅ Multi-Remote Setup mit manueller Synchronisation
- ✅ Import via Web-Interface (einmalig)
### Was nicht erlaubt ist
**Automatische PULL Mirrors:**
- ❌ Automatisches Fetchen von GitHub/GitLab
- ❌ Scheduled Updates von externen Repos
- ❌ "Mirror-Bot" Accounts
**Ausnahmen:** Case-by-case nach Absprache mit Codeberg-Team für spezielle Use Cases.
### Empfehlungen von Codeberg
1. **Codeberg-First Development:** Entwickle primär auf Codeberg
2. **Strategic Mirroring:** Mirror nur zu GitHub/GitLab für Sichtbarkeit
3. **Community Education:** Erkläre warum Codeberg, nicht nur "ist auch auf GitHub"
4. **Resource Awareness:** Lösche inaktive Mirrors, halte Repos klein
## Der Ausblick: Föderiertes Git mit ForgeFed
### Die Vision
Stell dir vor: Git-Forges könnten wie E-Mail oder Mastodon funktionieren - föderiert, dezentral, interoperabel.
```
Developer A @ codeberg.org
│
├─ Opens Issue @ gitlab.com/project
├─ Comments on PR @ github.com/other-project
└─ Follows Developer B @ git.sr.ht
```
### ForgeFed: Der ActivityPub-Ansatz
**ForgeFed** ist ein ActivityPub-Extension-Protokoll für Forge-Federation.
**Status Quo (Dezember 2025):**
**✅ Bereits implementiert in Forgejo:**
- **Federated Repository Stars** (seit Juni 2024)
- Du kannst Repos auf anderen Forgejo-Instanzen "starren"
- Via ActivityPub, wie Mastodon-Posts liken
- **User Following** (seit August 2024)
- Entwickler auf anderen Instanzen folgen
- Updates in deinem Activity-Feed sehen
- **F3 Format (Friendly Forge Format)**
- Import/Export zwischen Forges
- Mirroring mit Metadaten
**🚧 In aktiver Entwicklung:**
- Cross-Instance Issues
- Cross-Instance Pull Requests
- Comment Federation
- Notification System
### Wie würde das funktionieren?
**Beispiel: Cross-Instance Pull Request**
```
1. Developer auf codeberg.org findet Bug in Repo auf gitlab.com
2. Forkt das Repo LOKAL (keine GitLab-Account nötig!)
3. Macht Änderungen
4. Öffnet PR via ActivityPub:
- Codeberg-Instanz schickt AP-Message an GitLab-Instanz
- GitLab erstellt PR-Objekt
- Notifications gehen an Maintainer
- Comments funktionieren bidirektional via AP
```
**Technisch (vereinfacht):**
```json
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Create",
"actor": "https://codeberg.org/users/alice",
"object": {
"type": "ForgeFed:PullRequest",
"target": "https://gitlab.com/org/repo",
"source": {
"repository": "https://codeberg.org/alice/repo-fork",
"branch": "fix-bug-123"
},
"title": "Fix critical bug in parser",
"content": "This PR fixes..."
}
}
```
### Die Roadmap
**Forgejo Federation Roadmap 2025:**
**Q1 2025:**
- Cross-instance Issue creation
- Basic PR federation (read-only)
**Q2-Q3 2025:**
- Full PR federation (comments, reviews)
- Forge Discovery Protocol
- ActivityPub-based notifications
**Q4 2025+:**
- CI/CD federation
- Package Registry federation
- Advanced access control
### Warum das alles ändert
**Vorher (heute):**
```
GitHub Account → GitHub-only Contributions
GitLab Account → GitLab-only Contributions
Codeberg Account → Codeberg-only Contributions
```
**Nachher (Federation):**
```
EIN Account @ Lieblings-Forge
→ Contribute zu ALLEN föderierten Forges
→ Wie E-Mail: gmail.com ↔ outlook.com ↔ protonmail.com
```
### Auswirkungen auf Mirror-Strategien
**Was bedeutet Federation für Mirrors?**
**Kurzfristig (2025-2026):**
- Mirrors bleiben relevant für Sichtbarkeit
- Aber: Stars/Follows können föderiert werden
- Weniger Grund für "Mirror zur Reichweite"
**Mittelfristig (2027+):**
- Issues/PRs föderiert → Mirrors nur noch für Redundanz?
- Discovery über Federation → GitHub-Mirror weniger kritisch
- Primary-Platform-Entscheidung bleibt, aber weniger einschränkend
**Langfristig (2030+):**
- Mirrors möglicherweise obsolet
- Stattdessen: Multi-Instanz Hosting mit auto-sync
- Git selbst wird föderiert?
### Risiken und Herausforderungen
**Technisch:**
- Spam/Abuse über Federation
- Performance bei großen Repos
- Konfliktauflösung zwischen Instanzen
**Sozial:**
- GitHub/GitLab unterstützen ForgeFed (noch) nicht
- Kleinere Forges müssen nachziehen
- Community-Buy-In erforderlich
**Politisch:**
- BigTech-Forges haben kein Interesse an Federation
- Lock-In ist business model
- Regulierung könnte helfen (Digital Markets Act?)
## Fazit
### Die Mirror-Landschaft heute
**Status Quo:**
- PULL Mirrors sind aus guten Gründen restricted
- PUSH Mirrors sind der richtige Weg für Codeberg-First Development
- Manuelle Multi-Remote-Workflows funktionieren gut
- Cherry-Picking und Remote-Handling überbrücken Plattformen
**Best Practice:**
```
Primary Development: Codeberg
Strategic Mirrors: GitHub/GitLab (Push only)
Clear Communication: README, CONTRIBUTING
Community Education: Why FOSS Forges matter
```
### Die Federation-Zukunft
**Ausblick:**
- ForgeFed macht große Fortschritte
- 2025 wird spannend für Cross-Instance-Features
- Langfristig könnte Federation Mirrors überflüssig machen
- Aber: Der Weg dahin ist noch lang
**Warum das wichtig ist:**
> Mirrors sind ein Workaround für Fragmentierung.
> Federation ist die Lösung.
### Call to Action
**Für Entwickler:**
- Experimentiere mit Codeberg als Primary Platform
- Nutze PUSH Mirrors strategisch
- Teste ForgeFed-Features sobald verfügbar
- Teile deine Erfahrungen
**Für die Community:**
- Unterstütze Forgejo/ForgeFed Development
- Gib Feedback zu Federation-Features
- Educate über FOSS-Forge-Alternativen
- Fordere Federation auch von BigTech-Forges
**Für Plattformen:**
- Implementiert ForgeFed
- Macht Migration einfach (F3!)
- Respektiert User-Choices
- Denkt langfristig: Federation über Lock-In
## Ressourcen
**Codeberg:**
- Codeberg.org: https://codeberg.org
- Codeberg Blog: https://blog.codeberg.org
- Forgejo Documentation: https://forgejo.org/docs
**ForgeFed:**
- Specification: https://forgefed.org
- Forgejo Federation Roadmap: https://codeberg.org/forgejo-contrib/federation
- ForgeFed Discussion: https://socialhub.activitypub.rocks/tag/forgefed
**Tools:**
- F3 (Friendly Forge Format): https://f3.forgefriends.org
- Woodpecker CI: https://woodpecker-ci.org
**Community:**
- Codeberg e.V.: https://codeberg.org/Codeberg
- Forgejo: https://codeberg.org/forgejo
- ActivityPub Community: https://activitypub.rocks
**Weiterführende Lektüre:**
- "Give Up GitHub" Campaign
- "The Real FLOSS Way" - Delightful Lists
- "Federation vs. Lock-In" - ActivityPub Case Studies