2011-06-23 06:30:20 +00:00
|
|
|
{- git-annex v2 -> v3 upgrade support
|
2011-06-22 20:02:43 +00:00
|
|
|
-
|
2015-01-21 16:50:09 +00:00
|
|
|
- Copyright 2011 Joey Hess <id@joeyh.name>
|
2011-06-22 20:02:43 +00:00
|
|
|
-
|
2019-03-13 19:48:14 +00:00
|
|
|
- Licensed under the GNU AGPL version 3 or higher.
|
2011-06-22 20:02:43 +00:00
|
|
|
-}
|
|
|
|
|
2011-06-22 21:51:48 +00:00
|
|
|
module Upgrade.V2 where
|
2011-06-22 20:02:43 +00:00
|
|
|
|
2016-01-20 20:36:33 +00:00
|
|
|
import Annex.Common
|
2011-06-30 17:16:57 +00:00
|
|
|
import qualified Git
|
2011-12-14 19:56:11 +00:00
|
|
|
import qualified Git.Command
|
2011-12-12 22:23:24 +00:00
|
|
|
import qualified Git.Ref
|
2011-10-04 04:40:47 +00:00
|
|
|
import qualified Annex.Branch
|
2015-01-28 21:17:26 +00:00
|
|
|
import qualified Annex
|
2011-10-04 04:40:47 +00:00
|
|
|
import Annex.Content
|
2013-05-12 23:19:28 +00:00
|
|
|
import Utility.Tmp
|
2013-08-29 22:51:22 +00:00
|
|
|
import Logs
|
2015-04-03 19:35:32 +00:00
|
|
|
import Messages.Progress
|
2011-06-22 21:51:48 +00:00
|
|
|
|
2011-06-24 05:13:33 +00:00
|
|
|
olddir :: Git.Repo -> FilePath
|
|
|
|
olddir g
|
|
|
|
| Git.repoIsLocalBare g = ""
|
|
|
|
| otherwise = ".git-annex"
|
2011-06-23 06:30:20 +00:00
|
|
|
|
2011-06-23 03:37:46 +00:00
|
|
|
{- .git-annex/ moved to a git-annex branch.
|
|
|
|
-
|
|
|
|
- Strategy:
|
|
|
|
-
|
|
|
|
- * Create the git-annex branch.
|
|
|
|
- * Find each location log file in .git-annex/, and inject its content
|
|
|
|
- into the git-annex branch, unioning with any content already in
|
|
|
|
- there. (in passing, this deals with the semi transition that left
|
|
|
|
- some location logs hashed two different ways; both are found and
|
|
|
|
- merged).
|
|
|
|
- * Also inject remote.log, trust.log, and uuid.log.
|
|
|
|
- * git rm -rf .git-annex
|
|
|
|
- * Remove stuff that used to be needed in .gitattributes.
|
|
|
|
- * Commit changes.
|
|
|
|
-}
|
2011-06-22 21:51:48 +00:00
|
|
|
upgrade :: Annex Bool
|
|
|
|
upgrade = do
|
2011-07-19 18:07:23 +00:00
|
|
|
showAction "v2 to v3"
|
2011-11-08 19:34:10 +00:00
|
|
|
bare <- fromRepo Git.repoIsLocalBare
|
|
|
|
old <- fromRepo olddir
|
2011-06-24 05:15:12 +00:00
|
|
|
|
2011-10-04 04:40:47 +00:00
|
|
|
Annex.Branch.create
|
2015-04-03 17:51:32 +00:00
|
|
|
showProgressDots
|
2011-07-19 18:07:23 +00:00
|
|
|
|
2011-11-08 19:34:10 +00:00
|
|
|
e <- liftIO $ doesDirectoryExist old
|
2011-06-24 16:09:04 +00:00
|
|
|
when e $ do
|
2015-01-28 21:17:26 +00:00
|
|
|
config <- Annex.getGitConfig
|
2019-12-02 16:01:20 +00:00
|
|
|
mapM_ (\(k, f) -> inject f $ fromRawFilePath $ locationLogFile config k) =<< locationLogs
|
2011-11-08 19:34:10 +00:00
|
|
|
mapM_ (\f -> inject f f) =<< logFiles old
|
2011-06-23 18:49:21 +00:00
|
|
|
|
2012-01-28 19:41:52 +00:00
|
|
|
saveState False
|
2015-04-03 17:51:32 +00:00
|
|
|
showProgressDots
|
2011-07-05 19:06:20 +00:00
|
|
|
|
2011-11-08 19:34:10 +00:00
|
|
|
when e $ do
|
2013-03-03 17:39:07 +00:00
|
|
|
inRepo $ Git.Command.run [Param "rm", Param "-r", Param "-f", Param "-q", File old]
|
2011-12-09 05:57:13 +00:00
|
|
|
unless bare $ inRepo gitAttributesUnWrite
|
2015-04-03 17:51:32 +00:00
|
|
|
showProgressDots
|
2011-07-05 19:06:20 +00:00
|
|
|
|
2011-07-15 07:12:05 +00:00
|
|
|
unless bare push
|
2011-06-23 18:49:21 +00:00
|
|
|
|
2011-06-23 06:30:20 +00:00
|
|
|
return True
|
|
|
|
|
2011-11-08 19:34:10 +00:00
|
|
|
locationLogs :: Annex [(Key, FilePath)]
|
|
|
|
locationLogs = do
|
2020-02-14 19:22:48 +00:00
|
|
|
config <- Annex.getGitConfig
|
2011-11-08 19:34:10 +00:00
|
|
|
dir <- fromRepo gitStateDir
|
|
|
|
liftIO $ do
|
|
|
|
levela <- dirContents dir
|
|
|
|
levelb <- mapM tryDirContents levela
|
|
|
|
files <- mapM tryDirContents (concat levelb)
|
2020-02-14 19:22:48 +00:00
|
|
|
return $ mapMaybe (islogfile config) (concat files)
|
2012-11-11 04:51:07 +00:00
|
|
|
where
|
|
|
|
tryDirContents d = catchDefaultIO [] $ dirContents d
|
2020-02-14 19:22:48 +00:00
|
|
|
islogfile config f = maybe Nothing (\k -> Just (k, f)) $
|
|
|
|
locationLogFileKey config (toRawFilePath f)
|
2011-06-23 06:30:20 +00:00
|
|
|
|
|
|
|
inject :: FilePath -> FilePath -> Annex ()
|
|
|
|
inject source dest = do
|
2011-11-08 19:34:10 +00:00
|
|
|
old <- fromRepo olddir
|
|
|
|
new <- liftIO (readFile $ old </> source)
|
2019-12-02 16:01:20 +00:00
|
|
|
Annex.Branch.change (toRawFilePath dest) $ \prev ->
|
2019-01-03 17:21:48 +00:00
|
|
|
encodeBL $ unlines $ nub $ lines (decodeBL prev) ++ lines new
|
2011-06-23 06:30:20 +00:00
|
|
|
|
|
|
|
logFiles :: FilePath -> Annex [FilePath]
|
|
|
|
logFiles dir = return . filter (".log" `isSuffixOf`)
|
2012-06-14 04:01:48 +00:00
|
|
|
<=< liftIO $ getDirectoryContents dir
|
2011-06-22 20:02:43 +00:00
|
|
|
|
2011-06-24 15:59:34 +00:00
|
|
|
push :: Annex ()
|
|
|
|
push = do
|
2011-12-12 22:23:24 +00:00
|
|
|
origin_master <- inRepo $ Git.Ref.exists $ Git.Ref "origin/master"
|
2011-10-04 04:40:47 +00:00
|
|
|
origin_gitannex <- Annex.Branch.hasOrigin
|
2011-06-24 15:59:34 +00:00
|
|
|
case (origin_master, origin_gitannex) of
|
|
|
|
(_, True) -> do
|
|
|
|
-- Merge in the origin's git-annex branch,
|
|
|
|
-- so that pushing the git-annex branch
|
|
|
|
-- will immediately work. Not pushed here,
|
|
|
|
-- because it's less obnoxious to let the user
|
|
|
|
-- push.
|
2011-10-04 04:40:47 +00:00
|
|
|
Annex.Branch.update
|
2011-06-24 15:59:34 +00:00
|
|
|
(True, False) -> do
|
|
|
|
-- push git-annex to origin, so that
|
|
|
|
-- "git push" will from then on
|
|
|
|
-- automatically push it
|
2011-10-04 04:40:47 +00:00
|
|
|
Annex.Branch.update -- just in case
|
2011-07-19 18:07:23 +00:00
|
|
|
showAction "pushing new git-annex branch to origin"
|
|
|
|
showOutput
|
2013-03-03 17:39:07 +00:00
|
|
|
inRepo $ Git.Command.run
|
2014-02-19 05:09:17 +00:00
|
|
|
[ Param "push"
|
|
|
|
, Param "origin"
|
|
|
|
, Param $ Git.fromRef Annex.Branch.name
|
|
|
|
]
|
2011-06-24 15:59:34 +00:00
|
|
|
_ -> do
|
|
|
|
-- no origin exists, so just let the user
|
|
|
|
-- know about the new branch
|
2011-10-04 04:40:47 +00:00
|
|
|
Annex.Branch.update
|
2011-06-24 15:59:34 +00:00
|
|
|
showLongNote $
|
|
|
|
"git-annex branch created\n" ++
|
|
|
|
"Be sure to push this branch when pushing to remotes.\n"
|
|
|
|
|
2011-06-22 20:02:43 +00:00
|
|
|
{- Old .gitattributes contents, not needed anymore. -}
|
|
|
|
attrLines :: [String]
|
|
|
|
attrLines =
|
|
|
|
[ stateDir </> "*.log merge=union"
|
|
|
|
, stateDir </> "*/*/*.log merge=union"
|
|
|
|
]
|
|
|
|
|
|
|
|
gitAttributesUnWrite :: Git.Repo -> IO ()
|
|
|
|
gitAttributesUnWrite repo = do
|
|
|
|
let attributes = Git.attributes repo
|
|
|
|
whenM (doesFileExist attributes) $ do
|
|
|
|
c <- readFileStrict attributes
|
2011-06-30 04:42:09 +00:00
|
|
|
liftIO $ viaTmp writeFile attributes $ unlines $
|
2011-07-15 07:12:05 +00:00
|
|
|
filter (`notElem` attrLines) $ lines c
|
2013-03-03 17:39:07 +00:00
|
|
|
Git.Command.run [Param "add", File attributes] repo
|
2011-06-23 12:48:13 +00:00
|
|
|
|
|
|
|
stateDir :: FilePath
|
2011-07-15 07:12:05 +00:00
|
|
|
stateDir = addTrailingPathSeparator ".git-annex"
|
2019-12-09 17:49:05 +00:00
|
|
|
|
2011-06-23 12:48:13 +00:00
|
|
|
gitStateDir :: Git.Repo -> FilePath
|
2019-12-09 17:49:05 +00:00
|
|
|
gitStateDir repo = addTrailingPathSeparator $
|
|
|
|
fromRawFilePath (Git.repoPath repo) </> stateDir
|