summaryrefslogtreecommitdiff
path: root/Command/Unannex.hs
blob: d24f921a93bcbaa548656d5c534643a23ffd8f68 (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
{- git-annex command
 -
 - Copyright 2010 Joey Hess <joey@kitenet.net>
 -
 - Licensed under the GNU GPL version 3 or higher.
 -}

module Command.Unannex where

import Common.Annex
import Command
import qualified Annex
import qualified Annex.Queue
import Utility.FileMode
import Logs.Location
import Annex.Content
import qualified Git
import qualified Git.LsFiles as LsFiles

def :: [Command]
def = [command "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
				top <- fromRepo Git.workTree
				staged <- inRepo $ LsFiles.staged [top]
				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 = next $ cleanup file key

cleanup :: FilePath -> Key -> CommandCleanup
cleanup file key = do
	liftIO $ removeFile file
	inRepo $ Git.run "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 do
			-- fast mode: hard link to content in annex
			src <- fromRepo $ gitAnnexLocation key
			liftIO $ do
				createLink src 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.
	Annex.Queue.add "commit" [Param "-m", Param "content removed from git annex"] []
	
	return True