From 2e3a77850be90b323b842b8e076a7e2f196a1104 Mon Sep 17 00:00:00 2001 From: Sylvain Leroux Date: Fri, 23 Jan 2026 15:53:06 +0100 Subject: [PATCH 1/3] feat(docs): Add documentation for the rewrite command This adds documentation for the `rewrite` command, explaining how to modify existing snapshots. --- src/SUMMARY.md | 1 + src/commands/misc/rewrite.md | 150 +++++++++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 src/commands/misc/rewrite.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index c430bd2..723df34 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -35,6 +35,7 @@ - [Working with repositories](./commands/misc/intro.md) - [Listing Snapshots](./commands/misc/listing.md) - [Copying Snapshots between Repositories](./commands/misc/copy.md) + - [Rewriting Snapshots](./commands/misc/rewrite.md) - [Filtering Snapshots](./commands/misc/filter.md) - [Show File History](./commands/misc/file_history.md) - [Ensuring deduplication for copied Snapshots](./commands/misc/deduplication.md) diff --git a/src/commands/misc/rewrite.md b/src/commands/misc/rewrite.md new file mode 100644 index 0000000..f8ad0ed --- /dev/null +++ b/src/commands/misc/rewrite.md @@ -0,0 +1,150 @@ +# Rewriting Snapshots + +## Removing files + +Sometimes you need to change an existing snapshot. Notably, if you discover it +includes unwanted files (e.g., a password in cleartext or large caches). + +Instead of deleting the snapshot and then using the `backup` command again, you +may use the `rewrite` command to modify the existing snapshots. + +### The long way + +Let's imagine I have the following snapshots: + +```console +$ rustic snapshots --filter-paths Project + +snapshots for (host [kasimir], label [], paths [Project]) +| ID | Time | Host | Label | Tags | Paths | Files | Dirs | Size | +|----------|---------------------|---------|-------|------|---------|-------|------|-----------| +| 7cea1643 | 2026-01-23 10:18:52 | kasimir | | | Project | 1190 | 87 | 120.3 MiB | +| a1a54f27 | 2026-01-23 11:38:35 | kasimir | | | Project | 1191 | 88 | 120.3 MiB | +| d40f48a9 | 2026-01-23 11:52:11 | kasimir | | | Project | 1191 | 88 | 120.3 MiB | +3 snapshot(s) + +total: 3 snapshot(s) +``` + +Unfortunately, the *Project/config/secret.env* file has sneaked in. First thing, +identify the snapshots containing that file: + +```console +$ rustic find --glob '**/secret.env' --filter-paths Project + +searching in snapshots group (host [kasimir], label [], paths [Project])... +found in a1a54f27 from 2026-01-23 11:38:35 +-rw-r--r-- sylvain sylvain 13 23 Jan 2026 11:38 "Project/config/secret.env" +found in d40f48a9 from 2026-01-23 11:52:11 +-rw------- sylvain sylvain 13 23 Jan 2026 11:38 "Project/config/secret.env" +``` + +Apparently, two snapshots are concerned. Let's rewrite them to *exclude* that +file: + +```console +$ rustic -n rewrite --glob '!**/secret.env' a1a54f27 d40f48a9 +$ rustic snapshots --all --filter-paths Project + +snapshots for (host [kasimir], label [], paths [Project]) +| ID | Time | Host | Label | Tags | Paths | Files | Dirs | Size | +|----------|---------------------|---------|-------|------|---------|-------|------|-----------| +| 7cea1643 | 2026-01-23 10:18:52 | kasimir | | | Project | 1190 | 87 | 120.3 MiB | +| a1a54f27 | 2026-01-23 11:38:35 | kasimir | | | Project | 1191 | 88 | 120.3 MiB | +| 1cb5ee37 | 2026-01-23 11:38:35 | kasimir | | | Project | 653 | 88 | 120.3 MiB | +| d40f48a9 | 2026-01-23 11:52:11 | kasimir | | | Project | 1191 | 88 | 120.3 MiB | +| fa65bc8d | 2026-01-23 11:52:11 | kasimir | | | Project | 653 | 88 | 120.3 MiB | +5 snapshot(s) + +total: 5 snapshot(s) +``` + +**Note:** In the `rewrite` command, you must use a negative glob (starting with +an exclamation mark) to specify the files you want to remove. + +**XXX**: Why do the rewritten snapshots display such a different number of files +compared to the original? + +As shown above, the snapshots `a1a54f27` and `d40f48a9` are still present. By +default, the `rewrite` command does *not* remove the source snapshots. So in my +case, I will have to remove them manually: + +```console +$ rustic forget a1a54f27 d40f48a9 +$ rustic snapshots --all --filter-paths Project + +snapshots for (host [kasimir], label [], paths [Project]) +| ID | Time | Host | Label | Tags | Paths | Files | Dirs | Size | +|----------|---------------------|---------|-------|------|---------|-------|------|-----------| +| 7cea1643 | 2026-01-23 10:18:52 | kasimir | | | Project | 1190 | 87 | 120.3 MiB | +| 1cb5ee37 | 2026-01-23 11:38:35 | kasimir | | | Project | 653 | 88 | 120.3 MiB | +| fa65bc8d | 2026-01-23 11:52:11 | kasimir | | | Project | 653 | 88 | 120.3 MiB | +3 snapshot(s) + +total: 3 snapshot(s) +``` + +You can now check: no remaining snapshots contain the file we removed: + +```console +$ rustic find --glob '**/secret.env' --filter-paths Project + +searching in snapshots group (host [kasimir], label [], paths [Project])... +``` + +### The short way + +In the above section, we've seen all the involved steps with great detail. We +especially had to manually remove the unwanted snapshots. But to do it for you, +the `rewrite` command has the `--forget` option. + +Let's restart in a clean state: + +```console +$ rustic backup Project +$ rustic snapshots --all + +snapshots for (host [109a0e940612], label [], paths [Project]) +| ID | Time | Host | Label | Tags | Paths | Files | Dirs | Size | +|----------|---------------------|--------------|-------|------|---------|-------|------|-----------| +| 22b7d2a4 | 2026-01-23 14:10:29 | kasimir | | | Project | 1191 | 88 | 120.3 MiB | +1 snapshot(s) + +total: 1 snapshot(s) +$ rustic find --glob 'Project/config/secret.env' --filter-paths Project + +searching in snapshots group (host [109a0e940612], label [], paths [Project])... +found in 22b7d2a4 from 2026-01-23 14:10:29 +-rw------- sylvain sylvain 13 23 Jan 2026 11:38 "Project/config/secret.env" +``` + +As you noticed, the `secret.env` file is back in this example snapshot. We will +remove it again, but this time using the `rewrite --forget` command: + +```console +$ rustic rewrite --forget --glob '!Project/config/secret.env' --filter-paths Project + +$ rustic snapshots --all + +snapshots for (host [109a0e940612], label [], paths [Project]) +| ID | Time | Host | Label | Tags | Paths | Files | Dirs | Size | +|----------|---------------------|--------------|-------|------|---------|-------|------|-----------| +| b7826f11 | 2026-01-23 14:10:29 | kasimir | | | Project | 653 | 88 | 120.3 MiB | +1 snapshot(s) + +total: 1 snapshot(s) +``` + +The original snapshot was removed, and the rewritten one no longer lists the +`secret.env` file. + +**Note:** The `rewrite` command modifies only the index trees. It does not deal +with the data packs. It has two consequences: + +- You can rewrite snapshots configured to use cold storage without bringing + anything into the hot storage. +- Even if the file was removed from the tree index, the data are still present + in the rustic repository as pack files. For sensitive data, consider using the + `rustic prune` command to remove the pack files. It will remove the pack + files, but Rustic has no way to ensure that the data are wipped out from the + repository's underlying disk/storage system. From 0eb76422a8f95b456d6f2100ecb480a94d94b6f5 Mon Sep 17 00:00:00 2001 From: Sylvain Leroux Date: Tue, 3 Feb 2026 13:13:28 +0100 Subject: [PATCH 2/3] feat(docs): Add documentation for the rewrite command Add the {add,set,remove}-tags options Add the --set-hostname option --- src/commands/misc/rewrite.md | 320 ++++++++++++++++++++++++++++------- 1 file changed, 260 insertions(+), 60 deletions(-) diff --git a/src/commands/misc/rewrite.md b/src/commands/misc/rewrite.md index f8ad0ed..a25d4ce 100644 --- a/src/commands/misc/rewrite.md +++ b/src/commands/misc/rewrite.md @@ -3,7 +3,7 @@ ## Removing files Sometimes you need to change an existing snapshot. Notably, if you discover it -includes unwanted files (e.g., a password in cleartext or large caches). +includes unwanted files (e.g., cleartext passwords or large caches). Instead of deleting the snapshot and then using the `backup` command again, you may use the `rewrite` command to modify the existing snapshots. @@ -13,14 +13,15 @@ may use the `rewrite` command to modify the existing snapshots. Let's imagine I have the following snapshots: ```console -$ rustic snapshots --filter-paths Project +# Initial state: +$ rustic snapshots --all --filter-paths Project snapshots for (host [kasimir], label [], paths [Project]) -| ID | Time | Host | Label | Tags | Paths | Files | Dirs | Size | -|----------|---------------------|---------|-------|------|---------|-------|------|-----------| -| 7cea1643 | 2026-01-23 10:18:52 | kasimir | | | Project | 1190 | 87 | 120.3 MiB | -| a1a54f27 | 2026-01-23 11:38:35 | kasimir | | | Project | 1191 | 88 | 120.3 MiB | -| d40f48a9 | 2026-01-23 11:52:11 | kasimir | | | Project | 1191 | 88 | 120.3 MiB | +| ID | Host | Label | Tags | Paths | Files | Dirs | Size | +|----------|---------|-------|------|---------|-------|------|-----------| +| 7f3eef1f | kasimir | | | Project | 507 | 87 | 524.0 KiB | +| 5109f5fe | kasimir | | | Project | 508 | 87 | 524.0 KiB | +| ca466029 | kasimir | | | Project | 509 | 87 | 524.0 KiB | 3 snapshot(s) total: 3 snapshot(s) @@ -30,30 +31,42 @@ Unfortunately, the *Project/config/secret.env* file has sneaked in. First thing, identify the snapshots containing that file: ```console -$ rustic find --glob '**/secret.env' --filter-paths Project +$ rustic find --glob '**/secret.env' --filter-paths Project searching in snapshots group (host [kasimir], label [], paths [Project])... -found in a1a54f27 from 2026-01-23 11:38:35 --rw-r--r-- sylvain sylvain 13 23 Jan 2026 11:38 "Project/config/secret.env" -found in d40f48a9 from 2026-01-23 11:52:11 --rw------- sylvain sylvain 13 23 Jan 2026 11:38 "Project/config/secret.env" +found in 5109f5fe from 2026-02-02 13:17:52 +-rw-r--r-- user user 29 2 Feb 2026 13:17 "Project/config/secret.env" +found in ca466029 from 2026-02-02 13:17:57 +-rw-r--r-- user user 29 2 Feb 2026 13:17 "Project/config/secret.env" +``` + +**Note:** As an alternative to `rustic find`, you may directly use `rustic rewrite -n` (`-n` is for dry-run) +```console +$ rustic rewrite -n --glob '!**/secret.env' +Would have rewritten the following snapshots: +| ID | Host | Label | Tags | Paths | Files | Dirs | Size | +|----------|---------|-------|------|---------|-------|------|-----------| +| 5109f5fe | kasimir | | | Project | 507 | 87 | 524.0 KiB | +| ca466029 | kasimir | | | Project | 508 | 87 | 524.0 KiB | +2 snapshot(s) + ``` Apparently, two snapshots are concerned. Let's rewrite them to *exclude* that file: ```console -$ rustic -n rewrite --glob '!**/secret.env' a1a54f27 d40f48a9 +$ rustic rewrite --glob '!**/secret.env' 5109f5fe ca466029 $ rustic snapshots --all --filter-paths Project snapshots for (host [kasimir], label [], paths [Project]) -| ID | Time | Host | Label | Tags | Paths | Files | Dirs | Size | -|----------|---------------------|---------|-------|------|---------|-------|------|-----------| -| 7cea1643 | 2026-01-23 10:18:52 | kasimir | | | Project | 1190 | 87 | 120.3 MiB | -| a1a54f27 | 2026-01-23 11:38:35 | kasimir | | | Project | 1191 | 88 | 120.3 MiB | -| 1cb5ee37 | 2026-01-23 11:38:35 | kasimir | | | Project | 653 | 88 | 120.3 MiB | -| d40f48a9 | 2026-01-23 11:52:11 | kasimir | | | Project | 1191 | 88 | 120.3 MiB | -| fa65bc8d | 2026-01-23 11:52:11 | kasimir | | | Project | 653 | 88 | 120.3 MiB | +| ID | Host | Label | Tags | Paths | Files | Dirs | Size | +|----------|---------|-------|---------|---------|-------|------|-----------| +| 7f3eef1f | kasimir | | | Project | 507 | 87 | 524.0 KiB | +| 337ff932 | kasimir | | rewrite | Project | 507 | 87 | 524.0 KiB | +| 5109f5fe | kasimir | | | Project | 508 | 87 | 524.0 KiB | +| ca466029 | kasimir | | | Project | 509 | 87 | 524.0 KiB | +| cf5416ee | kasimir | | rewrite | Project | 508 | 87 | 524.0 KiB | 5 snapshot(s) total: 5 snapshot(s) @@ -62,23 +75,20 @@ total: 5 snapshot(s) **Note:** In the `rewrite` command, you must use a negative glob (starting with an exclamation mark) to specify the files you want to remove. -**XXX**: Why do the rewritten snapshots display such a different number of files -compared to the original? - -As shown above, the snapshots `a1a54f27` and `d40f48a9` are still present. By -default, the `rewrite` command does *not* remove the source snapshots. So in my -case, I will have to remove them manually: +We now have two _new_ snapshots tagged `rewrite`: the updated snapshots with the secret file removed. +You may also notice that the snapshots `5109f5fe` and `ca466029` remain. By +default, the `rewrite` command does *not* remove the source snapshots. So, in mycase, I will have to remove them manually: ```console -$ rustic forget a1a54f27 d40f48a9 +$ rustic forget 5109f5fe ca466029 $ rustic snapshots --all --filter-paths Project snapshots for (host [kasimir], label [], paths [Project]) -| ID | Time | Host | Label | Tags | Paths | Files | Dirs | Size | -|----------|---------------------|---------|-------|------|---------|-------|------|-----------| -| 7cea1643 | 2026-01-23 10:18:52 | kasimir | | | Project | 1190 | 87 | 120.3 MiB | -| 1cb5ee37 | 2026-01-23 11:38:35 | kasimir | | | Project | 653 | 88 | 120.3 MiB | -| fa65bc8d | 2026-01-23 11:52:11 | kasimir | | | Project | 653 | 88 | 120.3 MiB | +| ID | Host | Label | Tags | Paths | Files | Dirs | Size | +|----------|---------|-------|---------|---------|-------|------|-----------| +| 7f3eef1f | kasimir | | | Project | 507 | 87 | 524.0 KiB | +| 337ff932 | kasimir | | rewrite | Project | 507 | 87 | 524.0 KiB | +| cf5416ee | kasimir | | rewrite | Project | 508 | 87 | 524.0 KiB | 3 snapshot(s) total: 3 snapshot(s) @@ -92,52 +102,119 @@ $ rustic find --glob '**/secret.env' --filter-paths Project searching in snapshots group (host [kasimir], label [], paths [Project])... ``` +Finally, let's get rid of the `rewrite` tags (more on that later): + +```console +$ rustic rewrite --forget --remove-tags 'rewrite' --filter-paths Project +$ rustic snapshots --all --filter-paths Project + +snapshots for (host [kasimir], label [], paths [Project]) +| ID | Host | Label | Tags | Paths | Files | Dirs | Size | +|----------|---------|-------|------|---------|-------|------|-----------| +| 7f3eef1f | kasimir | | | Project | 507 | 87 | 524.0 KiB | +| 4b0b7b90 | kasimir | | | Project | 507 | 87 | 524.0 KiB | +| 1d95e18e | kasimir | | | Project | 508 | 87 | 524.0 KiB | +3 snapshot(s) + +total: 3 snapshot(s) +``` + +**Note:** The `rewrite` command never modifies an existing snapshot. It always creates a new one. +That's why the _untagged_ snapshots above have a different ID than the _tagged_ ones. + ### The short way -In the above section, we've seen all the involved steps with great detail. We -especially had to manually remove the unwanted snapshots. But to do it for you, -the `rewrite` command has the `--forget` option. +In the section above, we've outlined all the steps in detail. We +especially had to manually identify and then remove the unwanted snapshots. But using the `-n` and `--forget` options, the `rewrite command` can do the job with fewer keystrokes. -Let's restart in a clean state: +Let's resume at the moment we noticed the unwanted file in the backups. If you remember, we had then three snapshots without knowing the ones that were containing the `secret.env` file: ```console -$ rustic backup Project -$ rustic snapshots --all +# Initial state: +$ rustic snapshots --all --filter-paths Project -snapshots for (host [109a0e940612], label [], paths [Project]) -| ID | Time | Host | Label | Tags | Paths | Files | Dirs | Size | -|----------|---------------------|--------------|-------|------|---------|-------|------|-----------| -| 22b7d2a4 | 2026-01-23 14:10:29 | kasimir | | | Project | 1191 | 88 | 120.3 MiB | -1 snapshot(s) +snapshots for (host [kasimir], label [], paths [Project]) +| ID | Host | Label | Tags | Paths | Files | Dirs | Size | +|----------|---------|-------|------|---------|-------|------|-----------| +| 7f3eef1f | kasimir | | | Project | 507 | 87 | 524.0 KiB | +| 5109f5fe | kasimir | | | Project | 508 | 87 | 524.0 KiB | +| ca466029 | kasimir | | | Project | 509 | 87 | 524.0 KiB | +3 snapshot(s) -total: 1 snapshot(s) -$ rustic find --glob 'Project/config/secret.env' --filter-paths Project +total: 3 snapshot(s) +``` + +To identify the snapshots containing the `secret.env` file, we previously used `rustic find`. +But `rewrite` also has a _dry-run_ option `-n`. It doesn't perform any action on +the repo, but it will show you the snapshot that would have been affected: + +```console +$ rustic rewrite -n --glob '!Project/config/secret.env' --filter-paths Project +Would have rewritten the following snapshots: +| ID | Host | Label | Tags | Paths | Files | Dirs | Size | +|----------|---------|-------|------|---------|-------|------|-----------| +| 5109f5fe | kasimir | | | Project | 507 | 87 | 524.0 KiB | +| ca466029 | kasimir | | | Project | 508 | 87 | 524.0 KiB | +2 snapshot(s) +``` + +And using the `--forget` option, we can do the `rewrite` and `forget` steps in one command: + +```console +$ rustic rewrite --forget --glob '!Project/config/secret.env' 5109f5fe ca466029 +$ rustic snapshots --all --filter-paths Project + +snapshots for (host [kasimir], label [], paths [Project]) +| ID | Host | Label | Tags | Paths | Files | Dirs | Size | +|----------|---------|-------|------|---------|-------|------|-----------| +| 7f3eef1f | kasimir | | | Project | 507 | 87 | 524.0 KiB | +| d0f5387f | kasimir | | | Project | 507 | 87 | 524.0 KiB | +| 27a82e21 | kasimir | | | Project | 508 | 87 | 524.0 KiB | +3 snapshot(s) -searching in snapshots group (host [109a0e940612], label [], paths [Project])... -found in 22b7d2a4 from 2026-01-23 14:10:29 --rw------- sylvain sylvain 13 23 Jan 2026 11:38 "Project/config/secret.env" +total: 3 snapshot(s) ``` -As you noticed, the `secret.env` file is back in this example snapshot. We will -remove it again, but this time using the `rewrite --forget` command: +Interestingly, the new snapshots replaced the old ones but were not tagged. The options `--forget` and `--tags-rewritten ''` prevent the command from adding the `rewrite` tag. + +### The very short way + +Well, as a matter of fact, if you know what you're doing, all can be done just using `rewrite --forget`: ```console +# Initial state: +$ rustic snapshots --all --filter-paths Project + +snapshots for (host [kasimir], label [], paths [Project]) +| ID | Host | Label | Tags | Paths | Files | Dirs | Size | +|----------|---------|-------|------|---------|-------|------|-----------| +| 7f3eef1f | kasimir | | | Project | 507 | 87 | 524.0 KiB | +| 5109f5fe | kasimir | | | Project | 508 | 87 | 524.0 KiB | +| ca466029 | kasimir | | | Project | 509 | 87 | 524.0 KiB | +3 snapshot(s) + +total: 3 snapshot(s) + +# Here is the rewrite command: $ rustic rewrite --forget --glob '!Project/config/secret.env' --filter-paths Project +$ rustic snapshots --all --filter-paths Project + +snapshots for (host [kasimir], label [], paths [Project]) +| ID | Host | Label | Tags | Paths | Files | Dirs | Size | +|----------|---------|-------|------|---------|-------|------|-----------| +| 7f3eef1f | kasimir | | | Project | 507 | 87 | 524.0 KiB | +| 09ccdc56 | kasimir | | | Project | 507 | 87 | 524.0 KiB | +| e176474e | kasimir | | | Project | 508 | 87 | 524.0 KiB | +3 snapshot(s) -$ rustic snapshots --all +total: 3 snapshot(s) -snapshots for (host [109a0e940612], label [], paths [Project]) -| ID | Time | Host | Label | Tags | Paths | Files | Dirs | Size | -|----------|---------------------|--------------|-------|------|---------|-------|------|-----------| -| b7826f11 | 2026-01-23 14:10:29 | kasimir | | | Project | 653 | 88 | 120.3 MiB | -1 snapshot(s) +# Check: +$ rustic find --glob '**/secret.env' --filter-paths Project -total: 1 snapshot(s) +searching in snapshots group (host [kasimir], label [], paths [Project])... ``` -The original snapshot was removed, and the rewritten one no longer lists the -`secret.env` file. - **Note:** The `rewrite` command modifies only the index trees. It does not deal with the data packs. It has two consequences: @@ -148,3 +225,126 @@ with the data packs. It has two consequences: `rustic prune` command to remove the pack files. It will remove the pack files, but Rustic has no way to ensure that the data are wipped out from the repository's underlying disk/storage system. + +## Rewriting tags + +The `rustic rewrite` command allows you to manipulate the snapshots' tags. + +For example, you can use `rewrite --set-tags ...` to set a new tag list to a snapshot: + +```console +$ rustic snapshots --all --filter-paths Project + +snapshots for (host [kasimir], label [], paths [Project]) +| ID | Host | Label | Tags | Paths | Files | Dirs | Size | +|----------|---------|-------|------|---------|-------|------|-----------| +| 7f3eef1f | kasimir | | | Project | 507 | 87 | 524.0 KiB | +1 snapshot(s) + +total: 1 snapshot(s) + +# Replace the tag list +$ rustic rewrite --set-tags origin,precious 7f3eef1f +$ rustic snapshots --all --filter-paths Project + +snapshots for (host [kasimir], label [], paths [Project]) +| ID | Host | Label | Tags | Paths | Files | Dirs | Size | +|----------|---------|-------|----------|---------|-------|------|-----------| +| 0d675c5c | kasimir | | origin | Project | 507 | 87 | 524.0 KiB | +| | | | precious | | | | | +| | | | rewrite | | | | | +| 7f3eef1f | kasimir | | | Project | 507 | 87 | 524.0 KiB | +2 snapshot(s) + +total: 2 snapshot(s) +``` + +You can also add tags with `rewrite --add-tags ...` and remove them using `rewrite --add-tags ...`: + + + +```console +# Add more tags +$ rustic rewrite --forget --add-tags main 0d675c5c +$ rustic snapshots --all --filter-paths Project + +snapshots for (host [kasimir], label [], paths [Project]) +| ID | Host | Label | Tags | Paths | Files | Dirs | Size | +|----------|---------|-------|----------|---------|-------|------|-----------| +| 285e7e62 | kasimir | | main | Project | 507 | 87 | 524.0 KiB | +| | | | origin | | | | | +| | | | precious | | | | | +| | | | rewrite | | | | | +| 7f3eef1f | kasimir | | | Project | 507 | 87 | 524.0 KiB | +2 snapshot(s) + +total: 2 snapshot(s) + +# Remove some tags +$ rustic rewrite --forget --remove-tags rewrite,origin 285e7e62 +$ rustic snapshots --all --filter-paths Project + +snapshots for (host [kasimir], label [], paths [Project]) +| ID | Host | Label | Tags | Paths | Files | Dirs | Size | +|----------|---------|-------|----------|---------|-------|------|-----------| +| 3f1560c5 | kasimir | | main | Project | 507 | 87 | 524.0 KiB | +| | | | precious | | | | | +| 7f3eef1f | kasimir | | | Project | 507 | 87 | 524.0 KiB | +2 snapshot(s) + +total: 2 snapshot(s) +``` + +**Note:** `rustic tag --remove ...` is an alias for `rustic rewrite --forget --remove-tags ...` + +```console +# Replace the tag list +$ rustic rewrite --forget --set-tags origin 3f1560c5 +$ rustic snapshots --all --filter-paths Project + +snapshots for (host [kasimir], label [], paths [Project]) +| ID | Host | Label | Tags | Paths | Files | Dirs | Size | +|----------|---------|-------|--------|---------|-------|------|-----------| +| 7a690c53 | kasimir | | origin | Project | 507 | 87 | 524.0 KiB | +| 7f3eef1f | kasimir | | | Project | 507 | 87 | 524.0 KiB | +2 snapshot(s) + +total: 2 snapshot(s) +``` + +## Rewriting the hostname + +You can change the hotname of an index tree. It can be useful if you have a master snapshot you want to use for different hosts: + +```console +$ rustic snapshots --all --filter-paths Project + +snapshots for (host [kasimir], label [], paths [Project]) +| ID | Host | Label | Tags | Paths | Files | Dirs | Size | +|----------|---------|-------|------|---------|-------|------|-----------| +| 7f3eef1f | kasimir | | | Project | 507 | 87 | 524.0 KiB | +1 snapshot(s) + +total: 1 snapshot(s) + +# Create a new identical snapshot with a different host name +# (--tags-rewritten '' prevent the addition of the `rewrite` tag) +$ rustic rewrite --set-hostname mikado --tags-rewritten '' 7f3eef1f +$ rustic snapshots --all --filter-paths Project + +snapshots for (host [kasimir], label [], paths [Project]) +| ID | Host | Label | Tags | Paths | Files | Dirs | Size | +|----------|---------|-------|------|---------|-------|------|-----------| +| 7f3eef1f | kasimir | | | Project | 507 | 87 | 524.0 KiB | +1 snapshot(s) + +snapshots for (host [mikado], label [], paths [Project]) +| ID | Host | Label | Tags | Paths | Files | Dirs | Size | +|----------|--------|-------|------|---------|-------|------|-----------| +| 5b28ba53 | mikado | | | Project | 507 | 87 | 524.0 KiB | +1 snapshot(s) +``` + +## More + +If you want more, try `rustic rewrite --help` to see all the rewrite capabilities. From d4a1e5a1c44bb45333b290170ad2b90611f1f8e3 Mon Sep 17 00:00:00 2001 From: Sylvain Leroux Date: Tue, 3 Feb 2026 14:11:02 +0100 Subject: [PATCH 3/3] dprint fmt --- src/commands/misc/rewrite.md | 61 ++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/src/commands/misc/rewrite.md b/src/commands/misc/rewrite.md index a25d4ce..de966cd 100644 --- a/src/commands/misc/rewrite.md +++ b/src/commands/misc/rewrite.md @@ -40,7 +40,9 @@ found in ca466029 from 2026-02-02 13:17:57 -rw-r--r-- user user 29 2 Feb 2026 13:17 "Project/config/secret.env" ``` -**Note:** As an alternative to `rustic find`, you may directly use `rustic rewrite -n` (`-n` is for dry-run) +**Note:** As an alternative to `rustic find`, you may directly use +`rustic rewrite -n` (`-n` is for dry-run) + ```console $ rustic rewrite -n --glob '!**/secret.env' Would have rewritten the following snapshots: @@ -49,7 +51,6 @@ Would have rewritten the following snapshots: | 5109f5fe | kasimir | | | Project | 507 | 87 | 524.0 KiB | | ca466029 | kasimir | | | Project | 508 | 87 | 524.0 KiB | 2 snapshot(s) - ``` Apparently, two snapshots are concerned. Let's rewrite them to *exclude* that @@ -75,9 +76,10 @@ total: 5 snapshot(s) **Note:** In the `rewrite` command, you must use a negative glob (starting with an exclamation mark) to specify the files you want to remove. -We now have two _new_ snapshots tagged `rewrite`: the updated snapshots with the secret file removed. -You may also notice that the snapshots `5109f5fe` and `ca466029` remain. By -default, the `rewrite` command does *not* remove the source snapshots. So, in mycase, I will have to remove them manually: +We now have two *new* snapshots tagged `rewrite`: the updated snapshots with the +secret file removed. You may also notice that the snapshots `5109f5fe` and +`ca466029` remain. By default, the `rewrite` command does *not* remove the +source snapshots. So, in mycase, I will have to remove them manually: ```console $ rustic forget 5109f5fe ca466029 @@ -119,15 +121,20 @@ snapshots for (host [kasimir], label [], paths [Project]) total: 3 snapshot(s) ``` -**Note:** The `rewrite` command never modifies an existing snapshot. It always creates a new one. -That's why the _untagged_ snapshots above have a different ID than the _tagged_ ones. +**Note:** The `rewrite` command never modifies an existing snapshot. It always +creates a new one. That's why the *untagged* snapshots above have a different ID +than the *tagged* ones. ### The short way -In the section above, we've outlined all the steps in detail. We -especially had to manually identify and then remove the unwanted snapshots. But using the `-n` and `--forget` options, the `rewrite command` can do the job with fewer keystrokes. +In the section above, we've outlined all the steps in detail. We especially had +to manually identify and then remove the unwanted snapshots. But using the `-n` +and `--forget` options, the `rewrite command` can do the job with fewer +keystrokes. -Let's resume at the moment we noticed the unwanted file in the backups. If you remember, we had then three snapshots without knowing the ones that were containing the `secret.env` file: +Let's resume at the moment we noticed the unwanted file in the backups. If you +remember, we had then three snapshots without knowing the ones that were +containing the `secret.env` file: ```console # Initial state: @@ -144,9 +151,10 @@ snapshots for (host [kasimir], label [], paths [Project]) total: 3 snapshot(s) ``` -To identify the snapshots containing the `secret.env` file, we previously used `rustic find`. -But `rewrite` also has a _dry-run_ option `-n`. It doesn't perform any action on -the repo, but it will show you the snapshot that would have been affected: +To identify the snapshots containing the `secret.env` file, we previously used +`rustic find`. But `rewrite` also has a *dry-run* option `-n`. It doesn't +perform any action on the repo, but it will show you the snapshot that would +have been affected: ```console $ rustic rewrite -n --glob '!Project/config/secret.env' --filter-paths Project @@ -158,7 +166,8 @@ Would have rewritten the following snapshots: 2 snapshot(s) ``` -And using the `--forget` option, we can do the `rewrite` and `forget` steps in one command: +And using the `--forget` option, we can do the `rewrite` and `forget` steps in +one command: ```console $ rustic rewrite --forget --glob '!Project/config/secret.env' 5109f5fe ca466029 @@ -175,11 +184,14 @@ snapshots for (host [kasimir], label [], paths [Project]) total: 3 snapshot(s) ``` -Interestingly, the new snapshots replaced the old ones but were not tagged. The options `--forget` and `--tags-rewritten ''` prevent the command from adding the `rewrite` tag. +Interestingly, the new snapshots replaced the old ones but were not tagged. The +options `--forget` and `--tags-rewritten ''` prevent the command from adding the +`rewrite` tag. ### The very short way -Well, as a matter of fact, if you know what you're doing, all can be done just using `rewrite --forget`: +Well, as a matter of fact, if you know what you're doing, all can be done just +using `rewrite --forget`: ```console # Initial state: @@ -230,7 +242,8 @@ with the data packs. It has two consequences: The `rustic rewrite` command allows you to manipulate the snapshots' tags. -For example, you can use `rewrite --set-tags ...` to set a new tag list to a snapshot: +For example, you can use `rewrite --set-tags ...` to set a new tag list to a +snapshot: ```console $ rustic snapshots --all --filter-paths Project @@ -259,9 +272,8 @@ snapshots for (host [kasimir], label [], paths [Project]) total: 2 snapshot(s) ``` -You can also add tags with `rewrite --add-tags ...` and remove them using `rewrite --add-tags ...`: - - +You can also add tags with `rewrite --add-tags ...` and remove them using +`rewrite --add-tags ...`: ```console # Add more tags @@ -295,7 +307,8 @@ snapshots for (host [kasimir], label [], paths [Project]) total: 2 snapshot(s) ``` -**Note:** `rustic tag --remove ...` is an alias for `rustic rewrite --forget --remove-tags ...` +**Note:** `rustic tag --remove ...` is an alias for +`rustic rewrite --forget --remove-tags ...` ```console # Replace the tag list @@ -314,7 +327,8 @@ total: 2 snapshot(s) ## Rewriting the hostname -You can change the hotname of an index tree. It can be useful if you have a master snapshot you want to use for different hosts: +You can change the hotname of an index tree. It can be useful if you have a +master snapshot you want to use for different hosts: ```console $ rustic snapshots --all --filter-paths Project @@ -347,4 +361,5 @@ snapshots for (host [mikado], label [], paths [Project]) ## More -If you want more, try `rustic rewrite --help` to see all the rewrite capabilities. +If you want more, try `rustic rewrite --help` to see all the rewrite +capabilities.