summaryrefslogtreecommitdiff
path: root/Command/Unannex.hs
blob: 4d4281eb0709cf6a7a9cfbda787ecbd01e993a1c (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
74
75
76
77
78
79
80
81
82
83
84
85
{- 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 System.Posix.Files

import Command
import qualified Command.Drop
import qualified Annex
import qualified AnnexQueue
import Utility.SafeCommand
import Utility.Path
import Utility.FileMode
import LocationLog
import Types
import Content
import qualified Git
import qualified Git.LsFiles as LsFiles
import Messages
import Locations

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

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

{- The unannex subcommand undoes an add. -}
start :: FilePath -> CommandStart
start file = isAnnexed file $ \(key, _) -> do
	ishere <- inAnnex key
	if ishere
		then do
			force <- Annex.getState Annex.force
			unless force $ do
				g <- Annex.gitRepo
				staged <- liftIO $ LsFiles.staged 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
			next $ perform file key
		else stop

perform :: FilePath -> Key -> CommandPerform
perform file key = do
	ok <- Command.Drop.dropKey key (Just 0) -- always remove
	if ok
		then next $ cleanup file key
		else stop

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)

	fast <- Annex.getState Annex.fast
	if fast
		then liftIO $ do
			-- fast mode: hard link to content in annex
			createLink (gitAnnexLocation g key) file
			allowWrite file
		else do
			fromAnnex key file
			logStatus key InfoMissing
	
	-- 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.
	AnnexQueue.add "commit" [Param "-m", Param "content removed from git annex"] []
	
	return True