From c5b017e55b33b51c611b463e8e11de18eb34d4e4 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Fri, 7 Apr 2023 17:12:55 -0400 Subject: [PATCH] full emulation of git filename escaping Not yet used, but the plan is to make git-annex use this when displaying filenames similar to how git does. Sponsored-by: Lawrence Brogan on Patreon --- Git/Filename.hs | 18 ++++++++++++++++-- doc/todo/terminal_escapes_in_filenames.mdwn | 5 +++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/Git/Filename.hs b/Git/Filename.hs index 322054fd80..507380ce0e 100644 --- a/Git/Filename.hs +++ b/Git/Filename.hs @@ -11,7 +11,7 @@ module Git.Filename where import Common -import Utility.Format (decode_c, encode_c, isUtf8Byte) +import Utility.Format (decode_c, encode_c, encode_c', isUtf8Byte) import Utility.QuickCheck import Data.Char @@ -39,8 +39,22 @@ encodeAlways s = "\"" <> encode_c needencode s <> "\"" where needencode c = isUtf8Byte c || c == fromIntegral (ord '"') +-- git config core.quotePath controls whether to quote unicode characters +newtype QuotePath = QuotePath Bool + +-- encodes and double quotes when git would +encode :: QuotePath -> RawFilePath -> S.ByteString +encode (QuotePath qp) s = case encode_c' needencode s of + Nothing -> s + Just s' -> "\"" <> s' <> "\"" + where + needencode c + | c == fromIntegral (ord '"') = True + | qp = isUtf8Byte c + | otherwise = False + -- Encoding and then decoding roundtrips only when the string does not --- contain high unicode, because eg, both "\12345" and "\227\128\185" +-- contain high unicode, because eg, both "\12345" and "\227\128\185" -- are encoded to "\343\200\271". -- -- That is not a real-world problem, and using TestableFilePath diff --git a/doc/todo/terminal_escapes_in_filenames.mdwn b/doc/todo/terminal_escapes_in_filenames.mdwn index 8f6940c581..181727eb81 100644 --- a/doc/todo/terminal_escapes_in_filenames.mdwn +++ b/doc/todo/terminal_escapes_in_filenames.mdwn @@ -35,3 +35,8 @@ useful defense in depth against terminal security holes, and also good to behave more like git. --[[Joey]] + +> Git.Filename.encode is implemented, and only needs to be used. +> Note that core.quotePath controls whether git quotes unicode characters +> (by default it does), so once this gets implemented, some users may want +> to set that config to false. --[[Joey]]