Skip to content

Instantly share code, notes, and snippets.

@dirkz
Created October 30, 2016 13:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dirkz/788e3da7652a5e5f46e3aa6362c40323 to your computer and use it in GitHub Desktop.
Save dirkz/788e3da7652a5e5f46e3aa6362c40323 to your computer and use it in GitHub Desktop.
Rewrite mercurial (hg) commit dates/timestamps with haskell
{-|
How to use:
```
hg export -g -r 1: | runhaskell ~/projects/haskell/mercurial/change-dates.hs > ../patch.txt
# rm the same commits, e.g. with histedit
hg import ../patch.txt
```
-}
import Data.Time.Clock.POSIX
import Data.List
import Text.Regex.Posix
patternToMatch = "# Date ([0-9]+) ([-+][0-9]+)"
delta = 2
matchPattern :: String -> String -> [String]
matchPattern pattern line = getAllTextMatches (line =~ pattern) :: [String]
groupsPattern :: String -> String -> (String,String,String,[String])
groupsPattern pattern line = line =~ pattern :: (String,String,String,[String])
groupsOnlyPattern :: String -> String -> [String]
groupsOnlyPattern pattern line = let (_, _, _, xs) = groupsPattern pattern line in xs
isTimeStamp :: String -> Bool
isTimeStamp = isPrefixOf "# Date "
replaceTimeStamp timestamp line =
(timestamp - delta, "# Date " ++ show timestamp ++ " " ++ timeZone)
where
_:timeZone:[] = groupsOnlyPattern patternToMatch line
processLine :: String -> (Int, [String]) -> (Int, [String])
processLine line (time, lines) =
(newTime, replacedLine:lines)
where
(newTime, replacedLine) = if isTimeStamp line then replaceTimeStamp time line else (time, line)
process :: Int -> String -> String
process time = unlines . snd . foldr processLine (time, []) . lines
main = do
unixTime <- round <$> getPOSIXTime
interact $ process unixTime
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment