97 lines
5.4 KiB
Markdown
97 lines
5.4 KiB
Markdown
# Firmware fork → DT Gitea migration + clean RRG-tracking model
|
|
|
|
**Status:** Planned, not started · **Date:** 2026-07-05 · Related: [2026-07-03-firmware-upstream-rebase-plan.md](2026-07-03-firmware-upstream-rebase-plan.md)
|
|
|
|
## Goal
|
|
|
|
Host pm3py and its Proxmark3 firmware fork on the DT Gitea, customize the firmware,
|
|
and pull RRG (`RfidResearchGroup/proxmark3`) updates **without ever touching the RRG
|
|
version** — via the standard **rebase-fork** model.
|
|
|
|
## The model
|
|
|
|
One firmware repo, `<dt-org>/proxmark3`, with a strict branch split:
|
|
|
|
| Branch | Role |
|
|
|--------|------|
|
|
| `master` | **pristine RRG mirror** — only ever fast-forwarded from `upstream`, never our commits |
|
|
| `pm3py` | our customizations (atomic single-file commits) on top of `master`; the submodule pins this |
|
|
|
|
Remotes: `origin` = `<dt-org>/proxmark3` (SSH), `upstream` = RRG (already configured).
|
|
pm3py itself moves to `<dt-org>/pm3py`; its `.gitmodules` points at the `pm3py` branch.
|
|
|
|
Why rebase-fork (not merge / subtree / quilt): our ~33 patches already *are* a hand-managed
|
|
atomic-commit patch queue; rebase is the native git form. It keeps `git diff master..pm3py`
|
|
a clean picture of exactly our changes, and resolves the recurring `iso15693.c` conflict
|
|
(24/33 commits touch it) **once** per update instead of on every merge.
|
|
|
|
## The three real gotchas (all handled)
|
|
|
|
1. **Gitlink must be published or fresh clones dangle.** The firmware `pm3py` tip must be
|
|
pushed *before* pm3py's gitlink references it (Phase 6 before 7).
|
|
2. **The uncommitted EML host-poll change is in no ref** — it would be silently lost on any
|
|
checkout/reclone. Backed up (`scratchpad/eml-hostpoll.patch`) and committed on `pm3py`
|
|
in Phase 5.
|
|
3. **Our history is intermixed with upstream merges** — `merge-base(main, upstream/master)`
|
|
is only 11 commits below HEAD, so 48 of our 59 commits sit *below* it in the upstream DAG.
|
|
A naive `rebase --onto master $MB pm3py` would carry only the top 11 and **drop 48**. So
|
|
the migration does **not** rebase — it mirrors everything verbatim and defers the clean
|
|
split to the first upstream pull (see Ongoing).
|
|
|
|
## Migration runbook (no rewrite, no data loss)
|
|
|
|
Split by **who**: `[A]` = I do it locally (offline); `[U]` = you run it (Gitea web / pushes,
|
|
since my sandbox can't reach `:20022`).
|
|
|
|
- **Phase 0 [A] — safety net:** back up the EML diff (done); tag every must-preserve head
|
|
`bak/<name>`; `git bundle create --all` for both repos.
|
|
- **Phase 1 [U] — create EMPTY DT repos** `<dt-org>/proxmark3` and `<dt-org>/pm3py` (no
|
|
README/license — a first commit blocks a mirror push).
|
|
- **Phase 2 [A] — materialize local heads:** `git branch pm3py main` (verbatim), and local
|
|
branches for the 6 feature branches. No rebase.
|
|
- **Phase 3 [U] — mirror-push firmware:** `git fetch upstream master` then
|
|
`git push --mirror ssh://git@git.dngr.us:20022/<dt-org>/proxmark3.git` (safe: target empty).
|
|
- **Phase 4 [U] — seed `master`:** `git push <dt> refs/remotes/upstream/master:refs/heads/master`.
|
|
- **Phase 5 [A] — commit EML on `pm3py`, repoint config, bump gitlink:** commit the EML
|
|
host-poll; rename firmware `origin`→`mikefaith-backup`, add DT `origin`; set `.gitmodules`
|
|
`url`=DT SSH + `branch=pm3py`, `submodule sync`; `git add .gitmodules firmware` + commit.
|
|
- **Phase 6 [U] — publish the firmware tip (CRITICAL):** `git push origin pm3py`.
|
|
- **Phase 7 [U] — mirror-push pm3py + repoint origin** to `<dt-org>/pm3py`.
|
|
- **Phase 8 [U] — VERIFY** a fresh `git clone --recurse-submodules` of `<dt-org>/pm3py`:
|
|
submodule resolves (no "reference is not a tree"), `make PLATFORM=PM3GENERIC` + `pytest`
|
|
pass, then a hardware smoke test.
|
|
- **Phase 9 [U] — retire old repos** (ARCHIVE read-only, never delete) only after Phase 8.
|
|
|
|
Rollback at any point: nothing is rewritten/deleted, so `git remote rename mikefaith-backup
|
|
origin` restores the pre-migration state; the old repos and the Phase-0 bundles are the
|
|
backstop until Phase 8 passes.
|
|
|
|
## Ongoing: pull RRG updates without impacting RRG
|
|
|
|
```
|
|
git -C firmware fetch upstream master
|
|
git -C firmware push origin refs/remotes/upstream/master:refs/heads/master # ff-only, pristine
|
|
# rebase our patches onto the new base in an isolated worktree, build+test, then:
|
|
git -C firmware push origin rebase-wip:pm3py --force-with-lease # only our branch, leased
|
|
cd <pm3py> && git add firmware && git commit -m "chore(firmware): rebase onto RRG <tip>, bump gitlink"
|
|
```
|
|
`master` is append-only (never rewritten); only `pm3py` is force-pushed, always with a lease.
|
|
The **first** pull also does the deferred clean split: enumerate our commits
|
|
(`git log --author=michael --author=dangerous-tac0s upstream/master..pm3py`), skip
|
|
already-upstreamed ones (hf-mfu-esetblk PR #3404), and rebuild `pm3py` as an explicit
|
|
patch series onto fresh `master` — validate `git diff <rebuilt> pm3py` shows only deltas
|
|
upstream lacks. Later pulls are the simple linear `rebase --onto` case. See the 2026-07-03
|
|
plan for the per-file conflict detail (`iso15693.c` hot spot).
|
|
|
|
## Inputs needed from you
|
|
|
|
- The **DT org name** on git.dngr.us (substitutes `<dt-org>`).
|
|
- Fork default branch: recommend `master` (matches RRG).
|
|
- Confirm your SSH key has write in the `<dt-org>` namespace.
|
|
|
|
## Provenance
|
|
|
|
Multi-agent workflow (strategy eval + state audit + topology design → synthesized runbook).
|
|
The adversarial data-loss verify pass was cut short by a rate limit; the mirror-to-empty-repo
|
|
safety, publish-before-reference ordering, and EML backup were re-checked by hand.
|