summaryrefslogtreecommitdiff
path: root/Command/Unannex.hs
blob: 42dc1fb0abc625cbc2bb8ddcef75865b08fa14b1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
{- git-annex command
 -
 - Copyright 2010 Joey Hess <joey@kitenet.net>
 -
 - Licensed under the GNU GPL version 3 or higher.
 -}

module Command.Unannex where

import Control.Monad.State (liftIO)
import Control.Monad (unless)
import System.Directory

import Command
import qualified Annex
import Utility
import qualified Backend
import LocationLog
import Types
import Content
import qualified GitRepo as Git
import Messages

command :: [Command]
command = [Command "unannex" paramPath seek "undo accidential add command"]

seek :: [CommandSeek]
seek = [withFilesInGit start]

{- The unannex subcommand undoes an add. -}
start :: CommandStartString
start file = isAnnexed file $ \(key, backend) -> do
	ishere <- inAnnex key
	if ishere
		then do
			force <- Annex.getState Annex.force
			unless force $ do
				g <- Annex.gitRepo
				staged <- liftIO $ Git.stagedFiles g [Git.workTree g]
				unless (null staged) $
					error "This command cannot be run when there are already files staged for commit."
				Annex.changeState $ \s -> s { Annex.force = True }

			showStart "unannex" file
			return $ Just $ perform file key backend
		else return Nothing

perform :: FilePath -> Key -> Backend Annex -> CommandPerform
perform file key backend = do
	-- force backend to always remove
	ok <- Backend.removeKey backend key (Just 0)
	if ok
		then return $ Just $ cleanup file key
		else return Nothing

cleanup :: FilePath -> Key -> CommandCleanup
cleanup file key = do
	g <- Annex.gitRepo

	liftIO $ removeFile file
	liftIO $ Git.run g "rm" [Params "--quiet --", File file]
	-- git rm deletes empty directories; put them back
	liftIO $ createDirectoryIfMissing True (parentDir file)

	fromAnnex key file
	logStatus key ValueMissing
	
	-- Commit staged changes at end to avoid confusing the
	-- pre-commit hook if this file is later added back to
	-- git as a normal, non-annexed file.
	Annex.queue "commit" [Params "-a -m", Param "content removed from git annex"] "-a"
	
	return True