Repository: restic/restic
Pull request #4896 (2024-07-03 18:43:26)

man: work around broken rendering of <snapshotID>:<subfolder> help text
<!--
Thank you very much for contributing code or documentation to restic! Please
fill out the following questions to make it easier for us to review your
changes.
-->

What does this PR change? What problem does it solve?
-----------------------------------------------------
The help text `<snapshotID>:<subfolder>` is not rendered correctly in manpages, instead only `:` is included. This seems to be caused by the man page generator interpreting `<snapshotID>` as invalid HTML tag and therefore removing it. Replace all occurences of this pattern with `snapshotID:subfolder`. (without angle brackets).
<!--
Describe the changes and their purpose here, as detailed as needed.
-->

Was the change previously discussed in an issue or on the forum?
----------------------------------------------------------------
Fixes https://github.com/restic/restic/issues/4892 .
<!--
Link issues and relevant forum posts here.

If this PR resolves an issue on GitHub, use "Closes #1234" so that the issue
is closed automatically when this PR is merged.
-->

Checklist
---------

<!--
You do not need to check all the boxes below all at once. Feel free to take
your time and add more commits. If you're done and ready for review, please
check the last box. Enable a checkbox by replacing [ ] with [x].
-->

- [x] I have read the [contribution guidelines](https://github.com/restic/restic/blob/master/CONTRIBUTING.md#providing-patches).
- [x] I have [enabled maintainer edits](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/allowing-changes-to-a-pull-request-branch-created-from-a-fork).
- ~~[ ] I have added tests for all code changes.~~
- [x] I have added documentation for relevant changes (in the manual).
- ~~[ ] There's a new file in `changelog/unreleased/` that describes the changes for our users (see [template](https://github.com/restic/restic/blob/master/changelog/TEMPLATE)).~~
- [x] I have run `gofmt` on the code in all commits.
- [x] All commit messages are formatted in the same style as [the other commits in the repo](https://github.com/restic/restic/blob/master/CONTRIBUTING.md#git-commits).
- [x] I'm done! This pull request is ready for review.



Patch:
diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
index a943d1b15..771bf9f9a 100644
--- a/.github/workflows/docker.yml
+++ b/.github/workflows/docker.yml
@@ -55,7 +55,7 @@ jobs:
         if: github.ref != 'refs/heads/master'
 
       - name: Build and push Docker image
-        uses: docker/build-push-action@15560696de535e4014efeff63c48f16952e52dd1
+        uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0
         with:
           push: true
           context: .
diff --git a/changelog/unreleased/issue-1786 b/changelog/unreleased/issue-1786
index 87d4942c8..bdd0d48c3 100644
--- a/changelog/unreleased/issue-1786
+++ b/changelog/unreleased/issue-1786
@@ -1,6 +1,6 @@
 Enhancement: Support repositories with empty password
 
-Restic refused to create or operate on repositories with an empty password.
+Restic refused to create or operate on repositories with an emtpy password.
 Using the new option `--insecure-no-password` it is now possible to disable
 this check. Restic will not prompt for a password when using this option.
 For security reasons, the option must always be specified when operating on
@@ -10,8 +10,8 @@ Specifying `--insecure-no-password` while also passing a password to restic
 via a CLI option or via environment variable results in an error.
 
 The `init` and `copy` command also support the option `--from-insecure-no-password`
-which applies to the source repository. The `key add` and `key passwd` commands
-include the `--new-insecure-no-password` option to add or set an empty password.
+which applies to the source repository. The `key add` and `key passwd` comands
+include the `--new-insecure-no-password` option to add or set an emtpy password.
 
 https://github.com/restic/restic/issues/1786
 https://github.com/restic/restic/issues/4326
diff --git a/cmd/restic/cmd_diff.go b/cmd/restic/cmd_diff.go
index 28c742625..fd54897f1 100644
--- a/cmd/restic/cmd_diff.go
+++ b/cmd/restic/cmd_diff.go
@@ -33,7 +33,7 @@ Metadata comparison will likely not work if a backup was created using the
 '--ignore-inode' or '--ignore-ctime' option.
 
 To only compare files in specific subfolders, you can use the
-"<snapshotID>:<subfolder>" syntax, where "subfolder" is a path within the
+"snapshotID:subfolder" syntax, where "subfolder" is a path within the
 snapshot.
 
 EXIT STATUS
diff --git a/cmd/restic/cmd_dump.go b/cmd/restic/cmd_dump.go
index 39e915b40..2a98a8ae8 100644
--- a/cmd/restic/cmd_dump.go
+++ b/cmd/restic/cmd_dump.go
@@ -28,7 +28,7 @@ The special snapshotID "latest" can be used to use the latest snapshot in the
 repository.
 
 To include the folder content at the root of the archive, you can use the
-"<snapshotID>:<subfolder>" syntax, where "subfolder" is a path within the
+"snapshotID:subfolder" syntax, where "subfolder" is a path within the
 snapshot.
 
 EXIT STATUS
diff --git a/cmd/restic/cmd_prune.go b/cmd/restic/cmd_prune.go
index f0bfa2b94..2637fedc8 100644
--- a/cmd/restic/cmd_prune.go
+++ b/cmd/restic/cmd_prune.go
@@ -51,9 +51,9 @@ type PruneOptions struct {
 	MaxRepackSize  string
 	MaxRepackBytes uint64
 
-	RepackCacheableOnly bool
-	RepackSmall         bool
-	RepackUncompressed  bool
+	RepackCachableOnly bool
+	RepackSmall        bool
+	RepackUncompressed bool
 }
 
 var pruneOptions PruneOptions
@@ -70,7 +70,7 @@ func addPruneOptions(c *cobra.Command, pruneOptions *PruneOptions) {
 	f := c.Flags()
 	f.StringVar(&pruneOptions.MaxUnused, "max-unused", "5%", "tolerate given `limit` of unused data (absolute value in bytes with suffixes k/K, m/M, g/G, t/T, a value in % or the word 'unlimited')")
 	f.StringVar(&pruneOptions.MaxRepackSize, "max-repack-size", "", "maximum `size` to repack (allowed suffixes: k/K, m/M, g/G, t/T)")
-	f.BoolVar(&pruneOptions.RepackCacheableOnly, "repack-cacheable-only", false, "only repack packs which are cacheable")
+	f.BoolVar(&pruneOptions.RepackCachableOnly, "repack-cacheable-only", false, "only repack packs which are cacheable")
 	f.BoolVar(&pruneOptions.RepackSmall, "repack-small", false, "repack pack files below 80% of target pack size")
 	f.BoolVar(&pruneOptions.RepackUncompressed, "repack-uncompressed", false, "repack all uncompressed data")
 }
@@ -183,9 +183,9 @@ func runPruneWithRepo(ctx context.Context, opts PruneOptions, gopts GlobalOption
 		MaxUnusedBytes: opts.maxUnusedBytes,
 		MaxRepackBytes: opts.MaxRepackBytes,
 
-		RepackCacheableOnly: opts.RepackCacheableOnly,
-		RepackSmall:         opts.RepackSmall,
-		RepackUncompressed:  opts.RepackUncompressed,
+		RepackCachableOnly: opts.RepackCachableOnly,
+		RepackSmall:        opts.RepackSmall,
+		RepackUncompressed: opts.RepackUncompressed,
 	}
 
 	plan, err := repository.PlanPrune(ctx, popts, repo, func(ctx context.Context, repo restic.Repository, usedBlobs restic.FindBlobSet) error {
diff --git a/cmd/restic/cmd_restore.go b/cmd/restic/cmd_restore.go
index f39db6a76..467a7535a 100644
--- a/cmd/restic/cmd_restore.go
+++ b/cmd/restic/cmd_restore.go
@@ -25,7 +25,7 @@ a directory.
 The special snapshotID "latest" can be used to restore the latest snapshot in the
 repository.
 
-To only restore a specific subfolder, you can use the "<snapshotID>:<subfolder>"
+To only restore a specific subfolder, you can use the "snapshotID:subfolder"
 syntax, where "subfolder" is a path within the snapshot.
 
 EXIT STATUS
diff --git a/cmd/restic/cmd_snapshots.go b/cmd/restic/cmd_snapshots.go
index f689e4260..faa86d3a6 100644
--- a/cmd/restic/cmd_snapshots.go
+++ b/cmd/restic/cmd_snapshots.go
@@ -81,9 +81,9 @@ func runSnapshots(ctx context.Context, opts SnapshotOptions, gopts GlobalOptions
 		if opts.Last {
 			// This branch should be removed in the same time
 			// that --last.
-			list = FilterLatestSnapshots(list, 1)
+			list = FilterLastestSnapshots(list, 1)
 		} else if opts.Latest > 0 {
-			list = FilterLatestSnapshots(list, opts.Latest)
+			list = FilterLastestSnapshots(list, opts.Latest)
 		}
 		sort.Sort(sort.Reverse(list))
 		snapshotGroups[k] = list
@@ -126,11 +126,11 @@ func newFilterLastSnapshotsKey(sn *restic.Snapshot) filterLastSnapshotsKey {
 	return filterLastSnapshotsKey{sn.Hostname, strings.Join(paths, "|")}
 }
 
-// FilterLatestSnapshots filters a list of snapshots to only return
+// FilterLastestSnapshots filters a list of snapshots to only return
 // the limit last entries for each hostname and path. If the snapshot
 // contains multiple paths, they will be joined and treated as one
 // item.
-func FilterLatestSnapshots(list restic.Snapshots, limit int) restic.Snapshots {
+func FilterLastestSnapshots(list restic.Snapshots, limit int) restic.Snapshots {
 	// Sort the snapshots so that the newer ones are listed first
 	sort.SliceStable(list, func(i, j int) bool {
 		return list[i].Time.After(list[j].Time)
@@ -307,7 +307,7 @@ type Snapshot struct {
 	ShortID string     `json:"short_id"`
 }
 
-// SnapshotGroup helps to print SnapshotGroups as JSON with their GroupReasons included.
+// SnapshotGroup helps to print SnaphotGroups as JSON with their GroupReasons included.
 type SnapshotGroup struct {
 	GroupKey  restic.SnapshotGroupKey `json:"group_key"`
 	Snapshots []Snapshot              `json:"snapshots"`
diff --git a/cmd/restic/lock.go b/cmd/restic/lock.go
index 0e3dea6d5..99e199a67 100644
--- a/cmd/restic/lock.go
+++ b/cmd/restic/lock.go
@@ -34,12 +34,12 @@ func internalOpenWithLocked(ctx context.Context, gopts GlobalOptions, dryRun boo
 }
 
 func openWithReadLock(ctx context.Context, gopts GlobalOptions, noLock bool) (context.Context, *repository.Repository, func(), error) {
-	// TODO enforce read-only operations once the locking code has moved to the repository
+	// TODO enfore read-only operations once the locking code has moved to the repository
 	return internalOpenWithLocked(ctx, gopts, noLock, false)
 }
 
 func openWithAppendLock(ctx context.Context, gopts GlobalOptions, dryRun bool) (context.Context, *repository.Repository, func(), error) {
-	// TODO enforce non-exclusive operations once the locking code has moved to the repository
+	// TODO enfore non-exclusive operations once the locking code has moved to the repository
 	return internalOpenWithLocked(ctx, gopts, dryRun, false)
 }
 
diff --git a/doc/030_preparing_a_new_repo.rst b/doc/030_preparing_a_new_repo.rst
index 87975f9fa..5f3f3ff15 100644
--- a/doc/030_preparing_a_new_repo.rst
+++ b/doc/030_preparing_a_new_repo.rst
@@ -873,5 +873,5 @@ with an empty password, use the following command.
 
 
 The ``init`` and ``copy`` command also support the option ``--from-insecure-no-password``
-which applies to the source repository. The ``key add`` and ``key passwd`` commands
-include the ``--new-insecure-no-password`` option to add or set and empty password.
+which applies to the source repository. The ``key add`` and ``key passwd`` comands
+include the ``--new-insecure-no-password`` option to add or set and emtpy password.
diff --git a/doc/045_working_with_repos.rst b/doc/045_working_with_repos.rst
index 6b9666693..9d6167895 100644
--- a/doc/045_working_with_repos.rst
+++ b/doc/045_working_with_repos.rst
@@ -135,7 +135,7 @@ as separator.
     /home/user
     /home/user/work.txt
 
-To show more details about the files in a snapshot, you can use the ``--long`` option.  The columns include
+To show more details about the files in a snapshot, you can use the ``--long`` option.  The colums include
 file permissions, UID, GID, file size, modification time and file path. For scripting usage, the
 ``ls`` command supports the ``--json`` flag; the JSON output format is described at :ref:`ls json`.
 
diff --git a/doc/077_troubleshooting.rst b/doc/077_troubleshooting.rst
index 33302e9e0..f80df29b8 100644
--- a/doc/077_troubleshooting.rst
+++ b/doc/077_troubleshooting.rst
@@ -71,7 +71,7 @@ some blobs in the repository, then please ask for help in the forum or our IRC
 channel. These errors are often caused by hardware problems which **must** be
 investigated and fixed. Otherwise, the backup will be damaged again and again.
 
-Similarly, if a repository is repeatedly damaged, please open an `issue on GitHub
+Similarly, if a repository is repeatedly damaged, please open an `issue on Github
 <https://github.com/restic/restic/issues/new/choose>`_ as this could indicate a bug
 somewhere. Please include the check output and additional information that might
 help locate the problem.
@@ -102,7 +102,7 @@ remove data unexpectedly.
 Please take the time to understand what the commands described in the following
 do. If you are unsure, then ask for help in the forum or our IRC channel. Search
 whether your issue is already known and solved. Please take a look at the
-`forum`_ and `GitHub issues <https://github.com/restic/restic/issues>`_.
+`forum`_ and `Github issues <https://github.com/restic/restic/issues>`_.
 
 
 3. Repair the index
diff --git a/go.mod b/go.mod
index 3648e5c8c..2047d4657 100644
--- a/go.mod
+++ b/go.mod
@@ -2,8 +2,8 @@ module github.com/restic/restic
 
 require (
 	cloud.google.com/go/storage v1.41.0
-	github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0
-	github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0
+	github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1
+	github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0
 	github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.2
 	github.com/Backblaze/blazer v0.6.1
 	github.com/anacrolix/fuse v0.3.1-0.20240611061849-e4651fbc304d
@@ -13,7 +13,7 @@ require (
 	github.com/go-ole/go-ole v1.3.0
 	github.com/google/go-cmp v0.6.0
 	github.com/hashicorp/golang-lru/v2 v2.0.7
-	github.com/klauspost/compress v1.17.9
+	github.com/klauspost/compress v1.17.8
 	github.com/minio/minio-go/v7 v7.0.66
 	github.com/minio/sha256-simd v1.0.1
 	github.com/ncw/swift/v2 v2.0.2
@@ -23,12 +23,12 @@ require (
 	github.com/pkg/sftp v1.13.6
 	github.com/pkg/xattr v0.4.10-0.20221120235825-35026bbbd013
 	github.com/restic/chunker v0.4.0
-	github.com/spf13/cobra v1.8.1
+	github.com/spf13/cobra v1.8.0
 	github.com/spf13/pflag v1.0.5
 	go.uber.org/automaxprocs v1.5.3
 	golang.org/x/crypto v0.24.0
 	golang.org/x/net v0.26.0
-	golang.org/x/oauth2 v0.21.0
+	golang.org/x/oauth2 v0.20.0
 	golang.org/x/sync v0.7.0
 	golang.org/x/sys v0.21.0
 	golang.org/x/term v0.21.0
@@ -43,9 +43,9 @@ require (
 	cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect
 	cloud.google.com/go/compute/metadata v0.3.0 // indirect
 	cloud.google.com/go/iam v1.1.8 // indirect
-	github.com/Azure/azure-sdk-for-go/sdk/internal v1.9.0 // indirect
+	github.com/Azure/azure-sdk-for-go/sdk/internal v1.8.0 // indirect
 	github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect
-	github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
+	github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect
 	github.com/dustin/go-humanize v1.0.1 // indirect
 	github.com/felixge/fgprof v0.9.3 // indirect
 	github.com/felixge/httpsnoop v1.0.4 // indirect
diff --git a/go.sum b/go.sum
index 849957b0d..e229a0bdc 100644
--- a/go.sum
+++ b/go.sum
@@ -11,12 +11,12 @@ cloud.google.com/go/iam v1.1.8 h1:r7umDwhj+BQyz0ScZMp4QrGXjSTI3ZINnpgU2nlB/K0=
 cloud.google.com/go/iam v1.1.8/go.mod h1:GvE6lyMmfxXauzNq8NbgJbeVQNspG+tcdL/W8QO1+zE=
 cloud.google.com/go/storage v1.41.0 h1:RusiwatSu6lHeEXe3kglxakAmAbfV+rhtPqA6i8RBx0=
 cloud.google.com/go/storage v1.41.0/go.mod h1:J1WCa/Z2FcgdEDuPUY8DxT5I+d9mFKsCepp5vR6Sq80=
-github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0 h1:1nGuui+4POelzDwI7RG56yfQJHCnKvwfMoU7VsEp+Zg=
-github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0/go.mod h1:99EvauvlcJ1U06amZiksfYz/3aFGyIhWGHVyiZXtBAI=
-github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 h1:tfLQ34V6F7tVSwoTf/4lH5sE0o6eCJuNDTmH09nDpbc=
-github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg=
-github.com/Azure/azure-sdk-for-go/sdk/internal v1.9.0 h1:H+U3Gk9zY56G3u872L82bk4thcsy2Gghb9ExT4Zvm1o=
-github.com/Azure/azure-sdk-for-go/sdk/internal v1.9.0/go.mod h1:mgrmMSgaLp9hmax62XQTd0N4aAqSE5E0DulSpVYK7vc=
+github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1 h1:E+OJmp2tPvt1W+amx48v1eqbjDYsgN+RzP4q16yV5eM=
+github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1/go.mod h1:a6xsAQUZg+VsS3TJ05SRp524Hs4pZ/AeFSr5ENf0Yjo=
+github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0 h1:U2rTu3Ef+7w9FHKIAXM6ZyqF3UOWJZ12zIm8zECAFfg=
+github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg=
+github.com/Azure/azure-sdk-for-go/sdk/internal v1.8.0 h1:jBQA3cKT4L2rWMpgE7Yt3Hwh2aUj8KXjIGLxjHeYNNo=
+github.com/Azure/azure-sdk-for-go/sdk/internal v1.8.0/go.mod h1:4OG6tQ9EOP/MT0NMjDlRzWoVFxfu9rN9B2X+tlSVktg=
 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.5.0 h1:AifHbc4mg0x9zW52WOpKbsHaDKuRhlI7TVl47thgQ70=
 github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.2 h1:YUUxeiOWgdAQE3pXt2H7QXzZs0q8UBjgRbl56qo8GYM=
 github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.2/go.mod h1:dmXQgZuiSubAecswZE+Sm8jkvEa7kQgTPVRvwL/nd0E=
@@ -45,8 +45,8 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P
 github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
 github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
-github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
-github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM=
+github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
 github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -121,8 +121,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2
 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
 github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
 github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
-github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
-github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
+github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU=
+github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
 github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
 github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc=
 github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
@@ -185,8 +185,8 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf
 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
 github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
-github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
-github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
+github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
+github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
 github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
 github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/stephens2424/writerset v1.0.2/go.mod h1:aS2JhsMn6eA7e82oNmW4rfsgAOp9COBTTl8mzkwADnc=
@@ -250,8 +250,8 @@ golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
 golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
 golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
-golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs=
-golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
+golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo=
+golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
diff --git a/internal/fs/file_unix.go b/internal/fs/file_unix.go
index b562d15b1..65f10c844 100644
--- a/internal/fs/file_unix.go
+++ b/internal/fs/file_unix.go
@@ -29,7 +29,7 @@ func TempFile(dir, prefix string) (f *os.File, err error) {
 	return f, nil
 }
 
-// isNotSupported returns true if the error is caused by an unsupported file system feature.
+// isNotSuported returns true if the error is caused by an unsupported file system feature.
 func isNotSupported(err error) bool {
 	if perr, ok := err.(*os.PathError); ok && perr.Err == syscall.ENOTSUP {
 		return true
diff --git a/internal/fs/fs_local_vss.go b/internal/fs/fs_local_vss.go
index 718dfc46d..48ab165f1 100644
--- a/internal/fs/fs_local_vss.go
+++ b/internal/fs/fs_local_vss.go
@@ -72,7 +72,7 @@ type LocalVss struct {
 var _ FS = &LocalVss{}
 
 // parseMountPoints try to convert semicolon separated list of mount points
-// to map of lowercased volume GUID paths. Mountpoints already in volume
+// to map of lowercased volume GUID pathes. Mountpoints already in volume
 // GUID path format will be validated and normalized.
 func parseMountPoints(list string, msgError ErrorHandler) (volumes map[string]struct{}) {
 	if list == "" {
diff --git a/internal/repository/prune.go b/internal/repository/prune.go
index d5fdbba07..b8d3ba97b 100644
--- a/internal/repository/prune.go
+++ b/internal/repository/prune.go
@@ -25,9 +25,9 @@ type PruneOptions struct {
 	MaxUnusedBytes func(used uint64) (unused uint64) // calculates the number of unused bytes after repacking, according to MaxUnused
 	MaxRepackBytes uint64
 
-	RepackCacheableOnly bool
-	RepackSmall         bool
-	RepackUncompressed  bool
+	RepackCachableOnly bool
+	RepackSmall        bool
+	RepackUncompressed bool
 }
 
 type PruneStats struct {
@@ -381,7 +381,7 @@ func decidePackAction(ctx context.Context, opts PruneOptions, repo *Repository,
 			stats.Blobs.Remove += p.unusedBlobs
 			stats.Size.Remove += p.unusedSize
 
-		case opts.RepackCacheableOnly && p.tpe == restic.DataBlob:
+		case opts.RepackCachableOnly && p.tpe == restic.DataBlob:
 			// if this is a data pack and --repack-cacheable-only is set => keep pack!
 			stats.Packs.Keep++
 
diff --git a/internal/restic/node_windows.go b/internal/restic/node_windows.go
index 2785e0412..05dca7cd9 100644
--- a/internal/restic/node_windows.go
+++ b/internal/restic/node_windows.go
@@ -228,7 +228,7 @@ func (node Node) restoreGenericAttributes(path string, warn func(msg string)) (e
 	return errors.CombineErrors(errs...)
 }
 
-// genericAttributesToWindowsAttrs converts the generic attributes map to a WindowsAttributes and also returns a string of unknown attributes that it could not convert.
+// genericAttributesToWindowsAttrs converts the generic attributes map to a WindowsAttributes and also returns a string of unkown attributes that it could not convert.
 func genericAttributesToWindowsAttrs(attrs map[GenericAttributeType]json.RawMessage) (windowsAttributes WindowsAttributes, unknownAttribs []GenericAttributeType, err error) {
 	waValue := reflect.ValueOf(&windowsAttributes).Elem()
 	unknownAttribs, err = genericAttributesToOSAttrs(attrs, reflect.TypeOf(windowsAttributes), &waValue, "windows")
diff --git a/internal/restorer/restorer.go b/internal/restorer/restorer.go
index a80714fa7..85132c8b4 100644
--- a/internal/restorer/restorer.go
+++ b/internal/restorer/restorer.go
@@ -44,7 +44,7 @@ type OverwriteBehavior int
 const (
 	OverwriteAlways OverwriteBehavior = iota
 	// OverwriteIfChanged is like OverwriteAlways except that it skips restoring the content
-	// of files with matching size&mtime. Metadata is always restored.
+	// of files with matching size&mtime. Metatdata is always restored.
 	OverwriteIfChanged
 	OverwriteIfNewer
 	OverwriteNever


Test patch:
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 3ca7a9edb..796a614b1 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -325,7 +325,7 @@ jobs:
 
       - name: Build and push
         id: docker_build
-        uses: docker/build-push-action@v6
+        uses: docker/build-push-action@v5
         with:
           push: false
           context: .
diff --git a/cmd/restic/cmd_forget_integration_test.go b/cmd/restic/cmd_forget_integration_test.go
index 96dd7c63e..06487a841 100644
--- a/cmd/restic/cmd_forget_integration_test.go
+++ b/cmd/restic/cmd_forget_integration_test.go
@@ -54,7 +54,7 @@ func TestRunForgetSafetyNet(t *testing.T) {
 	err = testRunForgetMayFail(env.gopts, ForgetOptions{})
 	rtest.Assert(t, strings.Contains(err.Error(), `no policy was specified, no snapshots will be removed`), "wrong error message got %v", err)
 
-	// `forget --host example --unsafe-allow-remove-all` should work
+	// `forget --host example --unsafe-allow-remmove-all` should work
 	testRunForget(t, env.gopts, ForgetOptions{
 		UnsafeAllowRemoveAll: true,
 		GroupBy:              restic.SnapshotGroupByOptions{Host: true, Path: true},
diff --git a/cmd/restic/cmd_prune_integration_test.go b/cmd/restic/cmd_prune_integration_test.go
index 746eb5cc9..19c430716 100644
--- a/cmd/restic/cmd_prune_integration_test.go
+++ b/cmd/restic/cmd_prune_integration_test.go
@@ -51,8 +51,8 @@ func testPruneVariants(t *testing.T, unsafeNoSpaceRecovery bool) {
 		testPrune(t, opts, checkOpts)
 	})
 
-	t.Run("CacheableOnly"+suffix, func(t *testing.T) {
-		opts := PruneOptions{MaxUnused: "5%", RepackCacheableOnly: true, unsafeRecovery: unsafeNoSpaceRecovery}
+	t.Run("CachableOnly"+suffix, func(t *testing.T) {
+		opts := PruneOptions{MaxUnused: "5%", RepackCachableOnly: true, unsafeRecovery: unsafeNoSpaceRecovery}
 		checkOpts := CheckOptions{ReadData: true}
 		testPrune(t, opts, checkOpts)
 	})
diff --git a/internal/backend/cache/backend_test.go b/internal/backend/cache/backend_test.go
index 7addc275d..0de90471e 100644
--- a/internal/backend/cache/backend_test.go
+++ b/internal/backend/cache/backend_test.go
@@ -135,7 +135,7 @@ func TestOutOfBoundsAccess(t *testing.T) {
 
 	// load out of bounds
 	err := wbe.Load(context.TODO(), h, 100, 100, func(rd io.Reader) error {
-		t.Error("cache returned non-existent file section")
+		t.Error("cache returned non-existant file section")
 		return errors.New("broken")
 	})
 	test.Assert(t, strings.Contains(err.Error(), " is too short"), "expected too short error, got %v", err)
@@ -147,7 +147,7 @@ func TestOutOfBoundsAccess(t *testing.T) {
 
 	// start within bounds, but request too large chunk
 	err = wbe.Load(context.TODO(), h, 100, 0, func(rd io.Reader) error {
-		t.Error("cache returned non-existent file section")
+		t.Error("cache returned non-existant file section")
 		return errors.New("broken")
 	})
 	test.Assert(t, strings.Contains(err.Error(), " is too short"), "expected too short error, got %v", err)
diff --git a/internal/bloblru/cache_test.go b/internal/bloblru/cache_test.go
index d25daf764..b2becd256 100644
--- a/internal/bloblru/cache_test.go
+++ b/internal/bloblru/cache_test.go
@@ -79,14 +79,14 @@ func TestCacheGetOrCompute(t *testing.T) {
 		return data1, nil
 	})
 	rtest.OK(t, err)
-	rtest.Equals(t, &data1[0], &blob[0], "wrong buffer returned")
+	rtest.Equals(t, &data1[0], &blob[0], "wrong buffer returend")
 
 	// now the buffer should be returned without calling the compute function
 	blob, err = c.GetOrCompute(id1, func() ([]byte, error) {
 		return nil, e
 	})
 	rtest.OK(t, err)
-	rtest.Equals(t, &data1[0], &blob[0], "wrong buffer returned")
+	rtest.Equals(t, &data1[0], &blob[0], "wrong buffer returend")
 
 	// check concurrency
 	wg, _ := errgroup.WithContext(context.TODO())
diff --git a/internal/repository/index/associated_data_test.go b/internal/repository/index/associated_data_test.go
index 82dd9908d..715e3391a 100644
--- a/internal/repository/index/associated_data_test.go
+++ b/internal/repository/index/associated_data_test.go
@@ -128,7 +128,7 @@ func TestAssociatedSetWithExtendedIndex(t *testing.T) {
 	mi.StorePack(blob2.PackID, []restic.Blob{blob2.Blob})
 	test.OK(t, mi.SaveIndex(context.TODO(), &noopSaver{}))
 
-	// non-existent
+	// non-existant
 	test.Equals(t, false, bs.Has(of))
 	// set
 	bs.Set(of, 5)
diff --git a/internal/repository/index/indexmap_test.go b/internal/repository/index/indexmap_test.go
index f34e6a1d3..e0db9cb40 100644
--- a/internal/repository/index/indexmap_test.go
+++ b/internal/repository/index/indexmap_test.go
@@ -156,7 +156,7 @@ func TestIndexMapFirstIndex(t *testing.T) {
 
 	for i := 1; i <= 400; i++ {
 		r.Read(id[:])
-		rtest.Equals(t, -1, m.firstIndex(id), "wrong firstIndex for nonexistent id")
+		rtest.Equals(t, -1, m.firstIndex(id), "wrong firstIndex for nonexistant id")
 
 		m.add(id, 0, 0, 0, 0)
 		idx := m.firstIndex(id)
diff --git a/internal/repository/prune_test.go b/internal/repository/prune_test.go
index 02eefc463..17dfafa4e 100644
--- a/internal/repository/prune_test.go
+++ b/internal/repository/prune_test.go
@@ -80,9 +80,9 @@ func TestPrune(t *testing.T) {
 		{
 			name: "cachableonly",
 			opts: repository.PruneOptions{
-				MaxRepackBytes:      math.MaxUint64,
-				MaxUnusedBytes:      func(used uint64) (unused uint64) { return used / 20 },
-				RepackCacheableOnly: true,
+				MaxRepackBytes:     math.MaxUint64,
+				MaxUnusedBytes:     func(used uint64) (unused uint64) { return used / 20 },
+				RepackCachableOnly: true,
 			},
 		},
 		{
diff --git a/internal/restic/node_windows_test.go b/internal/restic/node_windows_test.go
index 4fd57bbb7..29a42e9e2 100644
--- a/internal/restic/node_windows_test.go
+++ b/internal/restic/node_windows_test.go
@@ -70,7 +70,7 @@ func getNode(name string, fileType string, genericAttributes map[GenericAttribut
 func getWindowsAttr(t *testing.T, testPath string, node *Node) WindowsAttributes {
 	windowsAttributes, unknownAttribs, err := genericAttributesToWindowsAttrs(node.GenericAttributes)
 	test.OK(t, errors.Wrapf(err, "Error getting windows attr from generic attr: %s", testPath))
-	test.Assert(t, len(unknownAttribs) == 0, "Unknown attribs found: %s for: %s", unknownAttribs, testPath)
+	test.Assert(t, len(unknownAttribs) == 0, "Unkown attribs found: %s for: %s", unknownAttribs, testPath)
 	return windowsAttributes
 }
 
@@ -263,7 +263,7 @@ func TestNewGenericAttributeType(t *testing.T) {
 		_, ua, err := genericAttributesToWindowsAttrs(node.GenericAttributes)
 		test.OK(t, err)
 		// Since this GenericAttribute is unknown to this version of the software, it will not get set on the file.
-		test.Assert(t, len(ua) == 0, "Unknown attributes: %s found for path: %s", ua, testPath)
+		test.Assert(t, len(ua) == 0, "Unkown attributes: %s found for path: %s", ua, testPath)
 	}
 }
 
diff --git a/internal/restorer/restorer_test.go b/internal/restorer/restorer_test.go
index d70f1f162..3becf7c7a 100644
--- a/internal/restorer/restorer_test.go
+++ b/internal/restorer/restorer_test.go
@@ -1162,7 +1162,7 @@ func TestRestoreIfChanged(t *testing.T) {
 			rtest.Equals(t, origData, string(data), "expected original file content")
 		} else {
 			// restore should not have noticed the changed file content
-			rtest.Equals(t, modData, string(data), "expected modified file content")
+			rtest.Equals(t, modData, string(data), "expeced modified file content")
 		}
 	}
 }
diff --git a/internal/restorer/restorer_unix_test.go b/internal/restorer/restorer_unix_test.go
index 59048e908..9523440cf 100644
--- a/internal/restorer/restorer_unix_test.go
+++ b/internal/restorer/restorer_unix_test.go
@@ -18,7 +18,7 @@ import (
 	restoreui "github.com/restic/restic/internal/ui/restore"
 )
 
-func TestRestorerRestoreEmptyHardlinkedFields(t *testing.T) {
+func TestRestorerRestoreEmptyHardlinkedFileds(t *testing.T) {
 	repo := repository.TestRepository(t)
 
 	sn, _ := saveSnapshot(t, repo, Snapshot{
diff --git a/internal/restorer/restorer_windows_test.go b/internal/restorer/restorer_windows_test.go
index 61d075061..90ece474d 100644
--- a/internal/restorer/restorer_windows_test.go
+++ b/internal/restorer/restorer_windows_test.go
@@ -356,29 +356,29 @@ func verifyFileAttributes(t *testing.T, mainFilePath string, attr FileAttributes
 	rtest.OK(t, err)
 	//Test positive and negative scenarios
 	if attr.ReadOnly {
-		rtest.Assert(t, fileAttributes&windows.FILE_ATTRIBUTE_READONLY != 0, "Expected read only attribute.")
+		rtest.Assert(t, fileAttributes&windows.FILE_ATTRIBUTE_READONLY != 0, "Expected read only attibute.")
 	} else {
-		rtest.Assert(t, fileAttributes&windows.FILE_ATTRIBUTE_READONLY == 0, "Unexpected read only attribute.")
+		rtest.Assert(t, fileAttributes&windows.FILE_ATTRIBUTE_READONLY == 0, "Unexpected read only attibute.")
 	}
 	if attr.Hidden {
-		rtest.Assert(t, fileAttributes&windows.FILE_ATTRIBUTE_HIDDEN != 0, "Expected hidden attribute.")
+		rtest.Assert(t, fileAttributes&windows.FILE_ATTRIBUTE_HIDDEN != 0, "Expected hidden attibute.")
 	} else {
-		rtest.Assert(t, fileAttributes&windows.FILE_ATTRIBUTE_HIDDEN == 0, "Unexpected hidden attribute.")
+		rtest.Assert(t, fileAttributes&windows.FILE_ATTRIBUTE_HIDDEN == 0, "Unexpected hidden attibute.")
 	}
 	if attr.System {
-		rtest.Assert(t, fileAttributes&windows.FILE_ATTRIBUTE_SYSTEM != 0, "Expected system attribute.")
+		rtest.Assert(t, fileAttributes&windows.FILE_ATTRIBUTE_SYSTEM != 0, "Expected system attibute.")
 	} else {
-		rtest.Assert(t, fileAttributes&windows.FILE_ATTRIBUTE_SYSTEM == 0, "Unexpected system attribute.")
+		rtest.Assert(t, fileAttributes&windows.FILE_ATTRIBUTE_SYSTEM == 0, "Unexpected system attibute.")
 	}
 	if attr.Archive {
-		rtest.Assert(t, fileAttributes&windows.FILE_ATTRIBUTE_ARCHIVE != 0, "Expected archive attribute.")
+		rtest.Assert(t, fileAttributes&windows.FILE_ATTRIBUTE_ARCHIVE != 0, "Expected archive attibute.")
 	} else {
-		rtest.Assert(t, fileAttributes&windows.FILE_ATTRIBUTE_ARCHIVE == 0, "Unexpected archive attribute.")
+		rtest.Assert(t, fileAttributes&windows.FILE_ATTRIBUTE_ARCHIVE == 0, "Unexpected archive attibute.")
 	}
 	if attr.Encrypted {
-		rtest.Assert(t, fileAttributes&windows.FILE_ATTRIBUTE_ENCRYPTED != 0, "Expected encrypted attribute.")
+		rtest.Assert(t, fileAttributes&windows.FILE_ATTRIBUTE_ENCRYPTED != 0, "Expected encrypted attibute.")
 	} else {
-		rtest.Assert(t, fileAttributes&windows.FILE_ATTRIBUTE_ENCRYPTED == 0, "Unexpected encrypted attribute.")
+		rtest.Assert(t, fileAttributes&windows.FILE_ATTRIBUTE_ENCRYPTED == 0, "Unexpected encrypted attibute.")
 	}
 }