From cf529403af9a1542f6cf341cb173484fdb755424 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Tue, 12 Aug 2025 22:33:09 +0200 Subject: [PATCH 1/2] docs: fix typos and grammar --- README.rst | 20 ++++++++++---------- docs/authors.rst | 6 +++--- docs/changes.rst | 4 ++-- docs/faq.rst | 14 +++++++------- docs/index.rst | 2 +- docs/installation.rst | 15 +++++++-------- docs/quickstart.rst | 6 +++--- docs/support.rst | 18 ++++++++---------- docs/usage.rst | 13 +++++++------ 9 files changed, 48 insertions(+), 50 deletions(-) diff --git a/README.rst b/README.rst index 529b164..b1a44c4 100644 --- a/README.rst +++ b/README.rst @@ -5,15 +5,15 @@ borg-import converts backups made with other backup software into the format use See ``borg-import -h`` for more information. -Potential advantages over manually doing it +Potential advantages over doing it manually =========================================== -Note: we have different importers and some importers may not support all the features. +Note: There are different importers, and some may not support all features. -- automation: less manual work, import lots of backups into a borg repo with one command -- automatically makes up borg archive name from what you give + discovered timestamp -- sets borg archive creation timestamp to the historically correct date/time -- temporarily moves the source directory so the borg files cache will speed up borg create +- Automation: less manual work; import many backups into a Borg repository with one command. +- Automatically constructs the Borg archive name from the provided input and the discovered timestamp. +- Sets the Borg archive creation timestamp to the correct historical date and time. +- Temporarily moves the source directory so Borg's files cache can speed up ``borg create``. Currently supported import formats ================================== @@ -22,8 +22,8 @@ Currently supported import formats -------------------------------------------------- Imports archives from an existing Borg repository into a new one. -This is useful when a Borg repository needs to be rebuilt (e.g. if -your borg key and passphrase was compromised). +This is useful when a Borg repository needs to be rebuilt (e.g., if +your Borg key and passphrase were compromised). Usage: ``borg-import borg SOURCE_REPOSITORY DESTINATION_REPOSITORY`` @@ -48,7 +48,7 @@ See ``borg-import rsynchl -h`` for help. `rsync-time-backup `_ --------------------------------------------------------------------- -Similar to `rsynchl`, except with timestamp extraction optimized for `rsync-time-backup` folder names. +Similar to ``rsynchl``, except with timestamp extraction optimized for ``rsync-time-backup`` folder names. Usage: ``borg-import rsync_tmbackup --prefix=foo- RSYNC_ROOT BORG_REPOSITORY`` @@ -58,7 +58,7 @@ Backup tools based on rsync with hard links ------------------------------------------- borg-import should, in principle, be able to import backups from any backup tool that is -based on rsync with hard links. This requires that the tool matches the assumptions listed above for simple +based on rsync with hard links, provided the tool matches the assumptions listed above for simple rsync. * `backintime `_ diff --git a/docs/authors.rst b/docs/authors.rst index 038e2ef..b47b17e 100644 --- a/docs/authors.rst +++ b/docs/authors.rst @@ -1,8 +1,8 @@ .. include:: global.rst.inc -================= -Authors & License -================= +=================== +Authors and License +=================== .. include:: ../AUTHORS diff --git a/docs/changes.rst b/docs/changes.rst index 2ea4817..12fd84c 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -1,8 +1,8 @@ Changelog ========= -Version 0.1 (not released yet) ------------------------------- +Version 0.1 (unreleased) +------------------------ Bug fixes: diff --git a/docs/faq.rst b/docs/faq.rst index 0f34e68..9e6789b 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -2,15 +2,15 @@ .. highlight:: none .. _faq: -Frequently asked questions +Frequently Asked Questions ========================== My old backup program isn't officially supported. Can I still use borg-import? ------------------------------------------------------------------------------ -Chances are good that your old backup program is using some -kind of rsync+hardlinks mechanisms that will work with -Borg-Import's ``rsynchl`` mode. If you're unsure, try to find -out or ask how the program is organizing its backups. -Support for the software `Back In Time`_ was discovered by -simply trying it out. +It is likely that your old backup program uses an +rsync-with-hard-links mechanism that works with +borg-import's ``rsynchl`` mode. If you're unsure, try to find +out or ask how the program organizes its backups. +Support for `Back In Time`_ was discovered simply by +trying it. diff --git a/docs/index.rst b/docs/index.rst index b0d5cd2..20ccebd 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,6 +1,6 @@ .. include:: global.rst.inc -Borg-Import Documentation +borg-import Documentation ========================= .. include:: ../README.rst diff --git a/docs/installation.rst b/docs/installation.rst index 57630e7..688fcf5 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -5,28 +5,27 @@ Installation ============ -To install Borg-Import, you need `Python 3`_ and `pip`_ installed. You can then either `download borg-import directly +To install borg-import, you need `Python 3`_ and `pip`_ installed. You can then either `download borg-import directly `_ -or clone it from the `githubrepo`_. +or clone it from GitHub_. Extract the downloaded .zip if necessary. -Open a terminal in the borg-import directory and execute the following to install the program via pip: -:code:`pip install --user -e .` +Open a terminal in the borg-import directory and execute the following to install the program via pip: ``pip install --user -e .`` -If you have */home/user/.local/bin/* in your ``PATH`` variable, you can then start using Borg-Import. +If you have */home/user/.local/bin/* in your ``PATH`` variable, you can then start using borg-import. Otherwise, you will need to add *.local/bin/* to your ``PATH``. For Developers -------------- -If you're planning to contribute to Borg-Import, you should set up the development environment: +If you're planning to contribute to borg-import, you should set up the development environment: 1. Install development dependencies: - :code:`pip install -r requirements.d/development.txt` + ``pip install -r requirements.d/development.txt`` 2. Set up pre-commit hooks: - :code:`pre-commit install` + ``pre-commit install`` This will automatically run code formatting (black) and linting (flake8) checks before each commit. The pre-commit hooks will ensure your code follows the project's style guidelines. diff --git a/docs/quickstart.rst b/docs/quickstart.rst index 02fa2a2..4689249 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -2,7 +2,7 @@ .. highlight:: bash .. _quickstart: -Quick Start -=========== +Quickstart +========== -This chapter will get you started with Borg-Import. +This guide will get you started with borg-import. diff --git a/docs/support.rst b/docs/support.rst index 7e6ed49..4a14b3e 100644 --- a/docs/support.rst +++ b/docs/support.rst @@ -4,9 +4,7 @@ Support ======= -Please first read the docs, the existing issue tracker issues and mailing -list posts -- a lot of stuff is already documented / explained / discussed / -filed there. +Please read the documentation, existing issue-tracker issues, and mailing list posts first—much is already documented, explained, discussed, or filed there. Issue Tracker ------------- @@ -14,25 +12,25 @@ Issue Tracker If you've found a bug or have a concrete feature request, please create a new ticket on the project's `issue tracker`_. -For more general questions or discussions, IRC or mailing list are preferred. +For more general questions or discussions, IRC or the mailing list is preferred. Chat (IRC) ---------- Join us on channel #borgbackup on chat.freenode.net. -As usual on IRC, just ask or tell directly and then patiently wait for replies. +As is usual on IRC, ask your question and then wait patiently for replies. Stay connected. -You could use the following link (after connecting, you can change the random -nickname you get by typing "/nick mydesirednickname"): +You can use the following link (after connecting, you can change the random +nickname you get by typing ``/nick mydesirednickname``): http://webchat.freenode.net/?randomnick=1&channels=%23borgbackup&uio=MTY9dHJ1ZSY5PXRydWUa8 -Mailing list +Mailing List ------------ -To find out about the mailing list, its topic, how to subscribe, how to -unsubscribe and where you can find the archives of the list, see the +To learn about the mailing list, its topic, how to subscribe, how to +unsubscribe, and where to find the list archives, see the `mailing list homepage `_. diff --git a/docs/usage.rst b/docs/usage.rst index 307ca2e..92d11da 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -7,16 +7,17 @@ Usage ``borg-import`` consists of a number of commands, one for each backup system supported. Each accepts a number of arguments and -options. The following sections will describe each in detail. +options. The following sections describe each in detail. General ------- -Note that Borg-Import will ask you for your repo's passphrase -which blocks the import until you enter it. To let Borg-Import -continue automatically, you can pass the environment variable -*BORG_PASSPHRASE*: -:code:`BORG_PASSPHRASE=xxxxxx borg-import ....` +Note that borg-import will prompt for your repository passphrase, +which pauses the import until you enter it. To let borg-import +continue automatically, set the environment variable +BORG_PASSPHRASE: + +``BORG_PASSPHRASE=xxxxxx borg-import ...`` .. _rsnapshot: From ed2d574ed4bc61f22e2a558e24babefd9d9d1528 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Tue, 12 Aug 2025 23:10:04 +0200 Subject: [PATCH 2/2] code: fix typos and grammar --- src/borg_import/borg.py | 4 +-- src/borg_import/helpers/discover.py | 3 +- src/borg_import/helpers/names.py | 14 ++++----- .../helpers/testsuite/test_names.py | 2 +- .../helpers/testsuite/test_timestamps.py | 6 ++-- src/borg_import/helpers/timestamps.py | 31 +++++++++---------- src/borg_import/main.py | 14 ++++----- src/borg_import/rsnapshots.py | 2 +- src/borg_import/rsync_tmbackup.py | 10 +++--- src/borg_import/rsynchl.py | 2 +- src/borg_import/testsuite/test_borg.py | 2 +- 11 files changed, 45 insertions(+), 45 deletions(-) diff --git a/src/borg_import/borg.py b/src/borg_import/borg.py index afe23a7..40d7aef 100644 --- a/src/borg_import/borg.py +++ b/src/borg_import/borg.py @@ -4,8 +4,8 @@ def get_borg_archives(repository): - """Get all archive metadata discovered in the Borg repository.""" - # Get list of archives with their timestamps + """Return metadata for all archives discovered in the Borg repository.""" + # Get a list of archives with their timestamps borg_cmdline = ["borg", "list", "--format", "{name}{TAB}{time}{NL}", repository] output = subprocess.check_output(borg_cmdline).decode() diff --git a/src/borg_import/helpers/discover.py b/src/borg_import/helpers/discover.py index c7db21b..1940d66 100644 --- a/src/borg_import/helpers/discover.py +++ b/src/borg_import/helpers/discover.py @@ -4,7 +4,7 @@ def discover(root, depth): """ - recurse starting from path and yield relative dir paths with wanted . + Recurse from the given root path and yield relative directory paths at the specified depth. """ def _discover(root, current_dir, current_depth, wanted_depth): @@ -23,6 +23,7 @@ def _discover(root, current_dir, current_depth, wanted_depth): def parser(rel_path, regex): + """Parse rel_path with regex and return a dict of named groups, or None if no match.""" m = re.match(regex, rel_path) if m: return m.groupdict() diff --git a/src/borg_import/helpers/names.py b/src/borg_import/helpers/names.py index a6ec379..a7b2303 100644 --- a/src/borg_import/helpers/names.py +++ b/src/borg_import/helpers/names.py @@ -3,17 +3,17 @@ def make_name(*args, dt_format="%Y-%m-%dT%H:%M:%S"): """ - assemble borg archive names from components. + Assemble Borg archive names from components. - args can be anything that converts to str, plus: + Arguments can be anything that converts to str, plus: - bytes objects, which are safely decoded - datetime objects, which are formatted using dt_format - invalid chars are replaced or removed, so the resulting archive name + Invalid characters are replaced or removed, so the resulting archive name should be valid. - E.g.: + Examples: make_name(b'hostname', b'üser', 1) -> 'hostname-üser-1' @@ -28,12 +28,12 @@ def make_name(*args, dt_format="%Y-%m-%dT%H:%M:%S"): s = arg.strftime(dt_format) else: s = str(arg) - # we don't want to have blanks for practical shell-usage reasons: + # Avoid spaces for practical shell-usage reasons: s = s.replace(" ", "_") - # the slash is not allowed in archive names + # A slash is not allowed in archive names # (archive name = FUSE directory name) s = s.replace("/", "!") - # :: is repo::archive separator, not allowed in archive names + # "::" is the repo::archive separator, not allowed in archive names s = s.replace("::", ":") components.append(s) return "-".join(components) diff --git a/src/borg_import/helpers/testsuite/test_names.py b/src/borg_import/helpers/testsuite/test_names.py index efbe500..aa2930e 100644 --- a/src/borg_import/helpers/testsuite/test_names.py +++ b/src/borg_import/helpers/testsuite/test_names.py @@ -4,7 +4,7 @@ def test_make_name(): - # str (some with invalid/unwanted chars) + # str (some with invalid/unwanted characters) assert make_name("backup name") == "backup_name" assert make_name("backup/name") == "backup!name" assert make_name("backup::name") == "backup:name" diff --git a/src/borg_import/helpers/testsuite/test_timestamps.py b/src/borg_import/helpers/testsuite/test_timestamps.py index 78959fb..b16ef93 100644 --- a/src/borg_import/helpers/testsuite/test_timestamps.py +++ b/src/borg_import/helpers/testsuite/test_timestamps.py @@ -21,8 +21,8 @@ def test_datetime_from_string(): dfs = datetime_from_string("1999-12-31T23:59:59") dt_trg = datetime(1999, 12, 31, 23, 59, 59).astimezone(tz=timezone.utc) assert dfs == dt_trg - # Of course, two datetimes can be equal in different timezones. Make - # sure the timezone info matches UTC, which borg itself expects. + # Two datetimes can be equal in different time zones. Make + # sure the time zone info matches UTC, which Borg itself expects. assert dfs.tzinfo == dt_trg.tzinfo == timezone.utc # FIXME: When this format is passed to datetime_from_string, the internal @@ -34,7 +34,7 @@ def test_datetime_from_string(): assert dfs == dt_trg assert dfs.tzinfo == dt_trg.tzinfo == timezone.utc - # rsync-time-backup format. + # rsync-time-backup format: dfs = datetime_from_string("2022-12-21-063019") dt_trg = datetime(2022, 12, 21, 6, 30, 19).astimezone(tz=timezone.utc) assert dfs == dt_trg diff --git a/src/borg_import/helpers/timestamps.py b/src/borg_import/helpers/timestamps.py index 7ecc82f..0068506 100644 --- a/src/borg_import/helpers/timestamps.py +++ b/src/borg_import/helpers/timestamps.py @@ -3,25 +3,24 @@ def datetime_from_mtime(path): """ - discover backup timestamp from a (single) filesystem object. + Discover the backup timestamp from a (single) filesystem object. - e.g. from a root/TIMESTAMP file created by "touch" at backup time, + For example, from a root/TIMESTAMP file created by "touch" at backup time, or from root/ (assuming that the directory timestamp was modified at backup time). """ t = path.stat().st_mtime - # Borg needs tz-aware timestamps in UTC timezone. + # Borg needs timezone-aware timestamps in UTC. return datetime.fromtimestamp(t, tz=timezone.utc) def datetime_from_string(s): """ - parse datetime from a string + Parse a datetime from a string. - returns a tz-aware datetime object in UTC timezone if the format could be - parsed. + Return a timezone-aware datetime object in UTC if the format could be parsed. - raises ValueError if not. + Raise ValueError otherwise. """ s = s.strip() for ts_format in [ @@ -40,26 +39,26 @@ def datetime_from_string(s): ]: try: if ts_format in ("%a %b %d %H:%M:%S %Z %Y",) and "UTC" in s: - # %Z returns a naive datetime, despite a timezone being specified. + # %Z returns a naive datetime, despite a time zone being specified. # However, strptime %Z only tends to work on local times and # UTC. # # Per astimezone docs: # If self is naive, it is presumed to represent time in the - # system timezone. + # system time zone. # - # If we had a UTC timezone, prevent conversion to aware - # datetime from assuming a local timezone before conversion + # If we had a UTC time zone, prevent conversion to an aware + # datetime from assuming a local time zone before conversion # to UTC. return datetime.strptime(s, ts_format).replace(tzinfo=timezone.utc) else: # If "UTC" wasn't specified using the above ts_format, assume - # the timezone specified was local and hope for the best. + # the time zone specified was local and hope for the best. # This handles all other ts_formats as well, which are assumed - # to be local since they don't carry timezone. + # to be local since they don't carry a time zone. return datetime.strptime(s, ts_format).astimezone(tz=timezone.utc) except ValueError: - # didn't work with this format, try next + # Didn't work with this format; try the next. pass else: raise ValueError("could not parse %r" % s) @@ -67,9 +66,9 @@ def datetime_from_string(s): def datetime_from_file(path): """ - discover backup timestamp from contents of a file. + Discover the backup timestamp from the contents of a file. - e.g. root/TIMESTAMP contains: Mon Oct 31 23:35:50 CET 2016 + For example, root/TIMESTAMP contains: Mon Oct 31 23:35:50 CET 2016 """ with path.open() as f: ts = f.readline().strip() diff --git a/src/borg_import/main.py b/src/borg_import/main.py index 87bcd95..29c04fc 100755 --- a/src/borg_import/main.py +++ b/src/borg_import/main.py @@ -33,7 +33,7 @@ def borg_import(args, archive_name, path, timestamp=None): except subprocess.CalledProcessError as cpe: if cpe.returncode != 1: raise - log.debug("Borg exited with a warning (being quiet about it since Borg spoke already)") + log.debug("Borg exited with a warning (not repeating details since Borg already reported them)") def list_borg_archives(args): @@ -72,7 +72,7 @@ class rsnapshotImporter(Importer): The directory is called "borg-import-dir" inside the rsnapshot root, and borg-import will note which snapshot is currently located there - in a file called "borg-import-dir.snapshot" besides it, in case + in a file called "borg-import-dir.snapshot" beside it, in case things go wrong. Otherwise nothing in the rsnapshot root is modified, and neither @@ -146,7 +146,7 @@ def import_rsnapshot(self, args): class rsynchlImporter(Importer): name = "rsynchl" - description = "import rsync+hardlink backups" + description = "import rsync-with-hard-links backups" epilog = """ Imports from rsync backup sets by renaming each snapshot to a common name independent of the snapshot, which allows the Borg files cache @@ -159,7 +159,7 @@ class rsynchlImporter(Importer): The directory is called "borg-import-dir" inside the specified root, and borg-import will note which snapshot is currently located there - in a file called "borg-import-dir.snapshot" besides it, in case + in a file called "borg-import-dir.snapshot" beside it, in case things go wrong. Otherwise nothing in the rsync root is modified, and neither @@ -237,7 +237,7 @@ class rsyncTmBackupImporter(Importer): The directory is called "borg-import-dir" inside the specified root, and borg-import will note which snapshot is currently located there - in a file called "borg-import-dir.snapshot" besides it, in case + in a file called "borg-import-dir.snapshot" beside it, in case things go wrong. Otherwise nothing in the rsync root is modified, and neither @@ -305,7 +305,7 @@ class borgImporter(Importer): This is useful when a Borg repository needs to be rebuilt and all archives transferred from the old repository to a new one. - The importer extracts each archive from the source repository to a intermediate + The importer extracts each archive from the source repository to an intermediate directory inside the current work directory (make sure there is enough space!) and then creates a new archive with the same name and timestamp in the destination repository. @@ -419,7 +419,7 @@ def build_parser(): def main(): if not shutil.which("borg"): - print("The 'borg' command can't be found in the PATH. Please correctly install borgbackup first.") + print("The 'borg' command cannot be found in PATH. Please install BorgBackup first.") print("See instructions at https://borgbackup.readthedocs.io/en/stable/installation.html") return 1 diff --git a/src/borg_import/rsnapshots.py b/src/borg_import/rsnapshots.py index aaf540d..66bf69b 100644 --- a/src/borg_import/rsnapshots.py +++ b/src/borg_import/rsnapshots.py @@ -6,7 +6,7 @@ def get_snapshots(root): - """Get all snapshot metadata discovered in the rsnapshot root directory.""" + """Return metadata for all snapshots discovered in the rsnapshot root directory.""" regex = re.compile(r"(?P.+)/(?P.+)") for path in discover(str(root), 2): parsed = parser(path, regex) diff --git a/src/borg_import/rsync_tmbackup.py b/src/borg_import/rsync_tmbackup.py index ec96e7d..a177578 100644 --- a/src/borg_import/rsync_tmbackup.py +++ b/src/borg_import/rsync_tmbackup.py @@ -7,11 +7,11 @@ def get_tmbackup_snapshots(root, prefix): - """Get all snapshot metadata discovered in the rsync root directory.""" + """Return metadata for all snapshots discovered in the rsync root directory.""" regex = re.compile(r"(?P.+)") if not Path("backup.marker").exists(): - raise FileNotFoundError("backup.marker file should exist for rsync-time-backup import") + raise FileNotFoundError("The backup.marker file must exist for rsync-time-backup import") for path in discover(str(root), 1): parsed = parser(path, regex) @@ -24,9 +24,9 @@ def get_tmbackup_snapshots(root, prefix): ) yield meta elif parsed["snapshot_date"] in ("latest",): - # latest is a symlink to the most recent build. Import it anyway - # in case user wants to do borg mount/has existing references - # to latest. + # "latest" is a symlink to the most recent backup. Import it anyway + # in case the user wants to do borg mount or has existing references + # to "latest". abs_path = root / path timestamp = Path("latest").resolve().name meta = dict( diff --git a/src/borg_import/rsynchl.py b/src/borg_import/rsynchl.py index 67f8486..02a9f5e 100644 --- a/src/borg_import/rsynchl.py +++ b/src/borg_import/rsynchl.py @@ -6,7 +6,7 @@ def get_rsyncsnapshots(root): - """Get all snapshot metadata discovered in the rsync root directory.""" + """Return metadata for all snapshots discovered in the rsync root directory.""" regex = re.compile(r"(?P.+)") for path in discover(str(root), 1): parsed = parser(path, regex) diff --git a/src/borg_import/testsuite/test_borg.py b/src/borg_import/testsuite/test_borg.py index d96c830..0c51101 100644 --- a/src/borg_import/testsuite/test_borg.py +++ b/src/borg_import/testsuite/test_borg.py @@ -4,7 +4,7 @@ def test_borg_import(tmpdir, monkeypatch): - """Test the borg importer by creating archives in a source repo and importing them to a target repo.""" + """Test the Borg importer by creating archives in a source repository and importing them to a target repository.""" # Create source and target repository directories source_repo = tmpdir.mkdir("source_repo") target_repo = tmpdir.mkdir("target_repo")