Skip to content

0.6.1

Choose a tag to compare

@github-actions github-actions released this 07 Aug 15:48
· 15 commits to main since this release

Update notes 0.6.1

Requires a Termux runner update (v9 → v11). Open the companion app and tap Update runner, or re-run the install command from the plugin settings. Nothing needs re-pairing: profiles and tokens are untouched.

0.6.0 was prepared but never published, so this release carries it too.

Several repositories on one device

Each vault gets its own profile and its own token (profiles/<id>.conf); an existing single-repository config migrates itself. One runner drains every profile, oldest request first, and git is pinned per profile with GIT_CEILING_DIRECTORIES and a toplevel check, so a vault nested inside another repository can never leak into it — the outer repository excludes it locally instead. A vault that moved is found again by its profile marker, a new one pairs itself, and a dead profile answers REPO_MISSING rather than failing silently.

A vault's repository, from nothing

Settings → Repository for this vault → Set up repository, also in the setup guide and the palette. It reads what the vault actually is and offers only the steps that apply: create a repository here, add or change the remote, clone an existing one, or re-clone a broken one. Creating and cloning are also palette commands of their own, so you can go straight to the one you mean.

A vault that is not a repository yet can be paired before it has one, so none of this needs a terminal. Until a repository exists, that profile answers only the actions that create one.

Cloning into a vault that already has files

A vault always holds at least .obsidian/, which a plain git clone refuses, and this is where other tools ask you to delete your configuration. Here nothing you already have is written over: the repository is cloned without a checkout and moved in, its tree goes into the index leaving the working tree alone, and only files the vault does not have are written out. You end up with a complete checkout plus your own versions of the overlapping files, listed as ordinary local changes — open each one, read the diff, then commit to keep yours or discard to take the repository's.

"Create a repository, then point it at my existing remote" lands in exactly the same place as cloning: same commit, branch, upstream and files. If both sides have a history, the plugin says so at once instead of letting refusing to merge unrelated histories surprise you later. A remote whose HEAD names a branch it does not have is handled too — plain git clone gives up there; the runner picks a branch and sets its upstream.

Re-cloning only replaces anything after the new clone succeeds, and the old repository is set aside, not deleted: full history, still a valid git directory, so you can attach it as a remote and cherry-pick from it. Because that copy is invisible and can be large, the plugin mentions it once a day with its size and three answers, one of which is "stop reminding me about this one".

Installing and updating without a network

The Termux scripts are now inside the plugin folder, so a device that has the plugin has everything needed to install or update the runner:

bash "<vault>/.obsidian/plugins/native-git-bridge/termux/bootstrap.sh" "<vault>"

Nothing to download, no version to pass, nothing that depends on GitHub being reachable. NGB_BASE_URL accepts a plain directory path or a file:// URL as well as https://. When the plugin arrives through vault sync the matching runner arrives with it, so the version handshake can be satisfied without a release at all.

Remote URLs

Validated identically in the plugin and in the runner, passed to git as an argv element, redacted in every log and result. Accepted: https://, ssh://, git@host:owner/repo.git, file:///absolute/path. Refused: anything starting with -, plain http://, git://, ext::…, whitespace, non-ASCII, and any URL carrying a password — a secret must never reach a request file inside the vault.

Getting out of states that had no way out

Two of these were reported from a real device, and neither could be escaped without opening Termux.

A protected sparse path stuck in the index. Stage a file, then add its directory to the sparse exclusions: the reapply takes the file off disk and leaves the index entry behind. Because sparse checkout sets skip-worktree, git stops looking at the worktree and reports a bare A — the index says "added", and nothing says the file is gone. The safety gate blocked every commit, push and sync; the "delete these files" repair moved nothing, because there was no file; and unstaging was refused, because the path was protected.

The safety report now reads both status columns and says what it actually found, and the repair button names what it will do: Delete files locally, Remove from index, or Delete and unstage. Removing from the index is the one write permitted on a protected path, and only for paths the last commit does not contain — so it can undo a staged addition and can never turn into a deletion of committed content. Anything tracked in HEAD is still listed with a reason and left to you.

An unfinished merge with nothing left to resolve. Every pull answered "a merge is already in progress", the Conflicts group was empty because you had already resolved everything, and Abort merge lived only in that group's menu — so there was no way out at all. The status panel now shows a banner whenever a merge or rebase is unfinished, regardless of how many conflicts remain, with Commit merge (prefilled with git's own merge message) and Abort merge. A refresh no longer erases it. Unfinished rebases are recognised too, with Continue and Abort; nothing in the plugin starts a rebase, but one started in Termux used to be invisible here.

Panels

The status and history panels are now a fixed top, a scrolling list and a fixed bottom bar. On a phone the git buttons sit in the bottom bar within thumb reach and the branch state stays on top; the merge banner sits under the branch line where it cannot be scrolled past. The history panel uses the same shell, so refresh and the layout toggle are in the same corners as the status panel's, and each panel has a button that opens the other. Scroll position survives a refresh, so the auto-refresh timer no longer throws you back to the top mid-scroll.

Termux installer output

The installer no longer wraps its own text at a fixed width. On a phone that wrapped a second time at the terminal edge, in the middle of words. Every message is now folded to the width the terminal actually reports, breaking on spaces, and lines meant to be copied — commands, the pairing token, paths — are printed whole.

Internals

Runner v11 adds init-repo, set-remote, clone-into-vault, adopt-remote, unstage-protected, abort-rebase, continue-rebase, the REPO_EXISTS error, the bootstrap profile state and rebaseInProgress in status. 353 unit tests, 408 e2e checks against real repositories, including the sparse-index state above end to end and both exits from an unfinished rebase.

Full Changelog: 0.6.0...0.6.1