-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

Hiya everyone. So I've been desultorily working on Darcs support in
Gitit, and it's turned out to be a little rougher than I expected.
Time to leech^Wask for help. Attached is what I have so far.

My questions are like this.
- ---------------------------
1)
One function Gitit uses is gitDiff:
gitDiff :: MonadIO m
        => String     -- ^ Filename
        -> String     -- ^ Old version (sha1)
        -> String     -- ^ New version (sha1)
        -> m String  -- ^ String
gitDiff file from to = do
  (status, _, output)  FilePath -> FilePath -> FilePath -> m String
gitMergeFile edited original latest = do
  (status, err, out)  return out
       ExitFailure n | n >= 0  -> return out  -- indicates number of
merge conflicts
       _                       -> error $ "git merge-file returned an
error.\n" ++ err

I've tried to read up on Git, but I don't understand this. Is it just
a clone of the Unix command merge, as
http://www.kernel.org/pub/software/scm/git/docs/git-merge-file.html
suggests? I think from its use in Gitit.hs that it is intended for use
in 'edit conflict' situations
(https://secure.wikimedia.org/wikipedia/en/wiki/Edit_conflict
https://secure.wikimedia.org/wikipedia/en/wiki/Wikipedia:Edit_conflict)
where you change a page, save, and discover someone else edited it
already; but isn't Darcs supposed to handle such situations
intelligently? Perhaps the right solution involves some combination of
recording and pushing.
- --------------------------
The last two issues involve git cat-file
http://book.git-scm.com/7_browsing_git_objects.html (I am unsure what
the Darcs analogue is) and figuring out how to parse the changelog
XML, but those aren't major issues.

- --
gwern
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)

iEYEAREKAAYFAklfvBUACgkQvpDo5Pfl1oKOzACeOF6dDh9BHPoQ8LAjzk22Kkuw
4mgAmQHSZ1EuLK5b/qstnX/EbEYBehFM
=XSB2
-----END PGP SIGNATURE-----
module Gitit.Darcs where

import Control.Monad
import Control.Monad.Trans
import System.Exit
import Gitit.State
import Gitit.Shell
import HAppS.State
import Gitit.Git (LogEntry(..))
-- data LogEntry = LogEntry
--   { logRevision :: String
--   , logDate :: String
--   , logAuthor :: String
--   , logSubject :: String
--   , logFiles :: [String]
--   } deriving (Read, Show)

{- TODO:
gitCatFile: http://book.git-scm.com/7_browsing_git_objects.html
* ??? Some sort of history browsing with metadata about revision ID and committer
gitDiff: http://book.git-scm.com/3_comparing_commits_-_git_diff.html
* Should be handleable by 'darcs diff --index=N-M ', if we can turn two patch names into
  2 indices.
gitGetSHA1,
* Gets the SHA ID of the last revision to change a specified file. I think. I see no obvious way
  to get the name of the last patch to change a file in Darcs; 'darcs diff file' doesn't have any
  option to give you it.
gitLog
* Partially implemented. Just need to figure out how to parse the XML.
gitMergeFile
* merg-file is confusing. It's used once:
 > mergeText <- gitMergeFile (pathForPage page ++ ".edited") (pathForPage page ++ ".original") (pathForPage page ++ ".latest")
  Can we do this automatically in Darcs? I don't yet understand what 'git merge-file' does.
-}

-- | Run darcs command and return error status, standard output, and error output.  The repository
-- is used as working directory.
runDarcsCommand :: MonadIO m => String -> [String] -> m (ExitCode, String, String)
runDarcsCommand cm args = do repo <- liftM repositoryPath (query GetConfig)
                             runProgCommand repo Nothing "darcs" cm args

-- | Return list of log entries for the given time frame and commit author.
-- If author is null, return entries for all authors.
-- TODO: finish this. Need to parse the XML *groan*
darcsLog :: MonadIO m => String -> [String] -> m [LogEntry]
darcsLog author files = do (_, _, output) <- runDarcsCommand "changes" $ ["--xml-output"] ++ files
                           -- logs <- map xmlParse output
                           return undefined

darcsRemove :: MonadIO m => FilePath -> (String, String) -> String -> m ()
darcsRemove file (author, email) logMsg = do 
    repo <- liftM repositoryPath (query GetConfig)
    runProgCommand repo Nothing "rm" "" ["-f"]
    (statusCommit, errCommit, _) <- runDarcsCommand "record" ["--patch-name="++logMsg, "-A", 
                                                              author++" <"++email++">", file]
    if statusCommit == ExitSuccess
     then return ()
     else unless (null errCommit) $ error $ "Could not darcs record " ++ file ++ "\n" ++ errCommit


-- | Add and then commit file, raising errors if either step fails.
darcsCommit :: MonadIO m => FilePath -> (String, String) -> String -> m ()
darcsCommit file (author, email) logMsg = do
  (statusAdd, errAdd, _) <- runDarcsCommand "add" [file]
  if statusAdd == ExitSuccess
     then do (statusCommit, errCommit, _) <- runDarcsCommand "record" ["-A", author ++ " <" ++
                                               email ++ ">", "-m", logMsg]
             if statusCommit == ExitSuccess
                then return ()
                else unless (null errCommit) $ error $ "Could not darcs record " ++ file ++ "\n" ++ errCommit
     else error $ "Could not darcs add " ++ file ++ "\n" ++ errAdd

-- gitGrep is just a grep on files; but *only* files which are tracked by Git.
-- Darcs doesn't support this directly, but 'darcs query manifest' will give us
-- the list of tracked files, and then we can work from there.
darcsGrep :: MonadIO m => [String] -> m String
darcsGrep patterns = do (_,_stderr,managedfiles) <- runDarcsCommand "query manifest" []
                        repo <- liftM repositoryPath (query GetConfig)
                        (_,results,_) <- runProgCommand repo Nothing "grep" (unwords patterns) (lines managedfiles)
                        return results

-- like gitLsTree, but always on HEAD
-- TODO: apparently the user of the wiki can look back in the history. The browser sends
-- a revision-ID/SHA-hash and that's how 'git ls-tree' works. With darcs, do we have to do
-- something like 
-- 'darcs get --to-patch="xmonad.hs: let's try a simpler prompt" ~/ && cd gwern && darcs query manifest'
-- for the same functionality?
darcsLsTree :: MonadIO m => String -> m [String]
darcsLsTree _ = do
    (status, errOutput, output) <- runDarcsCommand "query manifest" []
    if status == ExitSuccess
     then return (lines output)
     else error $ "'darcs query manifest' returned error status.\n" ++ errOutput

{-
darcsMergeFile :: MonadIO m => FilePath -> FilePath -> FilePath -> m String
darcsMergeFile edited original latest = do
  (status, err, out) <- runDarcsCommand "merge-file" ["--stdout", edited, original, latest]
  case status of
       ExitSuccess             -> return out
       ExitFailure n | n >= 0  -> return out  -- indicates number of merge conflicts
       _                       -> error $ "darcs merge-file returned an error.\n" ++ err

-}
_______________________________________________
darcs-users mailing list
[email protected]
http://lists.osuosl.org/mailman/listinfo/darcs-users

Reply via email to