Skip to content

merge

Folds another vault into this one — for two copies that drifted apart on different machines.

Terminal window
sefy merge <FILE> [OPTIONS]
Option Meaning
--other-password-env <VAR> Read the other vault’s password from this variable.
Terminal window
$ sefy merge ~/from-laptop.bak
Password for /home/you/from-laptop.bak:
merged: 1 added, 1 updated, 1 unchanged; 2 earlier versions brought across

The other vault’s password is asked for separately, because a copy from another machine may well be under a different one. --other-password-env is the script form; the global --password-env still carries this vault’s own password.

The other file is only ever read. Everything happens in this vault, which is saved once at the end.

Items are matched on the identity each one carries — not on its title, since two accounts can share a name and renaming an item must not turn it into a different one.

On the other side Here Result
present missing copied across, with its identity, dates and history
present the same contents left alone
a version this side has been past moved on left alone
moved on a version the other side has been past the other side’s contents become current
moved on moved on too a conflict — see below
missing present left alone

Contents are settled by their versions, not by the clock. Each side knows which versions its contents have been through, so “the other copy is simply behind” and “both copies changed” can be told apart — and only the second is a conflict. Whatever contents an item leaves behind become a version in its history; nothing is overwritten.

Earlier versions travel too. A merge brings across every version the other side has and this one does not, each kept once however many times it arrives — so two machines that sync end up with the same history.

Titles and tags are labels, not contents: for them the side changed more recently wins, and that never counts as a conflict.

The interesting case. If an item’s contents changed here and there since the copies parted, the copy changed more recently becomes current — on a tie, this one — and the other is kept in the item’s history, marked as having lost a conflict:

Terminal window
$ sefy merge ~/from-laptop.bak
merged: 0 added, 0 updated, 3 unchanged
1 item changed on both sides.
The copy changed more recently is current; the other is kept in the item's history:
"mail" (the other copy's is current): sefy history 2
Compare with sefy history ID VERSION; bring one back with sefy restore ID VERSION.

Nothing is thrown away, and nothing is added to the list: there is still one mail, and the version that lost is one line in its history, with the machine it was written on.

Terminal window
$ sefy history mail
"mail" (login), 3 versions
1 2026-08-02 09:14 UTC desk created
2 2026-09-20 08:01 UTC desk password (lost a merge conflict)
3 2026-09-20 08:03 UTC laptop password (current)

“Newest wins” is a fine rule for a title and a ruinous one for a password: the older copy may be the one that still opens the account. That is why the loser is kept, and why restore brings it back — whole, or just the password.

Once settled on one machine, a conflict does not come back on the other: the version it lost to arrives there with the history, and that machine is simply behind.

An item that exists here but not in the other vault stays. A merge cannot tell “deleted over there” from “added over here” — from this side the two look identical — and guessing wrong would destroy a secret silently.

So removals do not propagate. Remove an item in both places, or accept that a merge will bring it back from a copy that still has it.

Identities arrived in sefy 0.2.0. An item created by 0.1.x is given one the first time this build opens the vault — and if two copies of that vault were each opened separately, each gave it a different identity.

There is no way around it: the copies genuinely carry no common mark from before. Merging them treats such an item as two, and you remove the one you do not want. It only affects items that predate 0.2.0 in vaults that had already drifted; anything created since travels correctly.

Nothing in a vault file can warn you that two copies drifted: the format carries no header, no timestamp and no counter in the clear, because any of those would be the signature it deliberately avoids. There is no locking either — two machines saving the same file means the second save wins whole.

merge is the answer to that, applied afterwards with both passwords in hand.