borg/docs/usage
Kazuki Kanda 57538db831
known-repos: new command to list locally known repositories, fixes #10453
* known-repos: new command to list locally known repositories

Lists repositories this local Borg installation has state for (security
info and/or a local cache) without accessing any repository, local or
remote. Scans both the current borg2 security/cache directories and,
separately, the legacy borg 1.x security/cache directories (which can be
different default locations, e.g. on macOS).

Does not follow symlinks anywhere in the scanned trees (repo-id
directories, or the location/key-type files inside them), since borg
only ever writes plain directories and regular files there.

Key-type labels are derived from the key classes themselves
(LEGACY_KEY_TYPES + AVAILABLE_KEY_TYPES), matching how "borg repo-info"
names crypto suites, rather than a separately hand-maintained table.

dir_size() pushes each directory handle (root, and any subdirectory
opened while walking the cache tree) onto its explicit stack before
calling list_names() on it, not after, so cleanup can always close it
even if list_names() raises something other than OSError (it only
catches OSError itself) - e.g. KeyboardInterrupt. Covered by two unit
tests that monkeypatch list_names() to raise and then check the fd via
os.fstat().

has_cache and has_security_info are tri-state (True/False/None, not a
plain bool): an inspection failure (e.g. EACCES on a repo-id directory,
or on the security/cache root itself, including a root that opens but
fails during its own listing) is reported as unknown rather than being
collapsed into a false "no". A repo-id directory that could be listed
but not opened/classified is still included in the results with its
fields set to unknown, instead of silently disappearing from the
output. The JSON/text field for which state-directory layout a
repository was discovered under is named "layout" (values "borg2" /
"legacy" / null), not "version", so it cannot be confused with Borg's
actual repository format version (see "borg repo-info").

Adds docs/usage/known-repos.rst{,.inc} and the usage.rst toctree entry, and
the generated man page.

* known-repos: simplify after maintainer review, drop leftover defenses

Rewrite the scanner around ordinary OS file access instead of extra
symlink/size defenses, collapse duplicated scan/table/test logic, and
surface real inspection failures (ENOTDIR, unparseable cache config)
instead of treating them as absence.

Also forward create=False through legacy get_keys_dir(), refresh the
usage example, keep tests to the remaining behavioral surface, and
shorten a few overly verbose test docstrings.

* known-repos: fix black formatting, restore generated usage/man docs

black wants the process_epilog("""...""") call's opening triple-quote on
its own line and the closing paren on a separate line.

docs/usage/known-repos.rst still includes known-repos.rst.inc, which a
previous commit deleted along with the generated man page - this broke
the docs build (InputError: no such file). Regenerate both with
scripts/make.py build_usage/build_man, following the convention other
recently added commands (copy, find) already use.

* known-repos: address second-review minor points

- location_mismatch now compares the security location and cache
  previous_location through normalize_local_path(), the same way
  assert_location_matches() does, so an NFC vs. NFD unicode-form
  difference alone isn't flagged as a mismatch on macOS (#2913).
  Added a regression test for it.
- The table no longer truncates the repository id to 15 chars - users
  acting on an entry (e.g. removing a stale cache dir) need the full id.
  Strengthened the existing test assertion to match. Updated the
  epilog and the usage example accordingly (full id was previously
  JSON-only), and regenerated docs/usage/known-repos.rst.inc and
  docs/man/borg-known-repos.1 to match.
- legacy/fs.py: dropped the "(and now also the known-repos command)"
  historical phrasing from the module docstring; the following
  paragraph already lists both callers.
- Epilog: mentioned that a security-only repo gets layout "unknown"
  when BORG_SECURITY_DIR makes the borg2 and legacy security roots
  coincide. Thomas noted the behavior itself is fine either way, just
  worth a brief mention.

* known-repos: address PyPy msgpack warning and Windows encoding failures

Fixes two CI failures reported in maintainer follow-up review:

- PyPy: test_known_repos_without_repo_argument and
  test_known_repos_multiple_sorted_by_id failed with JSONDecodeError
  because pure-python msgpack emits PURE_PYTHON_MSGPACK_WARNING on PyPy,
  which contaminated exec_cmd() output. Introduce cmd_without_repo()
  helper that filters the warning line identically to cmd() while avoiding
  --repo injection, as suggested.
- Windows: test_known_repos_location_mismatch_ignores_nfc_nfd_difference
  crashed with UnicodeEncodeError writing NFD path in cp1252. Skip the NFD
  test on Windows, as suggested.
- Windows/scanner: read state files using default locale encoding matching
  borg's SaveFile/SyncFile implementation, dropping explicit encoding="utf-8",
  as suggested.

* known-repos: use security location mtime + cache newest-file mtime for last_written

PR #10497 (sealed files cache) removed CacheConfig.save(), so on
current master the borg2 cache config file's mtime stays at cache
creation time and no longer tracks last use.

last_written is now the newer of:
- the security location file's mtime (rewritten by Cache.close() via
  security_manager.save() on every run; also gives security-only
  repos a value)
- the newest mtime of the regular files below the cache dir, tracked
  during the existing cache_stats() walk that already computes size

The JSON field is renamed from cache_config_mtime to last_written.
Epilog/docs/man page say where the timestamp comes from and say
"regular file" to match what the code tracks. The long run-on epilog
sentence is split into shorter sentences.

Tests assert which source wins (location-newer, cache-newer including
a nested file) and the cache-only case now checks the exact mtime
instead of only non-null.
2026-11-01 18:21:55 +01:00
..
general locking: BORG_LOCK_RECHECK_DELAY sets the race recheck delay, fixes #9899 2026-10-05 23:04:09 +02:00
analyze.rst docs: add borg analyze usage examples with real output 2026-10-13 17:52:24 +02:00
analyze.rst.inc build_usage build_man 2026-09-02 21:39:09 +02:00
benchmark.rst docs: usage: add benchmark cpu and key change-location 2022-03-26 23:40:03 +01:00
benchmark_cpu.rst.inc build_usage build_man 2026-09-02 21:39:09 +02:00
benchmark_crud.rst.inc build_man ; build_usage 2026-08-29 17:42:35 +02:00
break-lock.rst.inc build_usage build_man 2026-09-27 23:02:35 +02:00
check.rst docs: split usage 2017-06-07 00:38:48 +02:00
check.rst.inc build_usage build_man 2026-09-27 23:02:35 +02:00
common-options.rst.inc remove --debug-profile option, use BORG_DEBUG_PROFILE 2026-07-25 12:15:02 +02:00
compact.rst docs: fix broken examples and stale output samples in the usage docs 2026-08-28 12:48:17 +02:00
compact.rst.inc build_usage build_man 2026-09-27 23:02:35 +02:00
completion.rst completion: borg can now generate completion scripts for supported shells, fixes #9172 2025-11-17 18:47:00 +01:00
completion.rst.inc completion: complete the --sort-by fields of list and diff 2026-08-12 15:59:40 +02:00
copy.rst docs: use archive series names instead of borg 1.x style names 2026-10-13 19:16:18 +02:00
copy.rst.inc copy: new command to copy an archive to a new archive name, #2300 2026-08-28 06:30:19 +02:00
create.rst docs: use archive series names instead of borg 1.x style names 2026-10-13 19:16:18 +02:00
create.rst.inc build_usage build_man 2026-09-27 23:02:35 +02:00
debug.rst repository: single config/config text object replaces readme, version, id and manifest (repo version 5) 2026-09-18 00:28:33 +02:00
delete.rst docs: use archive series names instead of borg 1.x style names 2026-10-13 19:16:18 +02:00
delete.rst.inc build_man ; build_usage 2026-08-29 17:42:35 +02:00
diff.rst docs: fix broken examples and stale output samples in the usage docs 2026-08-28 12:48:17 +02:00
diff.rst.inc build_usage build_man 2026-09-27 23:02:35 +02:00
export-tar.rst.inc export-tar: support sparse files, fixes #2562 2026-08-18 13:36:10 +02:00
extract.rst extract: refuse to extract into a non-empty directory, fixes #10057 2026-09-19 14:30:09 +02:00
extract.rst.inc build_usage build_man 2026-09-27 23:02:35 +02:00
find.rst docs: fix broken examples and stale output samples in the usage docs 2026-08-28 12:48:17 +02:00
find.rst.inc build_man ; build_usage 2026-08-29 17:42:35 +02:00
general.rst docs: fix broken examples and stale output samples in the usage docs 2026-08-28 12:48:17 +02:00
help.rst docs: split usage 2017-06-07 00:38:48 +02:00
help.rst.inc build_usage build_man 2026-09-27 23:02:35 +02:00
import-tar.rst.inc build_usage build_man 2026-09-27 23:02:35 +02:00
info.rst docs: fix broken examples and stale output samples in the usage docs 2026-08-28 12:48:17 +02:00
info.rst.inc create/import-tar --json: report the deduplicated size of the new archive, #10335 2026-09-07 19:56:04 +02:00
key.rst introduce the store hash: one place defining the content hash of store objects 2026-09-15 21:01:06 +02:00
key_add.rst.inc docs: add docs for "key add", "key list" and "key remove" 2026-06-13 21:37:21 +02:00
key_change-location.rst.inc build usage / man 2026-06-16 14:17:43 +02:00
key_change-passphrase.rst.inc build_usage / build_man / doc updates 2022-06-25 21:58:19 +02:00
key_export.rst.inc build usage / man 2026-06-16 14:17:43 +02:00
key_import.rst.inc build_man ; build_usage 2026-08-29 17:42:35 +02:00
key_list.rst.inc docs: add docs for "key add", "key list" and "key remove" 2026-06-13 21:37:21 +02:00
key_remove.rst.inc docs: add docs for "key add", "key list" and "key remove" 2026-06-13 21:37:21 +02:00
known-repos.rst known-repos: new command to list locally known repositories, fixes #10453 2026-11-01 18:21:55 +01:00
known-repos.rst.inc known-repos: new command to list locally known repositories, fixes #10453 2026-11-01 18:21:55 +01:00
list.rst docs: use archive series names instead of borg 1.x style names 2026-10-13 19:16:18 +02:00
list.rst.inc build_man ; build_usage 2026-08-29 17:42:35 +02:00
lock.rst docs: split usage 2017-06-07 00:38:48 +02:00
mount.rst docs: use archive series names instead of borg 1.x style names 2026-10-13 19:16:18 +02:00
mount.rst.inc build_usage build_man 2026-09-27 23:02:35 +02:00
notes.rst docs: fix broken examples and stale output samples in the usage docs 2026-08-28 12:48:17 +02:00
prune.rst docs: use archive series names instead of borg 1.x style names 2026-10-13 19:16:18 +02:00
prune.rst.inc build_usage build_man 2026-09-02 21:39:09 +02:00
recreate.rst docs: fix broken examples and stale output samples in the usage docs 2026-08-28 12:48:17 +02:00
recreate.rst.inc build_usage build_man 2026-09-27 23:02:35 +02:00
rename.rst docs: update repo-list output samples to the current default format 2026-08-29 15:04:30 +02:00
rename.rst.inc build_usage build_man 2025-12-23 18:00:09 +01:00
repo-compress.rst re-add repo-compress, fixes #9663 2026-08-02 10:12:06 +02:00
repo-compress.rst.inc build_usage build_man 2026-09-27 23:02:35 +02:00
repo-create.rst remove the none-sha256 and none-blake3 encryption modes 2026-09-18 01:17:09 +02:00
repo-create.rst.inc build_usage build_man 2026-09-27 23:02:35 +02:00
repo-delete.rst docs: fix broken examples and stale output samples in the usage docs 2026-08-28 12:48:17 +02:00
repo-delete.rst.inc build_usage build_man 2026-09-27 23:02:35 +02:00
repo-info.rst repository: single config/config text object replaces readme, version, id and manifest (repo version 5) 2026-09-18 00:28:33 +02:00
repo-info.rst.inc build_usage / build_man 2025-04-21 21:08:42 +02:00
repo-list.rst docs: update repo-list output samples to the current default format 2026-08-29 15:04:30 +02:00
repo-list.rst.inc build_usage build_man 2026-09-02 21:39:09 +02:00
repo-space.rst docs: fix usage docs and references for repo-* commands 2024-09-08 18:06:26 +02:00
repo-space.rst.inc build_usage build_man 2026-03-15 14:37:50 +01:00
serve.rst docs: ssh:// repository URLs, #9765 2026-09-24 15:55:01 +02:00
serve.rst.inc build_usage build_man 2026-09-27 23:02:35 +02:00
tag.rst tag: set, add, remove tags 2024-10-02 23:52:39 +02:00
tag.rst.inc build_usage build_man 2026-09-27 23:02:35 +02:00
tar.rst docs: use archive series names instead of borg 1.x style names 2026-10-13 19:16:18 +02:00
transfer.rst docs: ssh:// repository URLs, #9765 2026-09-24 15:55:01 +02:00
transfer.rst.inc build_usage build_man 2026-09-27 23:02:35 +02:00
umount.rst.inc build_usage build_man 2025-12-23 18:00:09 +01:00
undelete.rst build_usage build_man 2024-11-16 20:14:16 +01:00
undelete.rst.inc build_man ; build_usage 2026-08-29 17:42:35 +02:00
usage_general.rst.inc add support for yaml config files, default config 2026-03-10 18:36:30 +01:00
version.rst scripts/gendocs.py: make it work 2024-02-09 17:37:38 +01:00
version.rst.inc build_usage build_man 2026-09-27 23:02:35 +02:00
webdav.rst webdav: address review comments 2026-07-26 15:48:31 +02:00
webdav.rst.inc mount/webdav: BORG_MOUNT_ARCHIVE_DIR_FORMAT names the archive directories, fixes #9991 2026-08-21 17:31:42 +02:00
with-lock.rst.inc with-lock: fix epilog about leftover lock auto-removal, see #9870 2026-08-14 12:23:11 +02:00