started migrate --update
This is most of the way there, but not quite working. The layout of migrate.tree/ needs to be changed to follow this approach. git log will list all the files in tree order, so the new layout needs to alternate old and new keys. Can that be done? git may not document tree order, or may not preserve it here. Alternatively, change to using git log --format=raw and extract the tree header from that, then use git diff --raw $tree:migrate.tree/old $tree:migrate.tree/new That will be a little more expensive, but only when there are lots of migrations. Sponsored-by: Joshua Antonishen on Patreon
This commit is contained in:
parent
d06aee7ce0
commit
f1ce15036f
9 changed files with 172 additions and 38 deletions
40
Git/Log.hs
40
Git/Log.hs
|
@ -10,6 +10,7 @@ module Git.Log where
|
|||
import Common
|
||||
import Git
|
||||
import Git.Command
|
||||
import Git.Sha
|
||||
|
||||
import Data.Time
|
||||
import Data.Time.Clock.POSIX
|
||||
|
@ -28,14 +29,15 @@ data RefChange t = RefChange
|
|||
-- run after processing the returned list.
|
||||
getGitLog
|
||||
:: Ref
|
||||
-> Maybe Ref
|
||||
-> [FilePath]
|
||||
-> [CommandParam]
|
||||
-> (FilePath -> Maybe t)
|
||||
-> (Sha -> FilePath -> Maybe t)
|
||||
-> Repo
|
||||
-> IO ([RefChange t], IO Bool)
|
||||
getGitLog ref fs os fileselector repo = do
|
||||
getGitLog ref stopref fs os selector repo = do
|
||||
(ls, cleanup) <- pipeNullSplit ps repo
|
||||
return (parseGitRawLog fileselector (map decodeBL ls), cleanup)
|
||||
return (parseGitRawLog selector (map decodeBL ls), cleanup)
|
||||
where
|
||||
ps =
|
||||
[ Param "log"
|
||||
|
@ -45,14 +47,16 @@ getGitLog ref fs os fileselector repo = do
|
|||
, Param "--no-abbrev"
|
||||
, Param "--no-renames"
|
||||
] ++ os ++
|
||||
[ Param (fromRef ref)
|
||||
[ case stopref of
|
||||
Just stopref' -> Param $
|
||||
fromRef stopref' <> ".." <> fromRef ref
|
||||
Nothing -> Param (fromRef ref)
|
||||
, Param "--"
|
||||
] ++ map Param fs
|
||||
|
||||
-- The commitinfo is the timestamp of the commit, followed by
|
||||
-- the commit hash and then the commit's parents, separated by spaces.
|
||||
-- The commitinfo is the commit hash followed by its timestamp.
|
||||
commitinfoFormat :: String
|
||||
commitinfoFormat = "%ct"
|
||||
commitinfoFormat = "%H %ct"
|
||||
|
||||
-- Parses chunked git log --raw output generated by getGitLog,
|
||||
-- which looks something like:
|
||||
|
@ -69,21 +73,23 @@ commitinfoFormat = "%ct"
|
|||
--
|
||||
-- The commitinfo is not included before all changelines, so
|
||||
-- keep track of the most recently seen commitinfo.
|
||||
parseGitRawLog :: (FilePath -> Maybe t) -> [String] -> [RefChange t]
|
||||
parseGitRawLog fileselector = parse epoch
|
||||
parseGitRawLog :: (Ref -> FilePath -> Maybe t) -> [String] -> [RefChange t]
|
||||
parseGitRawLog selector = parse (deleteSha, epoch)
|
||||
where
|
||||
epoch = toEnum 0 :: POSIXTime
|
||||
parse oldts ([]:rest) = parse oldts rest
|
||||
parse oldts (c1:c2:rest) = case mrc of
|
||||
Just rc -> rc : parse ts rest
|
||||
Nothing -> parse ts (c2:rest)
|
||||
parse old ([]:rest) = parse old rest
|
||||
parse (oldcommitsha, oldts) (c1:c2:rest) = case mrc of
|
||||
Just rc -> rc : parse (commitsha, ts) rest
|
||||
Nothing -> parse (commitsha, ts) (c2:rest)
|
||||
where
|
||||
(ts, cl) = case separate (== '\n') c1 of
|
||||
(cl', []) -> (oldts, cl')
|
||||
(tss, cl') -> (parseTimeStamp tss, cl')
|
||||
(commitsha, ts, cl) = case separate (== '\n') c1 of
|
||||
(cl', []) -> (oldcommitsha, oldts, cl')
|
||||
(ci, cl') -> case words ci of
|
||||
(css:tss:[]) -> (Ref (encodeBS css), parseTimeStamp tss, cl')
|
||||
_ -> (oldcommitsha, oldts, cl')
|
||||
mrc = do
|
||||
(old, new) <- parseRawChangeLine cl
|
||||
v <- fileselector c2
|
||||
v <- selector commitsha c2
|
||||
return $ RefChange
|
||||
{ changetime = ts
|
||||
, changed = v
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue