merge
Folds another vault into this one — for two copies that drifted apart on different machines.
sefy merge <FILE> [OPTIONS]| Option | Meaning |
|---|---|
--other-password-env <VAR> |
Read the other vault’s password from this variable. |
$ sefy merge ~/from-laptop.bakPassword for /home/you/from-laptop.bak:merged: 1 added, 1 updated, 1 unchanged; 2 earlier versions brought acrossThe 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.
What it does, item by item
Section titled “What it does, item by item”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.
When both sides changed
Section titled “When both sides changed”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:
$ sefy merge ~/from-laptop.bakmerged: 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 2Compare 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.
$ 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.
Nothing is ever deleted
Section titled “Nothing is ever deleted”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.
Items older than identities
Section titled “Items older than identities”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.
Why this exists
Section titled “Why this exists”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.
Related
Section titled “Related”- Moving a vault between machines — how copies drift in the first place
import— bringing in contents from a plain JSON exporthistory— where a conflict ends uprestore— choosing the other side after all- Versions and compatibility — what a merge leaves where it is