sync: Fix parsing of gcrypt::rsync:// urls that use a relative path
Such an url is not valid; parseURI will fail on it. But git-annex doesn't actually need to parse the url, because all it needs to do to support syncing with it is know that it's not a local path, and use git pull and push. (Note that there is no good reason for the user to use such an url. An absolute url is valid and I patched git-remote-gcrypt to support them years ago. Still, users gonna do anything that tools allow, and git-remote-gcrypt still supports them.) Sponsored-by: Jack Hill on Patreon
This commit is contained in:
parent
0e18bf029e
commit
a0badc5069
12 changed files with 45 additions and 22 deletions
|
@ -235,7 +235,7 @@ editForm _new r@(RepoName _) = page "Edit repository" (Just Configuration) $ do
|
||||||
Nothing -> getRepoInfo Nothing mempty
|
Nothing -> getRepoInfo Nothing mempty
|
||||||
g <- liftAnnex gitRepo
|
g <- liftAnnex gitRepo
|
||||||
mrepo <- liftAnnex $ maybe (pure Nothing) (Just <$$> Remote.getRepo) mr
|
mrepo <- liftAnnex $ maybe (pure Nothing) (Just <$$> Remote.getRepo) mr
|
||||||
let sshrepo = maybe False (remoteLocationIsSshUrl . flip parseRemoteLocation g . Git.repoLocation) mrepo
|
let sshrepo = maybe False (\repo -> remoteLocationIsSshUrl (parseRemoteLocation (Git.repoLocation repo) False g)) mrepo
|
||||||
$(widgetFile "configurators/edit/nonannexremote")
|
$(widgetFile "configurators/edit/nonannexremote")
|
||||||
|
|
||||||
{- Makes any directory associated with the repository. -}
|
{- Makes any directory associated with the repository. -}
|
||||||
|
|
|
@ -110,5 +110,5 @@ checkGCryptRepoEncryption location notencrypted notinstalled encrypted =
|
||||||
- Only works if the gcrypt repo was created as a git-annex remote. -}
|
- Only works if the gcrypt repo was created as a git-annex remote. -}
|
||||||
probeGCryptRemoteUUID :: String -> Annex (Maybe UUID)
|
probeGCryptRemoteUUID :: String -> Annex (Maybe UUID)
|
||||||
probeGCryptRemoteUUID repolocation = do
|
probeGCryptRemoteUUID repolocation = do
|
||||||
r <- inRepo $ Git.Construct.fromRemoteLocation repolocation
|
r <- inRepo $ Git.Construct.fromRemoteLocation repolocation False
|
||||||
GCrypt.getGCryptUUID False r
|
GCrypt.getGCryptUUID False r
|
||||||
|
|
|
@ -186,12 +186,12 @@ repoList reposelector
|
||||||
-- Skip gcrypt repos on removable drives;
|
-- Skip gcrypt repos on removable drives;
|
||||||
-- handled separately.
|
-- handled separately.
|
||||||
case fromProposedAccepted <$> getconfig (Accepted "gitrepo") of
|
case fromProposedAccepted <$> getconfig (Accepted "gitrepo") of
|
||||||
Just rr | remoteLocationIsUrl (parseRemoteLocation rr g) ->
|
Just rr | remoteLocationIsUrl (parseRemoteLocation rr False g) ->
|
||||||
val True EnableSshGCryptR
|
val True EnableSshGCryptR
|
||||||
_ -> Nothing
|
_ -> Nothing
|
||||||
Just "git" ->
|
Just "git" ->
|
||||||
case fromProposedAccepted <$> getconfig (Accepted "location") of
|
case fromProposedAccepted <$> getconfig (Accepted "location") of
|
||||||
Just loc | remoteLocationIsSshUrl (parseRemoteLocation loc g) ->
|
Just loc | remoteLocationIsSshUrl (parseRemoteLocation loc False g) ->
|
||||||
val True EnableSshGitRemoteR
|
val True EnableSshGitRemoteR
|
||||||
_ -> Nothing
|
_ -> Nothing
|
||||||
_ -> Nothing
|
_ -> Nothing
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
git-annex (10.20230322) UNRELEASED; urgency=medium
|
||||||
|
|
||||||
|
* sync: Fix parsing of gcrypt::rsync:// urls that use a relative path.
|
||||||
|
|
||||||
|
-- Joey Hess <id@joeyh.name> Thu, 23 Mar 2023 15:04:41 -0400
|
||||||
|
|
||||||
git-annex (10.20230321) upstream; urgency=medium
|
git-annex (10.20230321) upstream; urgency=medium
|
||||||
|
|
||||||
* Using git-annex view in an adjusted branch, or git-annex adjust in a
|
* Using git-annex view in an adjusted branch, or git-annex adjust in a
|
||||||
|
|
|
@ -220,7 +220,7 @@ seek' o = do
|
||||||
let withbranch a = a =<< getCurrentBranch
|
let withbranch a = a =<< getCurrentBranch
|
||||||
|
|
||||||
remotes <- syncRemotes (syncWith o)
|
remotes <- syncRemotes (syncWith o)
|
||||||
-- Remotes that are git repositories, not special remotes.
|
-- Remotes that are git repositories, not (necesarily) special remotes.
|
||||||
let gitremotes = filter (Remote.gitSyncableRemoteType . Remote.remotetype) remotes
|
let gitremotes = filter (Remote.gitSyncableRemoteType . Remote.remotetype) remotes
|
||||||
-- Remotes that contain annex object content.
|
-- Remotes that contain annex object content.
|
||||||
contentremotes <- filter (\r -> Remote.uuid r /= NoUUID)
|
contentremotes <- filter (\r -> Remote.uuid r /= NoUUID)
|
||||||
|
|
|
@ -140,7 +140,7 @@ fromRemotes repo = catMaybes <$> mapM construct remotepairs
|
||||||
filterkeys f = filterconfig (\(k,_) -> f k)
|
filterkeys f = filterconfig (\(k,_) -> f k)
|
||||||
remotepairs = filterkeys isRemoteUrlKey
|
remotepairs = filterkeys isRemoteUrlKey
|
||||||
construct (k,v) = remoteNamedFromKey k $
|
construct (k,v) = remoteNamedFromKey k $
|
||||||
fromRemoteLocation (fromConfigValue v) repo
|
fromRemoteLocation (fromConfigValue v) False repo
|
||||||
|
|
||||||
{- Sets the name of a remote when constructing the Repo to represent it. -}
|
{- Sets the name of a remote when constructing the Repo to represent it. -}
|
||||||
remoteNamed :: String -> IO Repo -> IO Repo
|
remoteNamed :: String -> IO Repo -> IO Repo
|
||||||
|
@ -156,9 +156,15 @@ remoteNamedFromKey k r = case remoteKeyToRemoteName k of
|
||||||
Just n -> Just <$> remoteNamed n r
|
Just n -> Just <$> remoteNamed n r
|
||||||
|
|
||||||
{- Constructs a new Repo for one of a Repo's remotes using a given
|
{- Constructs a new Repo for one of a Repo's remotes using a given
|
||||||
- location (ie, an url). -}
|
- location (ie, an url).
|
||||||
fromRemoteLocation :: String -> Repo -> IO Repo
|
-
|
||||||
fromRemoteLocation s repo = gen $ parseRemoteLocation s repo
|
- knownurl can be true if the location is known to be an url. This allows
|
||||||
|
- urls that don't parse as urls to be used, returning UnparseableUrl.
|
||||||
|
- If knownurl is false, the location may still be an url, if it parses as
|
||||||
|
- one.
|
||||||
|
-}
|
||||||
|
fromRemoteLocation :: String -> Bool -> Repo -> IO Repo
|
||||||
|
fromRemoteLocation s knownurl repo = gen $ parseRemoteLocation s knownurl repo
|
||||||
where
|
where
|
||||||
gen (RemotePath p) = fromRemotePath p repo
|
gen (RemotePath p) = fromRemotePath p repo
|
||||||
gen (RemoteUrl u) = fromUrl u
|
gen (RemoteUrl u) = fromUrl u
|
||||||
|
|
|
@ -55,7 +55,15 @@ encryptedRemote baserepo = go
|
||||||
-- allows them); need to de-escape any such
|
-- allows them); need to de-escape any such
|
||||||
-- to get back the path to the repository.
|
-- to get back the path to the repository.
|
||||||
l' = Network.URI.unEscapeString l
|
l' = Network.URI.unEscapeString l
|
||||||
in fromRemoteLocation l' baserepo
|
-- gcrypt supports relative urls for rsync
|
||||||
|
-- like "rsync://host:relative/path"
|
||||||
|
-- but that does not parse as a valid url
|
||||||
|
-- (while the absolute urls it supports are
|
||||||
|
-- valid).
|
||||||
|
-- In order to support it, force treating it as
|
||||||
|
-- an url.
|
||||||
|
knownurl = "rsync://" `isPrefixOf` l'
|
||||||
|
in fromRemoteLocation l' knownurl baserepo
|
||||||
| otherwise = notencrypted
|
| otherwise = notencrypted
|
||||||
|
|
||||||
notencrypted = giveup "not a gcrypt encrypted repository"
|
notencrypted = giveup "not a gcrypt encrypted repository"
|
||||||
|
|
|
@ -63,7 +63,7 @@ makeLegalName s = case filter legal $ replace "/" "_" s of
|
||||||
legal c = isAlphaNum c
|
legal c = isAlphaNum c
|
||||||
|
|
||||||
data RemoteLocation = RemoteUrl String | RemotePath FilePath
|
data RemoteLocation = RemoteUrl String | RemotePath FilePath
|
||||||
deriving (Eq)
|
deriving (Eq, Show)
|
||||||
|
|
||||||
remoteLocationIsUrl :: RemoteLocation -> Bool
|
remoteLocationIsUrl :: RemoteLocation -> Bool
|
||||||
remoteLocationIsUrl (RemoteUrl _) = True
|
remoteLocationIsUrl (RemoteUrl _) = True
|
||||||
|
@ -75,16 +75,18 @@ remoteLocationIsSshUrl _ = False
|
||||||
|
|
||||||
{- Determines if a given remote location is an url, or a local
|
{- Determines if a given remote location is an url, or a local
|
||||||
- path. Takes the repository's insteadOf configuration into account. -}
|
- path. Takes the repository's insteadOf configuration into account. -}
|
||||||
parseRemoteLocation :: String -> Repo -> RemoteLocation
|
parseRemoteLocation :: String -> Bool -> Repo -> RemoteLocation
|
||||||
parseRemoteLocation s repo = ret $ calcloc s
|
parseRemoteLocation s knownurl repo = go
|
||||||
where
|
where
|
||||||
ret v
|
s' = calcloc s
|
||||||
|
go
|
||||||
#ifdef mingw32_HOST_OS
|
#ifdef mingw32_HOST_OS
|
||||||
| dosstyle v = RemotePath (dospath v)
|
| dosstyle s' = RemotePath (dospath s')
|
||||||
#endif
|
#endif
|
||||||
| scpstyle v = RemoteUrl (scptourl v)
|
| scpstyle s' = RemoteUrl (scptourl s')
|
||||||
| urlstyle v = RemoteUrl v
|
| urlstyle s' = RemoteUrl s'
|
||||||
| otherwise = RemotePath v
|
| knownurl && s' == s = RemoteUrl s'
|
||||||
|
| otherwise = RemotePath s'
|
||||||
-- insteadof config can rewrite remote location
|
-- insteadof config can rewrite remote location
|
||||||
calcloc l
|
calcloc l
|
||||||
| null insteadofs = l
|
| null insteadofs = l
|
||||||
|
|
|
@ -266,7 +266,7 @@ gCryptSetup _ mu _ c gc = go $ fromProposedAccepted <$> M.lookup gitRepoField c
|
||||||
let u = genUUIDInNameSpace gCryptNameSpace gcryptid
|
let u = genUUIDInNameSpace gCryptNameSpace gcryptid
|
||||||
if Just u == mu || isNothing mu
|
if Just u == mu || isNothing mu
|
||||||
then do
|
then do
|
||||||
method <- setupRepo gcryptid =<< inRepo (Git.Construct.fromRemoteLocation gitrepo)
|
method <- setupRepo gcryptid =<< inRepo (Git.Construct.fromRemoteLocation gitrepo False)
|
||||||
gitConfigSpecialRemote u c' [("gcrypt", fromAccessMethod method)]
|
gitConfigSpecialRemote u c' [("gcrypt", fromAccessMethod method)]
|
||||||
return (c', u)
|
return (c', u)
|
||||||
else giveup $ "uuid mismatch; expected " ++ show mu ++ " but remote gitrepo has " ++ show u ++ " (" ++ show gcryptid ++ ")"
|
else giveup $ "uuid mismatch; expected " ++ show mu ++ " but remote gitrepo has " ++ show u ++ " (" ++ show gcryptid ++ ")"
|
||||||
|
|
|
@ -102,7 +102,7 @@ list autoinit = do
|
||||||
Nothing -> return r
|
Nothing -> return r
|
||||||
Just url -> inRepo $ \g ->
|
Just url -> inRepo $ \g ->
|
||||||
Git.Construct.remoteNamed n $
|
Git.Construct.remoteNamed n $
|
||||||
Git.Construct.fromRemoteLocation (Git.fromConfigValue url) g
|
Git.Construct.fromRemoteLocation (Git.fromConfigValue url) False g
|
||||||
|
|
||||||
{- Git remotes are normally set up using standard git commands, not
|
{- Git remotes are normally set up using standard git commands, not
|
||||||
- git-annex initremote and enableremote.
|
- git-annex initremote and enableremote.
|
||||||
|
@ -118,7 +118,7 @@ gitSetup :: SetupStage -> Maybe UUID -> Maybe CredPair -> RemoteConfig -> Remote
|
||||||
gitSetup Init mu _ c _ = do
|
gitSetup Init mu _ c _ = do
|
||||||
let location = maybe (giveup "Specify location=url") fromProposedAccepted $
|
let location = maybe (giveup "Specify location=url") fromProposedAccepted $
|
||||||
M.lookup locationField c
|
M.lookup locationField c
|
||||||
r <- inRepo $ Git.Construct.fromRemoteLocation location
|
r <- inRepo $ Git.Construct.fromRemoteLocation location False
|
||||||
r' <- tryGitConfigRead False r False
|
r' <- tryGitConfigRead False r False
|
||||||
let u = getUncachedUUID r'
|
let u = getUncachedUUID r'
|
||||||
if u == NoUUID
|
if u == NoUUID
|
||||||
|
|
|
@ -203,7 +203,7 @@ configKnownUrl r
|
||||||
<$> M.lookup Annex.SpecialRemote.Config.typeField c
|
<$> M.lookup Annex.SpecialRemote.Config.typeField c
|
||||||
u <- fromProposedAccepted
|
u <- fromProposedAccepted
|
||||||
<$> M.lookup urlField c
|
<$> M.lookup urlField c
|
||||||
let u' = Git.Remote.parseRemoteLocation u g
|
let u' = Git.Remote.parseRemoteLocation u False g
|
||||||
return $ Git.Remote.RemoteUrl (Git.repoLocation r) == u'
|
return $ Git.Remote.RemoteUrl (Git.repoLocation r) == u'
|
||||||
&& t == typename remote
|
&& t == typename remote
|
||||||
go u mcu = do
|
go u mcu = do
|
||||||
|
|
|
@ -36,3 +36,4 @@ Flow 2 (absolute path, working)
|
||||||
### Have you had any luck using git-annex before? (Sometimes we get tired of reading bug reports all day and a lil' positive end note does wonders)
|
### Have you had any luck using git-annex before? (Sometimes we get tired of reading bug reports all day and a lil' positive end note does wonders)
|
||||||
I am VERY happy with git annex and am using it successfully with a gcrypt remote using an absolute path :)
|
I am VERY happy with git annex and am using it successfully with a gcrypt remote using an absolute path :)
|
||||||
|
|
||||||
|
> [[fixed|done]] --[[Joey]]
|
||||||
|
|
Loading…
Reference in a new issue