summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Joey Hess <joeyh@joeyh.name>2015-12-10 16:12:05 -0400
committerGravatar Joey Hess <joeyh@joeyh.name>2015-12-10 16:12:48 -0400
commit9e0360d0343575a03dce9f90e7d72c0c56deed1a (patch)
treeffc0b624843f8f71046c1d1cadc7f27b0d27d77b
parent23430aeb0b91b10e154e6610d43ae7d40595c2aa (diff)
v6 git-annex unlock
Note that the implementation uses replaceFile, so that the actual replacement of the work tree file is atomic. This seems a good property to have! It would be possible for unlock in v6 mode to be run on files that do not have their content present. However, that would be a behavior change from before, and I don't see any immediate need to support it, so I didn't implement it.
-rw-r--r--Command/Unlock.hs50
-rw-r--r--debian/changelog2
-rw-r--r--doc/git-annex-lock.mdwn2
-rw-r--r--doc/git-annex-unlock.mdwn12
-rw-r--r--doc/todo/smudge.mdwn7
5 files changed, 58 insertions, 15 deletions
diff --git a/Command/Unlock.hs b/Command/Unlock.hs
index d1b1d0e90..1cfd4a0b2 100644
--- a/Command/Unlock.hs
+++ b/Command/Unlock.hs
@@ -1,6 +1,6 @@
{- git-annex command
-
- - Copyright 2010 Joey Hess <id@joeyh.name>
+ - Copyright 2010,2015 Joey Hess <id@joeyh.name>
-
- Licensed under the GNU GPL version 3 or higher.
-}
@@ -11,6 +11,9 @@ import Common.Annex
import Command
import Annex.Content
import Annex.CatFile
+import Annex.Version
+import Annex.Link
+import Annex.ReplaceFile
import Utility.CopyFile
cmd :: Command
@@ -26,14 +29,45 @@ mkcmd n d = notDirect $ withGlobalOptions annexedMatchingOptions $
seek :: CmdParams -> CommandSeek
seek = withFilesInGit $ whenAnnexed start
-{- The unlock subcommand replaces the symlink with a copy of the file's
- - content. -}
+{- Before v6, the unlock subcommand replaces the symlink with a copy of
+ - the file's content. In v6 and above, it converts the file from a symlink
+ - to a pointer. -}
start :: FilePath -> Key -> CommandStart
-start file key = do
- showStart "unlock" file
+start file key = ifM (isJust <$> isAnnexLink file)
+ ( do
+ showStart "unlock" file
+ ifM (inAnnex key)
+ ( ifM versionSupportsUnlockedPointers
+ ( next $ performNew file key
+ , startOld file key
+ )
+ , do
+ warning "content not present; cannot unlock"
+ next $ next $ return False
+ )
+ , stop
+ )
+
+performNew :: FilePath -> Key -> CommandPerform
+performNew dest key = do
+ src <- calcRepo (gitAnnexLocation key)
+ replaceFile dest $ \tmp -> do
+ r <- linkAnnex' key src tmp
+ case r of
+ LinkAnnexOk -> return ()
+ _ -> error "linkAnnex failed"
+ next $ cleanupNew dest key
+
+cleanupNew :: FilePath -> Key -> CommandCleanup
+cleanupNew dest key = do
+ stagePointerFile dest =<< hashPointerFile key
+ return True
+
+startOld :: FilePath -> Key -> CommandStart
+startOld file key =
ifM (inAnnex key)
( ifM (isJust <$> catKeyFileHEAD file)
- ( next $ perform file key
+ ( next $ performOld file key
, do
warning "this has not yet been committed to git; cannot unlock it"
next $ next $ return False
@@ -43,8 +77,8 @@ start file key = do
next $ next $ return False
)
-perform :: FilePath -> Key -> CommandPerform
-perform dest key = ifM (checkDiskSpace Nothing key 0 True)
+performOld :: FilePath -> Key -> CommandPerform
+performOld dest key = ifM (checkDiskSpace Nothing key 0 True)
( do
src <- calcRepo $ gitAnnexLocation key
tmpdest <- fromRepo $ gitAnnexTmpObjectLocation key
diff --git a/debian/changelog b/debian/changelog
index e3ee9a34a..1b645fd06 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -9,6 +9,8 @@ git-annex (6.20151225) unstable; urgency=medium
* init: Configure .git/info/attributes to use git-annex as a smudge
filter. Note that this changes the default behavior of git add in a
newly initialized repository; it will add files to the annex.
+ * unlock, lock: In v6 mode, unlocking a file changes it from a symlink to a
+ pointer file, and this change can be committed to the git repository.
-- Joey Hess <id@joeyh.name> Tue, 08 Dec 2015 11:14:03 -0400
diff --git a/doc/git-annex-lock.mdwn b/doc/git-annex-lock.mdwn
index 4bf279fb2..b9e5d3450 100644
--- a/doc/git-annex-lock.mdwn
+++ b/doc/git-annex-lock.mdwn
@@ -9,7 +9,7 @@ git annex lock `[path ...]`
# DESCRIPTION
Use this to undo an unlock command if you don't want to modify
-the files, or have made modifications you want to discard.
+the files any longer, or have made modifications you want to discard.
# OPTIONS
diff --git a/doc/git-annex-unlock.mdwn b/doc/git-annex-unlock.mdwn
index ac8c21185..123146836 100644
--- a/doc/git-annex-unlock.mdwn
+++ b/doc/git-annex-unlock.mdwn
@@ -11,8 +11,16 @@ git annex unlock `[path ...]`
Normally, the content of annexed files is protected from being changed.
Unlocking an annexed file allows it to be modified. This replaces the
symlink for each specified file with a copy of the file's content.
-You can then modify it and `git annex add` (or `git commit`) to inject
-it back into the annex.
+You can then modify it and `git annex add` (or `git commit`) to save your
+changes.
+
+In repositories with annex.version 5 or earlier, unlocking a file is local
+to the repository, and is temporary. With version 6, unlocking a file
+changes how it is stored in the git repository (from a symlink to a pointer
+file), so you can commit it like any other change. Also in version 6, you
+can use `git add` to add a fie to the annex in unlocked form. This allows
+workflows where a file starts out unlocked, is modified as necessary, and
+is locked once it reaches its final version.
# OPTIONS
diff --git a/doc/todo/smudge.mdwn b/doc/todo/smudge.mdwn
index dd990afc7..72e062ff4 100644
--- a/doc/todo/smudge.mdwn
+++ b/doc/todo/smudge.mdwn
@@ -325,6 +325,9 @@ files to be unlocked, while the indirect upgrades don't touch the files.
#### implementation todo list
+* Dropping a smudged file causes git status to show it as modified,
+ because the timestamp has changed. Avoid this by preserving timestamp
+ of smudged files when manipulating.
* linkAnnex should check disk reserve when it falls back to copying the
file.
* Reconcile staged changes into the associated files database, whenever
@@ -337,10 +340,6 @@ files to be unlocked, while the indirect upgrades don't touch the files.
(when not in direct mode).
However, beware over-optimisation breaking the assistant or perhaps other
long-lived processes.
-* Convert `git annex unlock` to stage a pointer file, and hard link to the
- annexed object (or write pointer file if annexed object not present).
- - Also needs to thaw annex object file
- - Also needs to update associated files db.
* Convert `git annex lock` to verify that worktree file is not modified
(same check used when updating pointer files to the content of a key),
and then delete the worktree file and replace with an annex symlink.