git-annex unused --from remote skips its git-remote-annex keys

This turns out to only be necessary is edge cases. Most of the
time, git-annex unused --from remote doesn't see git-remote-annex keys
at all, because it does not record a location log for them.

On the other hand, git-annex unused does find them, since it does not
rely on the location log. And that's good because they're a local cache
that the user should be able to drop.

If, however, the user ran git-annex unused and then git-annex move
--unused --to remote, the keys would have a location log for that
remote. Then git-annex unused --from remote would see them, and would
consider them unused. Even when they are present on the special remote
they belong to. And that risks losing data if they drop the keys from
the special remote, but didn't expect it would delete git branches they
had pushed to it.

So, make git-annex unused --from skip git-remote-annex keys whose uuid
is the same as the remote.
This commit is contained in:
Joey Hess 2024-05-14 15:12:07 -04:00
parent 0bf72ef103
commit 24af51e66d
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
4 changed files with 37 additions and 9 deletions

View file

@ -14,6 +14,7 @@ module Backend.GitRemoteAnnex (
backends,
genGitBundleKey,
genManifestKey,
isGitRemoteAnnexKey,
) where
import Annex.Common
@ -24,9 +25,10 @@ import Utility.Metered
import qualified Backend.Hash as Hash
import qualified Data.ByteString.Short as S
import qualified Data.ByteString.Char8 as B8
backends :: [Backend]
backends = [gitbundle]
backends = [gitbundle, gitmanifest]
gitbundle :: Backend
gitbundle = Backend
@ -44,6 +46,19 @@ gitbundle = Backend
Hash.cryptographicallySecure hash
}
gitmanifest :: Backend
gitmanifest = Backend
{ backendVariety = GitManifestKey
, genKey = Nothing
, verifyKeyContent = Nothing
, verifyKeyContentIncrementally = Nothing
, canUpgradeKey = Nothing
, fastMigrate = Nothing
, isStableKey = const True
, isCryptographicallySecure = False
, isCryptographicallySecureKey = const $ pure False
}
-- git bundle keys use the sha256 hash.
hash :: Hash.Hash
hash = Hash.SHA2Hash (HashSize 256)
@ -72,5 +87,18 @@ genGitBundleKey remoteuuid file meterupdate = do
genManifestKey :: UUID -> Key
genManifestKey u = mkKey $ \kd -> kd
{ keyName = S.toShort (fromUUID u)
, keyVariety = OtherKey "GITMANIFEST"
, keyVariety = GitManifestKey
}
{- Is the key a manifest or bundle key that belongs to the special remote
- with this uuid? -}
isGitRemoteAnnexKey :: UUID -> Key -> Bool
isGitRemoteAnnexKey u k =
case fromKey keyVariety k of
GitBundleKey -> sameuuid $
-- Remove the checksum that comes after the UUID.
B8.dropEnd 1 . B8.dropWhileEnd (/= '-')
GitManifestKey -> sameuuid id
_ -> False
where
sameuuid f = fromUUID u == f (S.fromShort (fromKey keyName k))