Files
MovePatchesFromToMahle/README.md
2026-02-21 16:44:57 +01:00

8.9 KiB

Git Bundle Sync — Air-Gap Repository Synchronization

Bidirectional git sync between a home and an enterprise network using a shared file system. No direct network connection between the two networks is required.

Problem & Solution

Two git repositories on separate, non-routable networks need to stay in sync. The only common ground is a shared file system (mounted at ~/fifiletrans on both sides by default).

Solution: git bundle — a built-in git feature that packs any range of commits into a single portable binary file. The bundle is written to the shared folder by one side and picked up by the other.

Home repo  ──── sync-push.sh ────► ~/fifiletrans/ ◄──── sync-pull.sh ──── Office repo
Home repo  ◄─── sync-pull.sh ──── ~/fifiletrans/ ◄──── sync-push.sh ──── Office repo

Network context:

  • Home network has a Gitea instance — used as a local mirror/backup
  • Office network has a GitLab instance — no direct sync between the two is possible
  • Bundle files via shared filesystem are the only transport between the two networks

Scripts Overview

Script Purpose
sync-push.sh Export new commits as a bundle into the shared folder
sync-pull.sh Import a bundle from the shared folder and integrate it
sync-init-export.sh One-time: create full bootstrap bundle + copy scripts for new machine
sync-init-import.sh One-time: clone from bootstrap bundle into a brand-new directory
gitea-setup.sh Initialize a local folder (git or not) and push it to Gitea

Initial Setup of a New Machine

Use this when setting up the repo on a machine for the first time (no existing directory, no git history).

On the source machine

cd /path/to/your/repo
./sync-init-export.sh

This places in ~/fifiletrans/:

  • <repo>-INIT-from-<host>-<timestamp>.bundle — complete git history
  • sync-push.sh, sync-pull.sh, sync-init-import.sh — scripts for the other side
  • INIT-HOWTO-<repo>.txt — printed instructions

On the receiving machine

bash ~/fifiletrans/sync-init-import.sh ~/fifiletrans /path/to/new/repo

This will:

  1. Clone the full bundle into /path/to/new/repo (directory must not exist)
  2. Check out all branches
  3. Install sync-push.sh and sync-pull.sh into the new repo
  4. Set export checkpoints so the first sync-push is incremental

After this, both machines are in sync and ready for the ongoing workflow.


Ongoing Sync Workflow

Send changes (on either machine)

cd /path/to/your/repo
./sync-push.sh

Creates an incremental bundle (only commits since last push). First run after init creates a full bundle. Output example:

Repository : myrepo
Host       : homepc
Branches   : main
Mode       : incremental
New commits: 3
  main: 3 new commit(s)
    a1b2c3d Add feature X
    e4f5g6h Fix bug in Y
    i7j8k9l Refactor Z

Bundle created : /home/user/fifiletrans/myrepo-from-homepc-20260221-143022.bundle (12K)

Receive changes (on the other machine)

cd /path/to/your/repo
./sync-pull.sh

The script:

  1. Lists all available bundles for this repo in the shared folder
  2. Defaults to the newest one (press Enter to accept)
  3. Verifies bundle integrity
  4. Shows exactly which commits are incoming and whether branches have diverged
  5. Offers fast-forward, merge, rebase, or skip per branch

Typical round-trip

# ── At home, after finishing work ──────────────────────────────────────────
cd ~/projects/myrepo
git commit -m "..."
./sync-push.sh
# → writes ~/fifiletrans/myrepo-from-homepc-TIMESTAMP.bundle

# ── At office, pick up home changes ────────────────────────────────────────
cd ~/projects/myrepo
./sync-pull.sh
# → lists bundles, shows new commits, fast-forwards main

# ── At office, continue working ────────────────────────────────────────────
git commit -m "..."
./sync-push.sh
# → writes ~/fifiletrans/myrepo-from-officepc-TIMESTAMP.bundle

# ── At home, pick up office changes ────────────────────────────────────────
./sync-pull.sh

Gitea Integration (Home Network)

gitea-setup.sh registers a local repository with the home Gitea instance. Works for both cases:

  • Folder already a git repo — creates Gitea repo and pushes
  • Folder not yet versioned — runs git init, stages all files, commits, then pushes

Prerequisites

# Install tea (Gitea CLI) if not already present
# See https://gitea.com/gitea/tea/releases

# Configure your Gitea login (once per machine)
tea login add

Usage

./gitea-setup.sh [options] [<repo-path>]

Options:
  -n, --name NAME        Gitea repo name        (default: directory name)
  -d, --desc DESC        Repository description
  -o, --org  ORG         Create under organization
  -p, --private          Create as private repo
  -l, --login LOGIN      tea login profile      (default: active login)
      --auto-push        Enable Gitea auto-push after sync-push.sh
      --no-auto-push     Disable Gitea auto-push (default)

Example

# New, unversioned project
./gitea-setup.sh --name my-project --private ~/projects/my-project

# Existing git repo, enable auto-push to Gitea
cd ~/projects/existing-repo
./gitea-setup.sh --auto-push

Gitea Auto-Push

When enabled, every sync-push.sh run also pushes all branches and tags to the Gitea remote automatically.

# Enable
git config sync.gitea.autopush true

# Disable
git config sync.gitea.autopush false

# Check status
git config sync.gitea.autopush

The Gitea remote name defaults to gitea. Set a different one with:

git config sync.gitea.remote <remote-name>

Configuration Reference

All settings are stored in the repo's local git config (.git/config).

Key Set by Purpose
sync.exported.<branch> sync-push.sh Last exported commit hash per branch
sync.gitea.autopush gitea-setup.sh true/false — auto-push to Gitea after bundle export
sync.gitea.remote gitea-setup.sh Name of the Gitea git remote (default: gitea)

Bundle Filename Convention

<repo-name>-from-<hostname>-<YYYYMMDD-HHMMSS>.bundle       ← ongoing sync
<repo-name>-INIT-from-<hostname>-<YYYYMMDD-HHMMSS>.bundle  ← initial bootstrap

The pull scripts filter by <repo-name> automatically, so multiple repos can safely share the same folder.


Multiple Branches

All scripts handle multiple branches automatically:

  • sync-push.sh / sync-init-export.sh — export all local branches; incremental checkpoint is tracked independently per branch
  • sync-pull.sh / sync-init-import.sh — import all branches from the bundle and prompt for integration of each one individually

Important Notes

Apply incremental bundles in order. An incremental bundle depends on commits already present in the receiving repo. If you skip a bundle, the next pull will fail verification. Apply bundles in chronological order (oldest timestamp first) when catching up after a gap.

Checkpoints are local and per-machine. git config sync.exported.<branch> tracks what this machine has sent. It is not shared and not affected by imports.

Incoming refs persist. Fetched commits are stored under refs/sync/incoming/<branch> and remain available between pull runs. Inspect them anytime:

git log refs/sync/incoming/main
git diff main refs/sync/incoming/main

Conflict resolution. When branches have diverged and you choose merge or rebase, the script hands off to standard git. Resolve conflicts normally, then:

git rebase --continue   # or
git merge --continue

Troubleshooting

Symptom Cause Fix
"Bundle verification failed" Incremental bundle missing prerequisites Apply missing earlier bundles first, or force full re-export (see below)
"Nothing new to export" No commits since last push on any branch Nothing to do
No bundles listed by sync-pull Bundle filename mismatch (repo dir name differs) Check repo directory name matches on both machines
Gitea push fails Remote URL wrong or auth issue git remote -v and tea login list to verify
tea: command not found Gitea CLI not installed Install from https://gitea.com/gitea/tea/releases
Want to reset one branch checkpoint git config --unset sync.exported.<branch>
Want to force a full re-export git config --remove-section sync.exported
Skipped integration, want to redo Run ./sync-pull.sh again and pick the same bundle