diff --git a/Annex/Ssh.hs b/Annex/Ssh.hs index 07519d0390..a0e4ff9319 100644 --- a/Annex/Ssh.hs +++ b/Annex/Ssh.hs @@ -351,10 +351,15 @@ hostport2socket host (Just port) = hostport2socket' $ fromSshHost host ++ "!" ++ show port hostport2socket' :: String -> OsPath hostport2socket' s - | length s > lengthofmd5s = toOsPath $ show $ md5 $ encodeBL s - | otherwise = toOsPath s + | length s' > lengthofmd5s = toOsPath $ show $ md5 $ encodeBL s' + | otherwise = toOsPath s' where lengthofmd5s = 32 + -- ssh parses the socket filename as a ControlPath, so it can + -- contain eg "%h". We don't want that here, and it's possible + -- for a hostname to itself contain a '%', eg a IPV6 link-local + -- address with a zone ID. + s' = filter (/= '%') s socket2lock :: OsPath -> OsPath socket2lock socket = socket <> lockExt diff --git a/CHANGELOG b/CHANGELOG index aa6dc06ea8..d172c1b897 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -11,6 +11,7 @@ git-annex (10.20250321) UNRELEASED; urgency=medium version of the annex.web-options config. * migrate: Fix --remove-size to work when a file is not present. Fixes reversion introduced in version 10.20231129. + * Support git remotes that use a IPV6 link-local address with a zone ID. -- Joey Hess Fri, 21 Mar 2025 12:27:11 -0400 diff --git a/Git/Remote.hs b/Git/Remote.hs index eb4d78e88d..b0a31314ce 100644 --- a/Git/Remote.hs +++ b/Git/Remote.hs @@ -103,9 +103,10 @@ parseRemoteLocation s knownurl repo = go urlstyle v = isURI (escapeURIString isUnescapedInURI v) -- git remotes can be written scp style -- [user@]host:dir -- but foo::bar is a git-remote-helper location instead + -- (although '::' can also be part of an IPV6 address) scpstyle v = ":" `isInfixOf` v && not ("//" `isInfixOf` v) - && not ("::" `isInfixOf` v) + && not ("::" `isInfixOf` (takeWhile (/= '[') v)) scptourl v = "ssh://" ++ host ++ slash dir where (host, dir) diff --git a/Git/Url.hs b/Git/Url.hs index ad0e61b648..af13f58391 100644 --- a/Git/Url.hs +++ b/Git/Url.hs @@ -36,9 +36,14 @@ uriRegName' a = fixup $ uriRegName a len = length rest - 1 fixup x = x -{- Hostname of an URL repo. -} +{- Hostname of an URL repo. + - + - An IPV6 link-local address in an url can include a + - scope, eg "%wlan0". The "%" is necessarily URI-encoded + - as "%25" in the URI. So the hostname gets URI-decoded here. + -} host :: Repo -> Maybe String -host = authpart uriRegName' +host = authpart (unEscapeString . uriRegName') {- Port of an URL repo, if it has a nonstandard one. -} port :: Repo -> Maybe Integer @@ -53,7 +58,7 @@ port r = hostuser :: Repo -> Maybe String hostuser r = (++) <$> authpart uriUserInfo r - <*> authpart uriRegName' r + <*> host r {- The full authority portion an URL repo. (ie, "user@host:port") -} authority :: Repo -> Maybe String diff --git a/doc/bugs/IPv6_link-local_address_as_remote.mdwn b/doc/bugs/IPv6_link-local_address_as_remote.mdwn index d2c43ba221..d56686d73f 100644 --- a/doc/bugs/IPv6_link-local_address_as_remote.mdwn +++ b/doc/bugs/IPv6_link-local_address_as_remote.mdwn @@ -31,3 +31,5 @@ There is no problem with global IPv6 addresses, so it is likely that the percent ### 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) Yes, I have successfully used git-annex with a local remote (same computer), ssh over IPv4, and ssh to a globally visible IPv6 address. + +> [[fixed|done]] --[[Joey]]