Skip to content

Withdraw a source from Repozytorium Dzieł

Nerthus.Core (until cutover). This page describes the frozen system that runs today and is deleted at cutover. Replaced by: not yet written.

An owner has withdrawn consent for their work, and withdrawing means forgotten rather than merely unpublished. This page removes the directory, rewrites the history that held it, and puts every consumer back on a tree that never had it.

You are in this situation when

An owner named in a source's INDEX.md @zgoda line asks for their work to be removed. That is the whole trigger: the promise is theirs to call in, and no one else decides whether it was serious.

Two cases, and the second is the common one:

  • A whole source. nocarze.org belongs to MD. Withdrawing it removes nocarze.org/.
  • One author inside a source. prace-magiczne/ holds one directory per author precisely because the rights sit with each author. Withdrawing one removes prace-magiczne/<author>/ and leaves the other thirty-two alone.

If the request is "stop showing it" rather than "forget it", you do not need this page. Deleting the directory in an ordinary commit unpublishes the work: the daemon indexes HEAD, so the content leaves every search and every file read at the next converge. This page is for the stronger promise, and it is a history rewrite.

What it costs, before you start

A rewrite changes every commit id from the withdrawn content's first appearance onward. Anyone holding a clone of repozytorium-dziel has a history that no longer matches, and the fleet hosts are exactly that. Budget a converge wave, and tell the Rada before rather than after.

Nothing outside this repository moves. The lore repository is untouched, its history is never rewritten, and this is the reason the works live in a repository of their own.

Steps

  1. Record what you are about to do. In the source's INDEX.md, note the withdrawal and its date. That file is removed with the directory when a whole source goes, and it survives when one author goes — either way, the merge request carries the reason.

  2. Take the annotations with the content. nerthus.lang/ inside this repository holds one sidecar per indexed document, named after the document's path with / folded to _ and .json appended — so nocarze.org/content/opowiesc.md annotates to nerthus.lang/nocarze.org_content_opowiesc.md.json. List them before you delete:

    git -C repozytorium-dziel ls-files 'nerthus.lang/nocarze.org*'
    

    A sidecar left behind is the withdrawn text's lemmas and name spans, which is the content in a different shape.

  3. Rewrite the history. git filter-repo is a separate install (pipx install git-filter-repo), and it wants a fresh clone — it refuses to run where the working copy has other work in it:

    git clone git@gitlab.com:margonem/nerthus/it/repozytorium-dziel.git dziel-rewrite
    cd dziel-rewrite
    git filter-repo --invert-paths \
        --path 'nocarze.org/' \
        --path-glob 'nerthus.lang/nocarze.org*'
    

    For one author, the two paths are prace-magiczne/<author>/ and nerthus.lang/prace-magiczne_<author>*. --invert-paths keeps everything that is not named; the tool rewrites every commit that touched those paths and drops the ones left empty.

  4. Check that it is gone before you push. Two probes, and both must come back empty:

    git log --all --oneline -- 'nocarze.org/'
    git grep -I '<a phrase only that work uses>' $(git rev-list --all) | head
    

    The first says no commit touches the path any more. The second is the one that matters: it searches every blob in every remaining commit, so it catches a copy of the text that lived somewhere else under a different name.

  5. Push the rewritten history. It is a force-push onto a protected branch, so unprotect main, push, and protect it again:

    git push --force origin main
    
  6. Expire what the server still holds. A force-push leaves the old objects reachable through GitLab's own reflog and any open merge request. Close every merge request that touched the withdrawn path, delete every branch and tag that predates the rewrite, then ask GitLab to run housekeeping (Settings → General → Advanced → Run housekeeping). Until that runs, the objects are still fetchable by id.

  7. Rebuild every consumer. Each host holding this repository:

    git -C /srv/nerthus/dziel fetch origin
    git -C /srv/nerthus/dziel reset --hard origin/main
    

    A git pull will not do it — the histories have diverged and a merge would bring the content back.

You are out of it when

  • git log --all -- '<path>' is empty in a fresh clone, and so is the git grep over git rev-list --all.
  • Every fleet host reports the same commit for this repository, and none of them reports ahead.
  • GET /search?q=<phrase>&scope=external returns nothing for a token holding external.read, on every host. The external index is stamped on the works tree's digest, so a host that has reset finds its cached index stale and rebuilds it; a host still answering with the withdrawn text has not reset yet.
  • GET /files?path=Dzieła no longer lists the directory.

When the rewrite will not do

git filter-repo needs the content to be identifiable by path. If a withdrawn work was also pasted into some other source's markdown, the path filter misses it and step 4's git grep is what tells you. Remove the quoting file in the same rewrite, or the promise is not kept.

If the history is beyond untangling, the honest fallback is to recreate the project: a new empty repository, one commit holding the current tree minus the withdrawn work, and the old project deleted. It costs the whole history of every other source, which is why it is last — and it is available at all only because this content is quarantined here rather than in the lore repository.

  • The fleet — the converge loop the reset in step 7 puts each host back into
  • Recover a diverged host — for a host that does not come back into step after step 7