commit c7c903c480e5caf80230d25affdc6bd7747266d1
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Sun May 31 10:30:24 2026 +0100

    build: give each CI matrix job its own Go build cache
    
    The build matrix relied on setup-go's built-in cache, which keys only on
    go.sum with no job differentiation. All matrix jobs computed the same
    cache key and raced to save it; since cache keys are immutable, only the
    first job to finish saved its cache. That winner was usually a fast job
    whose build cache contained none of the cross-compiled architectures, so
    the compile_all and ci_beta steps started from a cold cache on every run.
    
    Disable setup-go's cache and add an explicit actions/cache keyed on the
    job name (plus runner OS, Go version, week and go.sum) so each job keeps
    its own module and build cache between runs. This lets the cross-compile
    steps reuse per-architecture build artifacts.
    
    Measured on CI, comparing a cold-cache run against the following
    warm-cache run:
    
        other_os    19m33s -> 3m29s    (compile_all 14m16s -> 19s)
        linux       28m47s -> 11m29s   (deploy 11m18s -> 1m36s,
                                         race test 8m19s -> 4m29s)
    
    Both jobs now finish well under 15 minutes once the cache is warm.

commit 2dbad62a11db3a045347e97d0be5ef0bf078292d
Author: Yakov Till <yakov.till@gmail.com>
Date:   Thu May 21 21:48:47 2026 +0200

    iclouddrive: fix ADP/PCS cookie acquisition for iCloud Drive

commit 74436281edab9727ceafbe58b71bf41de62bb33d
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Fri May 29 17:13:39 2026 +0100

    drive: fix server-side move failing on shared drives with duplicate dirs - fixes #9472
    
    When moving a file rclone removed the file from its old parent by
    looking the parent ID up from the path using the directory cache. When
    the source contained two directories with the same name and path, the
    cache could resolve to the wrong duplicate, so the removeParents
    request didn't match the file's real parent.
    
    This left the file with both its old and new parent, which fails on
    shared drives with:
    
        A shared drive item must have exactly one parent., teamDrivesParentLimit
    
    This uses the source object's actual parent ID instead when it is
    known, falling back to the path lookup only when the object has zero
    or multiple parents.

commit aec530d1e8bb6eab44a2f473ba564b6f6bb0d391
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Sat May 30 17:58:36 2026 +0100

    Add Puneet Dixit to contributors

commit 1c92cecaa3cfce5c81f40dbaf7417ec70c092df0
Author: Puneet Dixit <puneetdixit4321@gmail.com>
Date:   Sat May 30 15:31:20 2026 +0530

    sftp: add --sftp-encoding support

commit d2b5ff8384a80fc8194436836e56a665df1c3c4e
Author: Leon Brocard <acme@astray.com>
Date:   Fri Mar 20 17:12:55 2026 +0000

    local: fix getXattr returning empty map instead of nil
    
    At least on my macOS Sequoia 15.7.4, the system automatically adds a
    com.apple.provenance xattr to files created by processes. This xattr
    lacks the "user." prefix so getXattr filters it out, but the metadata
    map was already allocated, resulting in an empty non-nil map being
    returned instead of nil.
    
    This caused TestMetadata/Symlink/Xattr and TestMetadata/File/Xattr
    to fail because they assert the return value is nil when no user
    xattrs are present.
    
    The fix checks if the metadata map is empty after filtering and
    returns nil if so.

commit 79f42d37ff4ad4a1637148c491cd69b9f3a261a9
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Thu May 28 00:28:21 2026 +0100

    serve s3: fix multipart ListParts pagination returning wrong part numbers - fixes #9460
    
    Listing the parts of a multipart upload with a MaxParts smaller than
    the number of parts returned wrong PartNumber values and duplicate
    parts on pages after the first, and the part number marker regressed
    instead of advancing, causing clients to loop forever.
    
    This bumps github.com/rclone/gofakes3 to v0.0.6 pick up the fix.

commit 387be8d8c03a4340a7547d26fd7559a4af5f51ec
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Thu May 28 15:45:40 2026 +0100

    drime: fix directory rename leaving the renamed folder empty in VFS
    
    Drime's folder rename returns success immediately but the children
    listing of the renamed folder briefly returns empty before settling,
    which made VFS see an empty directory right after a successful rename
    and broke subsequent operations on its contents.
    
    After a successful DirMove, poll the renamed folder's listing until it
    shows the pre-rename child count, with a 30s timeout and exponential
    backoff. The backend integration test already tolerated this via its
    own list-consistency retries; this brings VFS into line.
    
    Fixes #9450

commit d742334be5674ca663a8d2d514e0f2befe6452df
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Fri May 29 12:51:17 2026 +0100

    Add Brian King to contributors

commit c262d86ab2ebc8f17d0eafc45369efa9d10a6650
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Fri May 29 12:51:17 2026 +0100

    Add Hakan İSMAİL to contributors

commit f2832217aa1f40a4295260f7095ec1e8bd561281
Author: Hakan İSMAİL <93117749+Hakanbaban53@users.noreply.github.com>
Date:   Thu May 28 19:51:58 2026 +0300

    rc: include OAuth authorization URL in rc config/oauthstatus response

commit 8a13055688e6609015aded9c9ec6b64ca72d9494
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Tue May 26 11:03:11 2026 +0100

    drime: remove stale mux_status field from Item
    
    The API no longer returns mux_status (it now uses transcode_status and
    stream_status). The field was unused, so just remove it.

commit b6cfcb97c21e322bae4d10540aa869af01c088de
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Tue May 26 11:02:40 2026 +0100

    drime: remove duplicate upload_cutoff config option
    
    The upload_cutoff option was registered twice with identical content.
    Remove the second copy.

commit afb29064e43a4d88b81122363a46cdf08ff0c304
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Tue May 26 10:26:24 2026 +0100

    drime: fix files being uploaded to the wrong directory
    
    Large files (sent as multipart uploads) were placed in the wrong folder
    for two reasons:
    
    - the parent folder was sent as "parent_id", but the API ignores that
      and expects "parentId", so the parent was never honoured
    - relativePath was sent as the full path from the drive root, which made
      the server build folders from it and silently drop any "0" path
      segment (e.g. ".../data/0/file" lost the "0")
    
    Send the parent as "parentId" and use just the leaf as relativePath,
    matching the working single-part upload. This also lets us remove the
    now-unneeded absolute-path resolution code.
    
    Fixes #9392
    Co-authored-by: Brian King <BrianDKing@gmail.com>

commit 8cb4bb19b0a7dff09abc2b332a05b98895d09af1
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Tue May 26 09:46:22 2026 +0100

    drime: fix server-side copy and move failing with Cloudflare 520 error
    
    The drime origin returns a malformed response (reported by Cloudflare as
    a 520 error) for a literal PUT request to the file-entries update
    endpoint, which broke renaming, and so server-side copy and move.
    
    Use a POST with the X-HTTP-Method-Override: PUT header instead - the API
    routes this to the same handler and it works reliably.
    
    Also retry Cloudflare 520-524 errors which may occur transiently.

commit f71bebab4401bd81564f796d4633f202c48a9e3a
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Sun May 24 17:21:26 2026 +0100

    serve sftp: use the requested atime when setting file times
    
    When a SETSTAT request set the access and modification times, the
    handler passed the modification time for both, discarding the
    requested access time. Pass the requested access time through instead.
    
    The VFS currently ignores the atime, but it might use it one day.

commit 54cd7d67508fdb2639a1fb7219665eccd0588d7d
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Sun May 24 17:08:49 2026 +0100

    serve sftp: implement statvfs@openssh.com to report disk usage
    
    The statvfs@openssh.com extension was advertised but returned an
    unsupported status, so clients couldn't query the amount of free and
    used space. Implement it using the VFS Statfs method, which reports the
    backend's usage where the backend supports About.

commit 90308de5d1fb3f360e832bcda26fe515fe141fb5
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Sun May 24 14:34:59 2026 +0100

    serve sftp: fix truncate request being silently ignored
    
    The SFTP serve handler ignored the size attribute of SETSTAT/FSETSTAT
    requests, only acting on the modification time. This meant a client
    asking to truncate a file (eg setting the final size of an upload, or
    an explicit truncate) had no effect at all.
    
    This respects the size attribute (if present) by truncating the file
    to the requested size.

commit 4dead760dd4aae993b032a6087d24fcc3e475ff3
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Sun May 24 13:33:21 2026 +0100

    serve sftp: fix file corruption when a client resumes an upload
    
    The SFTP serve write handler always opened files with O_TRUNC,
    ignoring the flags requested in the SFTP OPEN packet. Some clients
    (notably WinSCP's "Process in Background", which resumes an upload on
    a second connection) re-open the partially written file without the
    truncate flag and continue writing from the offset they had reached,
    relying on the existing data being preserved. Forcing O_TRUNC zeroed
    that prefix, so the start of the uploaded file ended up as a block of
    zero bytes.
    
    This fix respects the requested open flags instead so a resume open
    without truncate keeps the already written data intact.
    
    See: https://forum.rclone.org/t/rclone-serve-sftp-winscp-background-mode-uploading-causes-file-corruption/53841

commit 6efe605b97cbced954136223ebe71cf92a939434
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Mon May 25 20:43:17 2026 +0100

    Add Valerij Fredriksen to contributors

commit 5794a22983da5a56d1dca92a3301873436a66eed
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Mon May 25 20:43:17 2026 +0100

    Add caltechustc to contributors

commit 35b95aa2a322e7b1efaec239db97eea7324fb064
Author: FTCHD <144691102+FTCHD@users.noreply.github.com>
Date:   Mon May 25 21:59:09 2026 +0300

    rc: add config/oauthstop and config/oauthstatus to control oauth listener
    
    rclone starts a http listener if the user is adding a remote that requires
    oauth. The problem is that sometimes this breaks or the user stops midway with
    no way of us knowing that. Once that happens, clients of the api break. In the
    best scenario, new remotes cannot be configured without a restart.
    
    This change adds 2 oauth related endpoints, one to get the status of the listener
    and one to stop it. This allows clients to go back to normal without having to
    restart rclone.
    
    - config/oauthstop - cancels an in-progress OAuth flow and releases the port.
    - config/oauthstatus - reports "running" / "stopped".

commit 605eb306741d398fb720ce381f25e125b86c9281
Author: FTCHD <144691102+FTCHD@users.noreply.github.com>
Date:   Mon May 25 21:50:41 2026 +0300

    rc: respond with 202 if prefer-async header is passed
    
    Make rc respond with a 202 status code (instead of 200) if `Prefer: respond-
    async` was passed. Keeps backwards compatibility for current clients while also
    allowing the OpenAPI schema & generators to differentiate the responses
    properly.

commit 675806067afc904390c49a09094b844294493b65
Author: Valerij Fredriksen <freva@users.noreply.github.com>
Date:   Fri May 22 16:57:59 2026 +0200

    mount2: add --allow-idmap to advertise FUSE_ALLOW_IDMAP
    
    Lets the kernel id-map a mount2 mount into a user namespace
    (e.g. Kubernetes pods with hostUsers: false). Off by default;
    requires Linux 6.12+ and implies default_permissions.

commit be3bfe2d19a34ba2b1f204f67704d7051a6ec87b
Author: caltechustc <caltechustc@outlook.com>
Date:   Sat May 23 20:31:41 2026 +0800

    refactor: use slices.Contains to simplify code
    
    Signed-off-by: caltechustc <caltechustc@outlook.com>

commit 04d1e2563a39654bd471a01d32bdbc486f354a74
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Mon May 18 18:12:02 2026 +0100

    serve nfs: allow NFS clients to mount subpaths of the served remote
    
    Previously the Mount RPC ignored the path component of the mount
    request, so `server:/sub/dir` and `server:/` both landed at the root
    of the served remote. The Mount handler now cleans the requested path
    with path.Clean, looks it up in the VFS and serves a billy.Filesystem
    rooted at that directory, refusing the mount if the path does not
    exist or is not a plain directory.
    
    A pathRewriter cache wraps the inner handle cache so that the same
    file always produces the same NFS file handle regardless of which
    mount minted it (and stable across server restarts for the disk and
    symlink caches). This matches the traditional NFS expectation that a
    subpath mount behaves like `cd` into a subtree.
    
    nfsmount gains a --nfs-mount-path flag (default /) so clients can
    select a subpath at mount time. This replaces a latent misuse of
    --volname as the NFS mount path that was previously masked by the
    server ignoring it.
    
    Fixes #9442

commit 761157714b071806b054be8e920370b5048ff447
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Sun May 24 18:07:22 2026 +0100

    Add tomholford to contributors

commit f22a1b05a8d06f74b967259b289d21c3fb93cb38
Author: tomholford <16504501+tomholford@users.noreply.github.com>
Date:   Sun May 24 09:50:01 2026 -0700

    protondrive: implement shouldRetry instead of always returning false
    
    shouldRetry was a stub returning false unconditionally, which makes
    protondrive the only rclone backend that disables pacer-level retries
    entirely. Every other backend at minimum falls back to
    fserrors.ShouldRetry(err) so genuine transport-level transients (TCP
    resets, brief 5xx) get retried.
    
    - Use errors.As to unwrap proton.APIError instead of string matching
    - Retry transient storage block errors (Code=200501)
    - Retry server errors (5xx, except 503)
    - Skip 429 and 503 (handled by go-proton-api's resty retry layer
      via catchTooManyRequests / catchRetryAfter, which honours Retry-After)
    - Fall back to fserrors.ShouldRetry for non-API errors
    
    Co-authored-by: tomholford <tomholford@users.noreply.github.com>

commit 7dcbc8b4f3d89818642a22977d4307f836eafb6c
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Sat May 23 11:33:24 2026 +0100

    Changelog updates from Version v1.74.2

commit 05e5c05cdb6c2384805b5a6464b352241acb66e0
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Sat May 23 11:34:06 2026 +0100

    Add Iizuki to contributors

commit ad8a108453f3ce983fb6c3675ced694ff6bc3b53
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Fri May 22 12:08:35 2026 +0100

    lib/http: replace deprecated h2c.NewHandler with http.Server.Protocols
    
    The golang.org/x/net/http2/h2c package was deprecated in v0.54.0 in
    favour of setting the http.Server Protocols field to enable unencrypted
    HTTP/2.
    
    This replaces the h2c.NewHandler wrapping added in e863f751f with
    http.Server.Protocols, which is supported by the standard library
    since Go 1.24.
    
    Note that the stdlib only supports HTTP/2 prior-knowledge on cleartext
    connections, not HTTP/1.1 Upgrade: h2c negotiation. In practice clients
    use prior-knowledge or require TLS, so this should not affect users.

commit a03070c960afdfc074a3d56681d1c1a8a74ea8c1
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Fri May 22 11:54:29 2026 +0100

    build: update golang.org/x dependencies to address multiple CVEs
    
    Upgrade to v0.55.0 of golang.org/x/net in order to address:
    
    - CVE-2026-42506: html: incorrect handling of namespaced elements in foreign content
    - CVE-2026-39821: idna: failure to reject ASCII-only Punycode-encoded labels
    - CVE-2026-42502: html: incorrect handling of HTML elements in foreign content
    - CVE-2026-25680: html: denial of service when parsing arbitrary HTML
    - CVE-2026-25681: html: incorrect handling of character references in DOCTYPE nodes
    - CVE-2026-27136: html: duplicate attributes can cause XSS
    
    Upgrade to version v0.52.0 of golang.org/x/crypto to address:
    
    - CVE-2026-46598: ssh/agent: pathological inputs can lead to client panic
    - CVE-2026-46597: ssh: byte arithmetic causes underflow and panic
    - CVE-2026-39828: ssh: bypass of certificate restrictions
    - CVE-2026-39835: ssh: server panic during CheckHostKey/Authenticate
    - CVE-2026-39833: ssh/agent: key constraints not enforced
    - CVE-2026-39832: ssh/agent: agent constraints dropped when forwarding keys
    - CVE-2026-39827: ssh: memory leak when rejecting channels can lead to DoS
    - CVE-2026-39830: ssh: client can cause server deadlock on unexpected responses
    - CVE-2026-39829: ssh: pathological RSA/DSA parameters may cause DoS
    - CVE-2026-39831: ssh: bypass of FIDO/U2F security keys physical interaction
    - CVE-2026-39834: ssh: infinite loop on large channel writes
    - CVE-2026-42508: ssh/knownhosts: auth bypass via unenforced @revoked status
    - CVE-2026-46595: ssh: VerifiedPublicKeyCallback permissions skip enforcement
    
    Upgrade to version v0.41.0 of golang.org/x/image to address:
    
    - CVE-2026-42500: bmp: panic when reading out of bound palette index
    - CVE-2026-33809: tiff: excessive resource consumption in PackBits decompression
    
    Upgrade to version v0.45.0 of golang.org/x/sys to address:
    
    - CVE-2026-39824: windows: integer overflow in NewNTUnicodeString

commit 28d6b0b7b906da70afdc036ba5bb21f3c86613b8
Author: Iizuki <36295229+Iizuki@users.noreply.github.com>
Date:   Thu May 21 12:09:25 2026 +0300

    docs: s3: update doc link for force_path_style

commit cbc64a6e6c148995a5c3050c61eedf48afe7da37
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Wed May 20 12:08:05 2026 +0100

    s3: add new MEGA S4 endpoints on megas4.com including Asia-Pacific region
    
    MEGA S4 has launched a new dedicated domain megas4.com with three new
    endpoints, including their first Asia-Pacific location in Tokyo, plus
    new endpoints in Paris and Barcelona. The existing Amsterdam,
    Luxembourg, Montreal and Vancouver locations have been renamed onto
    the new domain.
    
    All current s4.mega.io endpoints continue to be supported and are
    retained as legacy options. New accounts use the megas4.com endpoints.

commit d97056cb22e4a81e44d997c9ae7a0f9f1ab984dd
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Wed May 20 11:52:10 2026 +0100

    docs: fix heading levels so sections appear in the table of contents
    
    The "Import/Export of google documents" section in drive.md and the
    "--b2-versions" examples section in b2.md were both at H4 instead of H3,
    which excluded them from the ToC even though they are top-level topics
    in their respective sections.

commit 3a914d908891e8621ff5e86cfede1318c97c9935
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Wed May 20 12:09:15 2026 +0100

    Add KyokoMiki to contributors

commit 7d4829bf7d80879668f505f16630df35263db3cf
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Wed May 20 12:09:14 2026 +0100

    Add TaterLi to contributors

commit 08bafc38ba328b10fa982d7796dc4fd0d645baa3
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Wed May 20 12:09:14 2026 +0100

    Add William Tange to contributors

commit ec011c065869dce19f19ca574c36b95170464155
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Wed May 20 12:09:14 2026 +0100

    Add Lucky945H to contributors

commit 5c6d13338971f2f183f1a0fb62ffa45bab4fa524
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Wed May 20 12:09:14 2026 +0100

    Add Sai Asish Y to contributors

commit c917ad9d36940bb644dc010a6332826af189f7a2
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Wed May 20 12:09:14 2026 +0100

    Add Tore Anderson to contributors

commit 7bd05530ebfae164ebc453d62310351289dbb4e2
Author: TaterLi <admin@lijingquan.net>
Date:   Tue Jun 23 15:00:44 2020 +0800

    onedrive: add support for no admin mode
    
    Add tenant_url configuration option for accessing OneDrive/SharePoint
    without admin privileges. When tenant_url is set, rclone uses the
    SharePoint v2.0 API endpoint instead of the standard Microsoft Graph
    API.
    
    Co-Authored-By: KyokoMiki <161209740+kyokomiki@users.noreply.github.com>

commit 930a7335947d6d42bbc5d5bde477923167b22768
Author: William Tange <github@tan.ge>
Date:   Tue May 19 10:18:58 2026 +0000

    protondrive: fix corrupted on transfer: sha1 hashes differ
    
    Some SHA1 hashes of protondrive files are uppercase, so always
    converting to lowercase before comparing seems to be the solution.
    
    Fixes #7345

commit f7d371fc378969841e9a853aecaf24be3ee7064e
Author: Lucky945H <1355363613@qq.com>
Date:   Sun May 17 00:52:59 2026 +0800

    vfs/vfscache: fix silent write failure when mounting with remote:.
    
    When mounting with 'remote:.' (dot notation for current directory),
    the '.' is passed through toOSPath() which encodes it to full-width
    '.' (U+FF0E) via EncodeDot. This caused the VFS cache data/meta root
    to be written to a full-width-dot directory while the local cache
    backend pointed to the canonicalized path, resulting in writes being
    cached but never uploaded.
    
    Fix by calling clean() on the relativeDirPath before toOSPath(),
    so path.Clean() strips the trailing '/.' removing the dot before
    encoding.

commit 793f2d2f06336496ad0efafaf6cad9cbe0bbf6e6
Author: Leon Brocard <acme@astray.com>
Date:   Fri May 15 19:12:47 2026 +0100

    docs: fix misspellings
    
    Fix several misspellings in documentation and config comments detected by `misspell`.

commit 75773e4d7230a0d165d8c9767ba139e4caf0d78b
Author: Sai Asish Y <say.apm35@gmail.com>
Date:   Wed May 13 00:15:50 2026 -0700

    webdav: honour auth_redirect on listAll PROPFIND - fixes #9159

commit 7e08899a2c72c0a1750279903e4b862c41f43533
Author: Tore Anderson <tore@fud.no>
Date:   Thu May 14 01:15:04 2026 +0200

    jottacloud: support whitelabel service Phonero Sky
    
    Phonero is a Norwegian mobile provider focusing on the enterprise
    market. They provide rebranded Jottacloud service through their «Phonero
    Sky» (Norwegian for «Phonero Cloud»).
    
    The Client ID `desktop` used by most of the other whitelabel services
    does not work for Phonero Sky. Both `desktop-win` and `desktop-mac`
    work, though. Authentication does not work when the `jotta-default`
    scope is present, so drop it. This results in a Client ID and scope
    setup that is identical with that of Let's Go Cloud (Germany).

commit 14cc32a1e456614c537ea10d6af31ea28c9717b8
Author: FTCHD <144691102+FTCHD@users.noreply.github.com>
Date:   Thu May 14 00:04:19 2026 +0300

    docs: add note about using config/update to reconnect an oauth remote

commit 72fcef51836de465e2f14edb15f332e455b24958
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Wed May 13 19:56:17 2026 +0100

    build: bump github.com/go-git/go-billy/v5 to 5.9.0 to fix CVE-2026-44740 (again)
    
    The previous commit had no content due to copilot deleting it as I was
    merging it!
    
    Bumps [github.com/go-git/go-billy/v5](https://github.com/go-git/go-billy) from 5.8.0 to 5.9.0.
    - [Release notes](https://github.com/go-git/go-billy/releases)
    - [Commits](https://github.com/go-git/go-billy/compare/v5.8.0...v5.9.0)
    
    ---
    updated-dependencies:
    - dependency-name: github.com/go-git/go-billy/v5
      dependency-version: 5.9.0
      dependency-type: direct:production
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

commit 57939d415708a215d421ffc1a635041bd9843052
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Tue May 12 12:04:50 2026 +0100

    docs: upgrade protondrive to tier 4 tests pass and community maintains

commit 70a0665dc7221673d02d5f68b53ea3e0e1be9e6d
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Wed May 13 20:00:53 2026 +0100

    Add Alvinwylim to contributors

commit 845c1d5e7bab4454ccf6f9a71c5a6f32f427df39
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Wed May 13 19:56:17 2026 +0100

    build: bump github.com/go-git/go-billy/v5 to 5.9.0 to fix CVE-2026-44740
    
    Bumps [github.com/go-git/go-billy/v5](https://github.com/go-git/go-billy) from 5.8.0 to 5.9.0.
    - [Release notes](https://github.com/go-git/go-billy/releases)
    - [Commits](https://github.com/go-git/go-billy/compare/v5.8.0...v5.9.0)
    
    ---
    updated-dependencies:
    - dependency-name: github.com/go-git/go-billy/v5
      dependency-version: 5.9.0
      dependency-type: direct:production
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

commit e95b64be086bf685b2778a84797a2cae8663c53e
Author: Alvinwylim <31592545+Alvinwylim@users.noreply.github.com>
Date:   Wed May 13 16:55:06 2026 +0800

    drime: fix 500 errors when listing shared folders
    
    When using the drime backend to access a folder shared from another
    Drime account (via root_folder_id config option), listing the folder's
    children fails with HTTP 500. This makes cross-account read-only
    mounts non-functional.
    
    This fixes the problem by changing listAll to use `folderId` instead
    of `parentIds[]`
    
    Fixes #9420

commit 35752d007950aa7d07246edd01dc291e2633a07a
Author: nielash <nielronash@gmail.com>
Date:   Sun May 10 23:49:03 2026 -0400

    bisync: fix --conflict-loser pathname with --conflict-resolve newer
    
    Before this change, --conflict-loser pathname assumed --conflict-resolve none,
    following the legacy behavior prior to v1.66. This produced unexpected behavior
    when used with a different --conflict-resolve option.
    
    This change fixes the issue by ensuring that --conflict-loser pathname looks for
    the correct name on the side not being renamed, when only one side should be
    renamed.
    
    https://forum.rclone.org/t/bisync-does-not-copy-the-winner-file-to-the-loser-site/53768

commit acda43a74f3c9fba063714c0c2756a8cb50eaed1
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Mon May 11 11:51:29 2026 +0100

    rc: remove duplicate metrics_addr option registration
    
    The metrics_addr option was registered twice: once explicitly and once
    implicitly via AddPrefix(libhttp.ConfigInfo, "metrics", ...). Both
    pointed at the same MetricsHTTP.ListenAddr field, so options/info
    returned a duplicate entry.
    
    Drop the explicit entry and use SetDefault to keep the empty default
    (so the metrics server stays off unless configured), matching the
    pattern already used for rc_addr.
    
    Fixes #9419

commit 4343b8094941ed59b0503748dee95eb3b6bd7a06
Author: John Volk <volkjohn@users.noreply.github.com>
Date:   Mon May 11 08:04:49 2026 -0400

    drime: fix file doesn't exists error when trying to delete
    
    When using rcat to upload a new version of a file that already existed,
    the file upload would succeed. The subsequent deletion of the old file
    is attempted after the upload. Drime appears to handle the deletion of
    the old file automatically and returns HTTP status code 422, stating
    the "The selected entry ids is invalid."
    
    The deletion and the rcat would fail before this change. This is with
    file history enabled on my Drime account.
    
    This change detects the error and ignores it since the file has
    already been deleted.

commit c00756810a5e05d2ad6f723687fc0f144dfd5f85
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Sat May 9 10:10:33 2026 +0100

    http: don't list parent directory when pointing at a single file
    
    When an HTTP URL points to a single file, listing the parent
    directory is unnecessary and may fail entirely on servers that
    disable directory listings but still serve HEAD/GET on the file.
    
    Remember the file name in the Fs and short-circuit List to return
    just that one object.
    
    See: https://forum.rclone.org/t/how-to-combine-on-the-fly-http-archive-remote-to-list-crc32s-in-a-http-hosted-zip/53761

commit 0157a1fb1e472ee70fd957a30d29fceb55eb64ed
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Fri May 8 17:15:06 2026 +0100

    Changelog updates from Version v1.74.1

commit fc50f3e731aab937264b3ce90827df9181c509e6
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Fri May 8 10:59:20 2026 +0100

    build: update golang.org/x/net to v0.53.0 to fix CVE-2026-33814

commit 869f77759484d1763c76d7e6d017cd33494e4dfb
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Fri May 8 10:47:04 2026 +0100

    build: fix multiple CVEs by upgrading to go1.26.3
    
    - CVE-2026-42501: cmd/go: malicious module proxy can bypass checksum database
    - CVE-2026-39825: net/http/httputil: ReverseProxy forwards queries with more than urlmaxqueryparams parameters
    - CVE-2026-39836: net: panic in Dial and LookupPort when handling NUL byte on Windows
    - CVE-2026-42499: net/mail: quadratic string concatenation in consumePhrase
    - CVE-2026-39820: net/mail: quadratic string concatentation in consumeComment
    - CVE-2026-39819: cmd/go: "go bug" follows symlinks in predictable temporary filenames
    - CVE-2026-39817: cmd/go: "go tool pack" does not sanitize output paths
    - CVE-2026-33814: net/http: infinite loop in HTTP/2 transport when given bad SETTINGS_MAX_FRAME_SIZE
    - CVE-2026-39826: html/template: escaper bypass leads to XSS
    - CVE-2026-33811: net: crash when handling long CNAME response
    - CVE-2026-39823: html/template: bypass of meta content URL escaping causes XSS

commit acb6155654dca78494448b80a61e79bb2e63085d
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Thu May 7 18:06:54 2026 +0100

    test_all: skip bisync normalization tests on Dropbox
    
    The bisync normalization test relies on uploading distinct NFC and NFD
    versions of the same filename and on the backend supporting in-place
    modtime updates. Dropbox normalizes unicode server-side (NFD -> NFC)
    and can't set modtime in place, so the test inevitably takes a
    different code path on Dropbox and the log diverges from the golden
    output without any functional difference.

commit f60213545bcb45263322676c022fadf8064f856c
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Thu May 7 11:07:41 2026 +0100

    sync: fix --fix-case rename on backends that need upload before overwrite
    
    operations.NeedTransfer's equality check may have deleted pair.Dst as
    a precursor to re-uploading it if SetModTime returns
    ErrorCantSetModTimeWithoutDelete (e.g. Dropbox). If so skip the eager
    delete of the destination if --fix-case will rename it to a different
    name. The rename itself replaces the destination, and any subsequent
    re-upload happens at the correctly-cased path.
    
    See: #8881

commit 92058f15c47f936b2e8db0e872b15cf330aa5cf8
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Thu May 7 17:44:20 2026 +0100

    Revert "sync: fix --fix-case rename failing on backends that can't update modtime"
    
    This reverts commit de67f29b3fe3693739c8d431ce4156dce73a7d6d.
    
    This solved the original Dropbox "from_lookup/not_found" failure, but
    broke --fix-case on case-sensitive backends that update modtime via a
    server-side copy (such as S3 on Cloudflare R2).

commit c55634bdf85eb20a36048c68c76f25efe9447ed8
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Tue May 5 15:30:41 2026 +0100

    drime: fix uploads of 100..200M files
    
    At some point Drime recommended 200M for the upload cutoff for
    switching to multipart upload. However uploads have stopped working
    using single part upload for 100..200Mish files.
    
    Their docs now recommend 5M as the cutoff for multipart upload so this
    changes the default.

commit 667903dca04005ee0c6a569290c3a8022da2b9ac
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Mon May 4 12:12:50 2026 +0100

    drime: fix large file uploads landing in drive root instead of configured folder
    
    The /s3/multipart/create and /s3/entries endpoints interpret relativePath
    as an absolute path from the drive root, not relative to parent_id. When
    root_folder_id was set to a non-root folder, files larger than
    upload_cutoff ended up at the user's drive root instead of the configured
    folder.
    
    Resolve the absolute path of the Fs root once via GET /folders/{hash}/path
    (cached on first OpenChunkWriter call) and use that to build the correct
    relativePath.
    
    Fixes #9392

commit 15419f90c2719a5d82d72465b6ae237b74e57028
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Thu May 7 11:15:10 2026 +0100

    docs: sponsor updates
    
    - Add Data Raven as a silver sponsor
    - Add Impossible Cloud as a bronze sponsor
    - Shuffle silver sponsors once per page load
    - Remove TOC from sponsors page

commit 84698c3d287a65204c53a5dbc946b765bec8e20e
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Thu May 7 17:38:15 2026 +0100

    Add ferrumclaudepilgrim to contributors

commit 1bbe758bc554a599a3af3ce43b125dc702a064ce
Author: ferrumclaudepilgrim <ferrumclaudepilgrim@users.noreply.github.com>
Date:   Tue May 5 22:58:39 2026 -0500

    local: add --local-fatal-if-no-space flag - fixes #8011
    
    When enabled, an out-of-space error during a local write returns a
    fatal error that aborts the run, instead of being retried.
    
    Without this option, ENOSPC errors are treated as retryable and
    rclone may spin through the retry loop many times on a full disk
    before giving up. That is fine for transient network errors but
    unhelpful when the disk is genuinely full and the operator wants
    the run to fail loudly. Default is off so existing behaviour is
    unchanged.
    
    Implementation follows the pattern suggested in the issue: a defer
    at the top of Update wraps the error with fserrors.FatalError when
    the option is on and the error is disk-full. Detection covers both
    file.ErrDiskFull from the preallocate path and syscall.ENOSPC from
    io.Copy or Close, via a small helper that uses fserrors.IsErrNoSpace.

commit 4c8bfb75007e5376d466dccc0f107eb12a8e864e
Author: Leon Brocard <lbrocard@fastly.com>
Date:   Thu May 7 08:32:36 2026 +0100

    s3: add new Fastly Object Storage regions
    
    Add three new regions and their endpoints for Fastly Object Storage:
    
    - eu-west-1 (Paris)
    - us-east-1 (Virginia)
    - us-west-1 (Oregon)
    
    These are distinct from the existing us-east, us-west and eu-central
    endpoints, which are kept in place.

commit 0c8d098b7f7707383566113263b5191cead9da22
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Wed May 6 15:47:17 2026 +0100

    cloudinary: fix retrying every error and fix pacer sleep units
    
    shouldRetry treated every non-nil error as retryable, so permanent
    failures (auth, 4xx, not-found) burned through the LowLevelRetries
    budget instead of returning fast.
    
    This also fixes the pacer sleeps: pacer.MinSleep(1000) and
    MaxSleep(10000) are time.Duration values, so they were 1µs and 10µs -
    almost certainly intended as 10ms and 2s.

commit 895e56e401c45f8d6a5800f68ef3345ef8eff923
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Wed May 6 15:30:02 2026 +0100

    test_all: give Cloudinary more list retries to fix flaky tests

commit daacfb6035ac08fe5a640773c18740d33f5c9de0
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Wed May 6 15:19:06 2026 +0100

    sync: fix flaky transform tests with retries
    
    The TransformFile tests in fs/sync call operations.TransformFile
    immediately after MoveDir. On eventually-consistent backends the
    internal NewObject lookup can momentarily fail with "object not
    found", making the tests flaky.
    
    This wraps the two operations.TransformFile calls in TestTransformFile
    and TestManualTransformFile with fstest.Retry

commit 384e9053736b5fbef4863421c6490a9c0018cf5c
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Wed May 6 15:19:06 2026 +0100

    fstest: make Retry helper public
    
    Add a public fstest.Retry helper that retries any function with
    exponential backoff up to *ListRetries attempts.

commit de67f29b3fe3693739c8d431ce4156dce73a7d6d
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Wed May 6 17:01:07 2026 +0100

    sync: fix --fix-case rename failing on backends that can't update modtime
    
    When --fix-case was used (e.g. by bisync) on backends that can't set
    modification times in place - such as Dropbox - files whose content
    matched but whose modtimes differed would fail to rename with a
    "from_lookup/not_found" error and abort the operation.
    
    This happened because operations.NeedTransfer was called before the
    fix-case rename. NeedTransfer's equality check would delete the
    destination as a precursor to re-uploading it (the standard way to
    update a modtime on these backends), so by the time the rename ran the
    file no longer existed on the remote.
    
    Fix by running the fix-case rename first, so that any subsequent
    delete/re-upload happens at the correctly-cased destination path.
    
    See: #8881

commit 40642fee0128a95daa1a4b97d7d2f123697475ea
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Wed May 6 17:47:23 2026 +0100

    Add Tim Schumacher to contributors

commit fdda89ae63f95f2924e4401a90c0fa8323e45ebc
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Wed May 6 17:47:23 2026 +0100

    Add kkocdko to contributors

commit d86b72c405e54bbf301d7e791ae23ff7d7141f1a
Author: kkocdko <31189892+kkocdko@users.noreply.github.com>
Date:   Wed May 6 19:41:15 2026 +0800

    serve: support custom http response headers
    
    Co-authored-by: Tim Schumacher <tim@tschumacher.net>

commit 03b06ac459b77daf4c8fe13e927a76a81dd33ace
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Wed May 6 11:35:18 2026 +0100

    ftp: fix flaky UploadTimeout test on slow integration servers
    
    The test set the short idle timeout before creating the test Fs, which
    made fs.NewFs fail to read the FTP welcome banner within 1s on slow CI
    hosts. Restore the long timeout while NewFs dials the control
    connection, then apply the short idle timeout before the upload so the
    data connection still exercises the close race that shut_timeout fixes.

commit 38926f43be333bf59b8c9b7c125732e60524dd10
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Wed May 6 11:13:00 2026 +0100

    test_all: give Drime more list retries to fix flaky tests

commit 3e78426fc9608ed4fbadac4c2011b5f6de5cc6e0
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Wed May 6 11:00:37 2026 +0100

    test_all: remove Webdav Infinite Scale integration tests
    
    These are broken and the submitter has not shown any interest in
    fixing them.

commit dac3fa851e47bef2356944ac134f20cda1ed6804
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Wed May 6 10:59:01 2026 +0100

    test_all: remove Seafile V6 tests as they are broken and V6 is 10 years old

commit 7b54c7a6e6e3adcf0c3b1512229cdfa3d8261b05
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Wed May 6 11:39:57 2026 +0100

    Add KTibow to contributors

commit 7200e377dd403630a2daf8bfb11d56641a6e58eb
Author: KTibow <KTibow@users.noreply.github.com>
Date:   Sat May 2 16:05:39 2026 -0700

    oauthutil: clarify token replacement prompt wording
    
    The previous wording "Already have a token - refresh?" was misleading
    because answering yes triggers a full re-authorization flow, not an
    OAuth2 refresh token grant. Updated to "Token already configured -
    replace it?" to accurately describe what happens.
    
    Also updated the SugarSync backend which has its own copy of the prompt,
    and the docs for box, drive, and onedrive that reference it.

commit 6f1678419fc8d8cd7cb2250367e89069d6eca7b2
Author: Leon Brocard <acme@astray.com>
Date:   Wed May 6 10:43:55 2026 +0100

    serve webdav: add gzip compression for compressible responses
    
    Enable on-the-fly response compression for WebDAV when the client sends
    Accept-Encoding and the response content type is suitable for
    compression.
    
    This adds compression for the WebDAV responses that benefit most in
    practice, notably PROPFIND XML responses and text file downloads.
    I tested this with Cyberduck, which sends
    `Accept-Encoding: gzip,deflate` and accepted the compressed responses.
    
    Range requests are explicitly left uncompressed.
    
    Fixes #5777

commit 6e99f8b301f0db7c9f74c0f8a37eab53c266f10e
Author: Leon Brocard <acme@astray.com>
Date:   Wed May 6 10:40:34 2026 +0100

    gui: serve static files with gzip/deflate compression
    
    Before this change, the GUI server sent all static files uncompressed,
    meaning the browser had to download the full size of every JS, CSS,
    and HTML asset.
    
    After this change, the GUI server uses chi's Compress middleware at
    level 5, which negotiates gzip or deflate encoding based on the
    client's Accept-Encoding header.
    
    This reduces transfer sizes significantly for the web UI assets, for
    example assets/index-CvfdU_RR.js is 874 KB uncompressed, and
    265 KB compressed.
    
    This is consistent with how rclone serve http, webdav, and restic
    already compress their responses.

commit 9d4c912e0e479dc459464cf3559088bb67385655
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Sat May 2 21:11:50 2026 +0100

    s3: fix STS call per request by caching AssumeRole credentials
    
    The stscreds.AssumeRoleProvider from AWS SDK Go v2 does not cache
    credentials by itself. The SDK only auto-wraps providers with
    aws.CredentialsCache when they are loaded via
    config.LoadDefaultConfig; when assigned directly to
    aws.Config.Credentials it must be wrapped manually, as documented on
    stscreds.NewAssumeRoleProvider.
    
    Without the cache, configurations using role_arn would call AssumeRole
    once per S3 request, flooding STS and CloudTrail.
    
    See: https://forum.rclone.org/t/aws-iam-roles-credentials-arent-cached/53732

commit 0737599cd4b4ecd74b37721a401b0891d04bb6f6
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Tue Apr 28 10:57:02 2026 +0100

    protondrive: fix segfault when copying files missing revision metadata
    
    When a Proton Drive file has no active revision attributes,
    readMetaDataForLink returns a nil FileSystemAttrs and Object.originalSize
    is left as nil. Object.Open then dereferenced this nil pointer when
    calling fs.FixRangeOption, causing a SIGSEGV during copy.
    
    Use Object.Size() instead, which already implements the correct fallback
    to the link size when originalSize is unavailable.
    
    This updates the github.com/rclone/Proton-API-Bridge package to fix a
    segfault when reading files with no metadata.
    
    Fixes #9377
    Fixes #9117

commit 3b2011c7a09fc32d8a62036891bbd47a36175e4d
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Mon May 4 18:25:56 2026 +0100

    protondrive: route library logging through rclone's logger
    
    Previously all log output produced by Proton-API-Bridge (stdlib log)
    and go-proton-api (logrus + resty's logger) bypassed rclone's
    logging: it ignored -v / -vv levels and didn't reach --log-file.
    
    Add a small adapter implementing the resty.Logger / bridge Logger
    shape that calls fs.Errorf / fs.Logf / fs.Debugf, and pass it via
    the new Config.Logger hook. The bridge in turn forwards the same
    value to go-proton-api's WithLogger option, so HTTP-layer warnings
    and the formerly-hardcoded logrus warnings inside go-proton-api
    also surface through rclone's log levels.

commit ef26e6d26d3b6ccb989fe69e2c78eb8fe707b88d
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Mon May 4 18:19:10 2026 +0100

    protondrive: route HTTP through rclone's transport
    
    The Proton Drive backend constructed the upstream Proton-API-Bridge
    without ever passing rclone's HTTP transport. As a result none of
    rclone's HTTP flags reached Proton: --dump headers, --dump bodies,
    --no-check-certificate, --user-agent, --bind, --ca-cert, --header,
    --tpslimit etc. all silently did nothing for this remote, and HTTP
    traffic was invisible to -vv.
    
    Pass fshttp.NewTransport(ctx) through the new Config.Transport hook on
    the bridge, which forwards it to the updated go-proton-api's
    WithTransport option and so to the underlying resty client.

commit c0a8b2597d6957c4ffe88174fa2038b6a3b82b32
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Tue May 5 09:43:22 2026 +0100

    Add Copilot to contributors

commit 74d65bf670503d26ca1b2c5fe163859e558d269b
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Tue May 5 09:43:22 2026 +0100

    Add Sven Rebhan to contributors

commit a4e647664221c84861bdbf66f9f73640efce53f9
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Tue May 5 09:43:22 2026 +0100

    Add Gustavo V. F. to contributors

commit 6c66b4985dbc4b8eeaa4a239de133897aa56c30a
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Tue May 5 09:43:22 2026 +0100

    Add 王一赫 to contributors

commit b8b3346499139ead43474530bbac8ab2ef542492
Author: Sven Rebhan <36194019+srebhan@users.noreply.github.com>
Date:   Mon May 4 12:06:30 2026 +0200

    log: fix side effects when importing rclone as a library
    
    Avoid side effects by using own logger instance
    
    - Importing fs/log only sets rclone's private logger via fs.SetLogger,
      so internal rclone logging works from the moment the package is
      imported but the process-wide slog default is left untouched.
    
    - slog.SetDefault and slog.SetLogLoggerLevel move into InitLogging,
      which is called explicitly from the CLI (cmd/cmd.go), the librclone
      wrapper and the integration test framework. So rclone-as-a-program
      keeps capturing log.Print/log.Fatal and slog.Default() output as
      before.
    
    Library consumers that import fs/log without calling InitLogging now
    keep their own slog default and can safely route rclone output back
    into it via log.Handler.SetOutput without recursing.
    
    Fixes #8907
    
    Co-authored-by: Nick Craig-Wood <nick@craig-wood.com>

commit 9f89102a574c841dbb00f2e8acdaa77c1b3b8a60
Author: Gustavo V. F. <31892323+Gustavo-V-F@users.noreply.github.com>
Date:   Sat May 2 12:47:07 2026 -0300

    bisync: fix retryable without --resync error message when --resync has a critical failure

commit 075552367ef240d90aea7f894948ff6485269909
Author: Leon Brocard <acme@astray.com>
Date:   Sat May 2 12:28:30 2026 +0100

    cmd/serve/s3: return object listings in key order
    
    The S3 ListObjects response from `rclone serve s3` was sorting object
    contents by modification time instead of object key. This made the
    listing order incompatible with S3 clients which expect lexicographic
    key ordering.
    
    In particular, `aws s3 sync` assumes both source and destination
    iterators are ordered by key. With the old modtime ordering it could
    misidentify files as missing or outdated and re-download objects that
    were already up to date.
    
    Change the pager to sort returned objects by key and add a regression
    test which uses keys and modtimes arranged so the old behaviour would
    fail.
    
    Fixes #9002

commit ada5559fe115385d28b0db02d85f413ca3c91d51
Author: Nick Craig-Wood <nick@craig-wood.com>
Date:   Fri May 1 17:15:20 2026 +0100

    Start v1.75.0-DEV development
