summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2010-10-27 14:33:44 -0400
committerGravatar Joey Hess <joey@kitenet.net>2010-10-27 14:33:44 -0400
commit563484e1354878df4a6877e4506af0d70e41b13e (patch)
tree119b65ec7fa76f1f6a72c25739f48bce1a58c146
parent3281a1cb19e25f964ca9b91877a194fcb216ca5d (diff)
pre-commit hook
-rw-r--r--Commands.hs20
-rw-r--r--Core.hs15
-rw-r--r--debian/changelog3
-rw-r--r--doc/git-annex.mdwn12
-rw-r--r--doc/todo/symlink_farming_commit_hook.mdwn2
-rw-r--r--doc/walkthrough.mdwn18
6 files changed, 55 insertions, 15 deletions
diff --git a/Commands.hs b/Commands.hs
index 015a2d822..b6bc6dfc2 100644
--- a/Commands.hs
+++ b/Commands.hs
@@ -68,7 +68,7 @@ doSubCmd cmdname start param = do
{- A subcommand can broadly want one of several kinds of input parameters.
- This allows a first stage of filtering before starting a subcommand. -}
data SubCmdWants = FilesInGit | FilesNotInGit | FilesMissing
- | Description | Keys | Tempfile
+ | Description | Keys | Tempfile | FilesToBeCommitted
data SubCommand = Command {
subcmdname :: String,
@@ -91,7 +91,9 @@ subCmds = [
, (Command "unannex" unannexStart FilesInGit
"undo accidential add command")
, (Command "fix" fixStart FilesInGit
- "fix up files' symlinks to point to annexed content")
+ "fix up symlinks to point to annexed content")
+ , (Command "pre-commit" fixStart FilesToBeCommitted
+ "fix up symlinks before they are committed")
, (Command "fromkey" fromKeyStart FilesMissing
"adds a file using a specific key")
, (Command "dropkey" dropKeyStart Keys
@@ -130,7 +132,7 @@ usage = usageInfo header options ++ "\nSubcommands:\n" ++ cmddescs
cmddescs = unlines $ map (\c -> indent $ showcmd c) subCmds
showcmd c =
(subcmdname c) ++
- (pad 10 (subcmdname c)) ++
+ (pad 11 (subcmdname c)) ++
(descWanted (subcmdwants c)) ++
(pad 13 (descWanted (subcmdwants c))) ++
(subcmddesc c)
@@ -161,6 +163,17 @@ findWanted FilesMissing params repo = do
if (e) then return False else return True
findWanted Description params _ = do
return $ [unwords params]
+findWanted FilesToBeCommitted params repo = do
+ files <- mapM gitcached params
+ return $ foldl (++) [] files
+ where
+ gitcached p = do
+ -- ask git for files staged for commit that
+ -- are being added, moved, or changed (but not deleted)
+ fs0 <- Git.pipeRead repo ["diff", "--cached",
+ "--name-only", "--diff-filter=ACMRT",
+ "-z", "HEAD", p]
+ return $ filter (not . null) $ split "\0" fs0
findWanted _ params _ = return params
{- Parses command line and returns two lists of actions to be
@@ -360,6 +373,7 @@ initPerform description = do
u <- getUUID g
describeUUID u description
liftIO $ gitAttributes g
+ liftIO $ gitPreCommitHook g
return $ Just $ initCleanup
initCleanup :: Annex Bool
initCleanup = do
diff --git a/Core.hs b/Core.hs
index 80bf56cc4..254bcec51 100644
--- a/Core.hs
+++ b/Core.hs
@@ -73,6 +73,21 @@ gitAttributes repo = do
Git.run repo ["commit", "-m", "git-annex setup",
attributes]
+{- set up a git pre-commit hook, if one is not already present -}
+gitPreCommitHook :: Git.Repo -> IO ()
+gitPreCommitHook repo = do
+ let hook = (Git.workTree repo) ++ "/" ++ (Git.dir repo) ++
+ "/hooks/pre-commit"
+ exists <- doesFileExist hook
+ if (exists)
+ then putStrLn $ "pre-commit hook (" ++ hook ++ ") already exists, not configuring"
+ else do
+ writeFile hook $ "#!/bin/sh\n" ++
+ "# automatically configured by git-annex\n" ++
+ "git annex pre-commit .\n"
+ p <- getPermissions hook
+ setPermissions hook $ p {executable = True}
+
{- Checks if a given key is currently present in the annexLocation.
-
- This can be run against a remote repository to check the key there. -}
diff --git a/debian/changelog b/debian/changelog
index fd1fddafd..d0922c1c5 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -4,6 +4,9 @@ git-annex (0.02) UNRELEASED; urgency=low
file content when dropping files.
* New move subcommand, that can move files from or to a remote.
* New fromkey subcommand, for registering urls, etc.
+ * git-annex init will now set up a pre-commit hook that fixes up symlinks
+ before they are committed, to ensure that moving symlinks around does not
+ break them.
* Add remote.annex-ignore git config setting to allow completly disabling
a given remote.
* --from/--to can be used to control the remote repository that git-annex
diff --git a/doc/git-annex.mdwn b/doc/git-annex.mdwn
index 417ff7e58..f7bb64988 100644
--- a/doc/git-annex.mdwn
+++ b/doc/git-annex.mdwn
@@ -107,9 +107,13 @@ Many git-annex subcommands will stage changes for later `git commit` by you.
Fixes up symlinks that have become broken to again point to annexed content.
This is useful to run if you have been moving the symlinks around.
- You do not normally need to run this by hand since `git-annex init`
- installs a pre-commit hook that automatically fixes up symlinks when
- they are committed.
+* pre-commit [path ...]
+
+ Fixes up symlinks that are staged as part of a commit, to ensure they
+ point to annexed content.
+
+ This is meant to be called from git's pre-commit hook. `git annex init`
+ automatically creates a pre-commit hook using this.
* fromkey file
@@ -202,7 +206,7 @@ decscriptions. You may edit it.
`.git-annex/*.log` is where git-annex records its content tracking
information. These files should be committed to git.
-`.git-annex/.gitattributes` is configured to use git's union merge driver
+`.gitattributes` is configured to use git's union merge driver
to avoid conflicts when merging files in the `.git-annex` directory.
# AUTHOR
diff --git a/doc/todo/symlink_farming_commit_hook.mdwn b/doc/todo/symlink_farming_commit_hook.mdwn
index af03beb70..3e93cb34b 100644
--- a/doc/todo/symlink_farming_commit_hook.mdwn
+++ b/doc/todo/symlink_farming_commit_hook.mdwn
@@ -10,3 +10,5 @@ up.
back to git-annex. If you want to have your own shell script in the post-commit
hook, just make it call `git annex` with no parameters. git-annex will detect
when it's run from a git hook and do the necessary fixups.
+
+[[done]]
diff --git a/doc/walkthrough.mdwn b/doc/walkthrough.mdwn
index ce68a77f7..b49a00f19 100644
--- a/doc/walkthrough.mdwn
+++ b/doc/walkthrough.mdwn
@@ -43,23 +43,25 @@ if you are using a centralized bare repository.
add debian.iso ok
# git commit -a -m added
-Notice you commit at the end, this checks in git-annex's record of the
-files but not their actual, large, content.
+When you add a file to the annex and commit it, only a symlink to
+the annexed content is committed. The content itself is stored in
+git-annex's backend.
## renaming files
# cd ~/annex
# git mv big_file my_cool_big_file
# mkdir iso
- # git mv debian.iso iso
- # git annex fix .
- fix iso/debian.iso ok
+ # git mv debian.iso iso/
# git commit -m moved
You can use any normal git operations to move files around, or even
-make copies or delete them. `git-annex fix` needs to be run if a file
-is moved into a different directory, in order to fix up the symlink
-pointing to the file's content.
+make copies or delete them.
+
+Notice that, since annexed files are represented by symlinks,
+the symlink will break when the file is moved into a subdirectory.
+But, git-annex will fix this up for you when you commit --
+it has a pre-commit hook that watches for and corrects broken symlinks.
## getting file content