Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Git sync

Git sync exports a project’s files to a branch of a git repository on GitHub, GitLab or any host that accepts SSH deploy keys. Agrafe pushes to the repository; it reads from it only when you import its files, on connecting or to resolve a divergence.

The settings are at the bottom of the Package pane (the Package button at the bottom of the sidebar), in the Git sync section. The server must have git sync enabled; if it is not, connecting answers “git sync is not available on this server”, followed by the reason in brackets (for example git: spawn failed: No such file or directory (os error 2); ssh: ok when the host has no git package).

Git sync requires the project owner’s plan to be Pro or Enterprise (a collaborator’s plan does not count). After a downgrade the sync is paused, with the connection and its history kept; it resumes on its own once the owner upgrades again.

How it works

  • A branch owned by Agrafe. Agrafe pushes to one branch, agrafe by default. Nobody else should commit to it: people merge it into their own branches through pull or merge requests.
  • Autosaves. While you edit, Agrafe records snapshots of the project locally, after 30 seconds without a save or at the latest 5 minutes after the first unsaved change. Autosaves are never pushed.
  • Checkpoints. A checkpoint squashes the autosaves into one commit with your message and pushes it. The branch history is one commit per checkpoint.
  • Releases. Creating a release adds an annotated tag v<version> and pushes it when the sync can push. A failed tag never fails the release; the reason shows as the last error.

What the repository contains

Under the connection’s path prefix (the repository root by default):

  • every project file at its path, folders included (models/person.dlf is in a models folder), package.dlf included;
  • the import locks, one folder .dolfin/imports/<import>/ per locked import, the same files as Export as zip writes (see Import locks on disk).

A clone of the branch therefore passes radeau check offline, as long as every import is locked.

Connecting a repository

Only the project owner can connect. Fill in:

FieldContent
Remote URLThe repository’s SSH URL, such as git@github.com:org/repo.git. An https:// URL is refused: Agrafe pushes with an SSH deploy key.
BranchThe branch Agrafe pushes to. Default agrafe.
Path prefixOptional folder of the repository the files go in, such as ontology/hr.

Connect creates a deploy key for this project and shows its public half. The private key is stored encrypted on the server and is never shown. Add the public key on the host as a deploy key with write access:

HostWhere
GitHubRepository Settings → Deploy keys → Add deploy key. Paste the key and tick Allow write access.
GitLabProject Settings → Repository → Deploy keys → Add new key. Paste the key and tick Grant write permissions to this key.
Other hostsAn SSH deploy key, or the SSH key of a bot account, with push access to this repository only.

The section opens the instructions of the host it recognises in the URL; the tabs show the others. Copy puts the key on the clipboard.

Branch warning

If the branch is main or master, the section warns that it looks like the repository’s main branch. Connecting is allowed, but every commit made on that branch outside Agrafe stops the sync as Diverged. Prefer a dedicated branch.

Test connection

Test connection checks that Agrafe can reach the repository with the deploy key (git ls-remote), without pushing. A successful test does not lift Paused or Diverged.

The SSH host keys of GitHub and GitLab.com are built in. For any other host, the first test records the host’s key, and pushes are refused until it has: run Test connection once after adding the deploy key. The recorded key is never replaced, so a host that later presents another key is refused.

Importing from the repository

When the connection works and nothing was pushed yet, Test connection also looks at the branch. If it already exists, the section lists what an import would bring before anything is written:

  • the .dlf files under the path prefix, in their folders;
  • the import locks under .dolfin/imports/ (see Import locks on disk);
  • the skipped entries, each with its reason: files that are not .dlf (a README.md), files over 5 MiB, names a project file cannot have (such as .hidden.dlf or docs/.hidden.dlf), and content that is not UTF-8 text.

Two buttons follow (owner only):

  • Import into this project, offered only while the project has no file but its package.dlf. The files are written as if you saved them, so each one gets a version in its history; the remote package.dlf replaces the default one.
  • Create a new project from the repository creates a project of yours, named after the repository, imports the branch there and opens it. The connection, with its deploy key, moves to the new project: the current project is disconnected, since both cannot push to one branch. Your usual project and file limits apply.

An import is all or nothing: an import lock whose files do not match its lock.json stops it before any file is written. After an import, the branch counts as pushed: the next checkpoint only commits what you change. A checkpoint writes the branch’s whole content, so files that were skipped disappear from it; keep the branch for Agrafe.

If you do not import, the first checkpoint stops as Diverged (the branch has commits Agrafe did not make).

Status

The section shows the status, the remote, the branch, the time of the last push attempt and the last error. A small branch icon next to the project name in the top bar shows the same status, in the status’s colour, with the status, the unpushed changes and the last error in its tooltip. Click it to open the Git sync section. The icon is absent when the project is not connected. It refreshes every minute and after each action.

StatusMeaning
OKThe last push or test succeeded.
Waiting for a deploy keyThe connection has no deploy key.
DivergedThe remote branch has commits Agrafe did not make. Pushes stop until you resolve it, see below.
Authentication failedThe host refused the key: it is missing, read-only or revoked.
Remote unreachableThe host could not be reached. Agrafe retries, waiting longer after each failure (up to 15 minutes).
Push rejectedThe host refused the push, for example a protected branch or a server hook.
PausedPushes are paused.

Under the table, the section counts the unpushed changes: the files added, modified or deleted since the last pushed checkpoint, and the autosaves taken since. Show files lists them. A checkpoint that was committed but not pushed yet is mentioned too.

Checkpoint, pause, disconnect

  • Checkpoint… asks for a message (at most 1000 characters), commits and pushes. If nothing changed, nothing is committed. While the sync is paused, waiting for a key or diverged, the checkpoint is committed but not pushed; the next checkpoint pushes it.
  • The History tab of a connected project also has a commit box, above the files changed since the last pushed commit, grouped by file.
  • Pause stops pushes. Autosaves go on locally. Resume restarts them.
  • Disconnect asks for confirmation, then deletes the connection, its deploy key and Agrafe’s copy of the repository. The repository on the host is not changed; remove the deploy key there yourself.

Resolving a divergence

When the status is Diverged, three buttons appear:

  • Take remote version asks for confirmation, then makes the project’s .dlf files and import locks those of the remote branch, as an import does: files are updated or created, and the .dlf files the branch lacks are deleted (package.dlf is kept). Your local changes stay in the files’ version history. The status goes back to OK, and the next checkpoint builds on the remote branch.
  • Overwrite remote branch asks for confirmation, then force-pushes Agrafe’s last checkpoint over the remote branch. The commits made on that branch outside Agrafe are lost from it. Checkpoint first if there is no checkpoint yet.
  • Switch to new branch keeps the remote branch as it is and moves the sync to a new one: agrafe-2, then agrafe-3, skipping the names the remote already has. The next checkpoint pushes there.

Import locks

A project whose package.dlf imports other ontologies exports their locks with the files. The section warns in two cases:

  • an import line has no lock (it failed to resolve, or a release must be picked): the repository gets no .dolfin/imports/ files for it. Fix the line in the Imports field of the Package pane; the next checkpoint exports the lock.
  • lock files changed since the last checkpoint: they reach the repository with the next checkpoint.

Limits and audit

When Agrafe reads a repository (to import from it or take its version), it fetches only the branch’s last commit, and refuses or skips what is too big:

LimitValueOver it
Size of the fetched data50 MiBThe fetch stops and nothing is kept.
Entries under the path prefix1000Refused, nothing is kept.
Size of one file5 MiB, as for a data file in a projectThe file is skipped and listed.

Agrafe’s copy of the repository is compacted from time to time after pushes (git gc --auto).

Connecting, disconnecting, overwriting the remote branch and importing are recorded in the server’s audit log, with the project, the user and the branch or commit. The remote URL and the deploy key are never recorded.

Who can do what

OwnerEditorViewer
See the status✓✓✓
Checkpoint, pause, resume✓✓
Connect, test, disconnect✓
Take remote version✓✓
Import from the repository✓
Overwrite remote branch, switch to new branch✓

The buttons you cannot use are hidden. Taking the remote version edits the project, so an editor needs the Pro plan that editing a shared project needs.