From b27760aa68d8c4cf1a1b0be3c3a5582539f857b5 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Mon, 12 Mar 2012 22:53:43 -0400 Subject: Work around a bug in rsync (IMHO) introduced by openSUSE's SIP patch. openSUSE patches rsync with a patch adding SIP protocol support. https://gist.github.com/2026167 With this patch, running rsync with no hostname parameter is apparently supposed to list SIP hosts on the network. Practically, it does nothing and exits 0. git-annex uses rsync in a very special way to allow git-annex-shell to be run on the remote host, and so did not need to specify a hostname, or a file to transfer as a rsync parameter. So it sent ":", a degenerate case of "host:file". But the patch cannot differentiate ":" with no host parameter (a bug in the SIP patch surely). Results were that getting files failed, as rsync seemed to succeed, but the requested file failed to arrive. Also I think that sending files will make git-annex think a file has been transferred to the remote when really rsync does nothing. The workaround for this buggy rsync patch is to use "dummy:" as the hostname. --- Remote/Git.hs | 7 +++++-- debian/changelog | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Remote/Git.hs b/Remote/Git.hs index 29c50e87f..12a7f1844 100644 --- a/Remote/Git.hs +++ b/Remote/Git.hs @@ -290,10 +290,13 @@ rsyncParamsRemote r sending key file = do then return $ o ++ eparam ++ [dummy, File file] else return $ o ++ eparam ++ [File file, dummy] where - -- the rsync shell parameter controls where rsync + -- The rsync shell parameter controls where rsync -- goes, so the source/dest parameter can be a dummy value, -- that just enables remote rsync mode. - dummy = Param ":" + -- For maximum compatability with some patched rsyncs, + -- the dummy value needs to still contain a hostname, + -- even though this hostname will never be used. + dummy = Param "dummy:" rsyncParams :: Git.Repo -> Annex [CommandParam] rsyncParams r = do diff --git a/debian/changelog b/debian/changelog index 8fc2cc330..63797f2ad 100644 --- a/debian/changelog +++ b/debian/changelog @@ -8,6 +8,7 @@ git-annex (3.20120310) UNRELEASED; urgency=low are present in the annex in memory. * status: Fixed to run in constant space. * status: More accurate display of sizes of tmp and bad keys. + * Work around a bug in rsync (IMHO) introduced by openSUSE's SIP patch. -- Joey Hess Sat, 10 Mar 2012 14:03:22 -0400 -- cgit v1.2.3 From f047e04179a7366e9e20b7c5805242f97e6ae6c7 Mon Sep 17 00:00:00 2001 From: "https://www.google.com/accounts/o8/id?id=AItOawm2MUhwzcOSnZfYnmWu7_2dMrH4064OKyQ" Date: Wed, 14 Mar 2012 11:09:32 +0000 Subject: --- doc/forum/post-copy__47__sync_hook.mdwn | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 doc/forum/post-copy__47__sync_hook.mdwn diff --git a/doc/forum/post-copy__47__sync_hook.mdwn b/doc/forum/post-copy__47__sync_hook.mdwn new file mode 100644 index 000000000..05fbc0b29 --- /dev/null +++ b/doc/forum/post-copy__47__sync_hook.mdwn @@ -0,0 +1,14 @@ +Hi, + +I have the following setup: +- normal git repository with website code. +- git annex repository to hold large set of binary data (pdfs, flashmovies, etc) that belongs to the site. + +I use git annex so I (and other developers) don't need to copy 1.4Gb+ of binary data for every working copy. (Data that is mostly left untouched.) Using git annex copy --to=origin I can simply only add new additions to this media/binary repository, without first pulling all the data. So far so good. + +When commits are pushed to a certain branch on the normal git repository, a post-receive hook exports (GIT_WORK_TREE=/data/site/ git checkout $branch -f) the updated repository to an apache documentroot. Thereby updating the staging server of the website. + +My question is, how can I do the same thing for my git annex repository? Since post-receive fires on receiving the annex hashes, and not the actual files. Those are rsynced, and I cannot find a way to trigger an action after all files are copied by git annex via rsync. + +Any tips? + -- cgit v1.2.3 From 5b869eef911d36627174ed5a02452011effc2a14 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 14 Mar 2012 12:01:56 -0400 Subject: git-annex-shell: Runs hooks/annex-content after content is received or dropped. --- Command/Commit.hs | 7 ++++++- Git.hs | 14 ++++++++++++-- debian/changelog | 2 ++ doc/git-annex-shell.mdwn | 8 ++++++++ 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/Command/Commit.hs b/Command/Commit.hs index 2bb016ea0..19b0bc250 100644 --- a/Command/Commit.hs +++ b/Command/Commit.hs @@ -7,8 +7,10 @@ module Command.Commit where +import Common.Annex import Command import qualified Annex.Branch +import qualified Git def :: [Command] def = [command "commit" paramNothing seek @@ -20,4 +22,7 @@ seek = [withNothing start] start :: CommandStart start = next $ next $ do Annex.Branch.commit "update" - return True + runhook =<< (inRepo $ Git.hookPath "annex-content") + where + runhook (Just hook) = liftIO $ boolSystem hook [] + runhook Nothing = return True diff --git a/Git.hs b/Git.hs index 284bf331c..043cda5ea 100644 --- a/Git.hs +++ b/Git.hs @@ -24,12 +24,14 @@ module Git ( gitDir, configTrue, attributes, + hookPath, assertLocal, ) where import qualified Data.Map as M import Data.Char import Network.URI (uriPath, uriScheme, unEscapeString) +import System.Directory import Common import Git.Types @@ -93,17 +95,25 @@ configBare repo = maybe unknown (fromMaybe False . configTrue) $ " is a bare repository; config not read" {- Path to a repository's gitattributes file. -} -attributes :: Repo -> String +attributes :: Repo -> FilePath attributes repo | configBare repo = workTree repo ++ "/info/.gitattributes" | otherwise = workTree repo ++ "/.gitattributes" {- Path to a repository's .git directory. -} -gitDir :: Repo -> String +gitDir :: Repo -> FilePath gitDir repo | configBare repo = workTree repo | otherwise = workTree repo ".git" +{- Path to a given hook script in a repository, only if the hook exists + - and is executable. -} +hookPath :: String -> Repo -> IO (Maybe FilePath) +hookPath script repo = do + let hook = gitDir repo "hooks" script + ok <- doesFileExist hook + return $ if ok then Just hook else Nothing + {- Path to a repository's --work-tree, that is, its top. - - Note that for URL repositories, this is the path on the remote host. -} diff --git a/debian/changelog b/debian/changelog index 63797f2ad..b6b62708e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -9,6 +9,8 @@ git-annex (3.20120310) UNRELEASED; urgency=low * status: Fixed to run in constant space. * status: More accurate display of sizes of tmp and bad keys. * Work around a bug in rsync (IMHO) introduced by openSUSE's SIP patch. + * git-annex-shell: Runs hooks/annex-content after content is received + or dropped. -- Joey Hess Sat, 10 Mar 2012 14:03:22 -0400 diff --git a/doc/git-annex-shell.mdwn b/doc/git-annex-shell.mdwn index 0fd77a811..89a05b1d6 100644 --- a/doc/git-annex-shell.mdwn +++ b/doc/git-annex-shell.mdwn @@ -49,6 +49,7 @@ first "/~/" or "/~user/" is expanded to the specified home directory. * commit This commits any staged changes to the git-annex branch. + It also runs the annex-content hook. # OPTIONS @@ -60,6 +61,13 @@ to git-annex-shell are: git-annex uses this to specify the UUID of the repository it was expecting git-annex-shell to access, as a sanity check. +# HOOK + +After content is received or dropped from the repository by git-annex-shell, +it runs a hook, `.git/hooks/annex-content` (or `hooks/annex-content` on a bare +repository). The hook is not currently passed any information about what +changed. + # ENVIRONMENT * GIT_ANNEX_SHELL_READONLY -- cgit v1.2.3 From f974a200871d11edc44af5e5acad491f9653ad12 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 14 Mar 2012 12:17:38 -0400 Subject: check hook executability --- Git.hs | 10 ++++++++-- Utility/FileMode.hs | 7 +++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Git.hs b/Git.hs index 043cda5ea..9b7dccfeb 100644 --- a/Git.hs +++ b/Git.hs @@ -32,9 +32,11 @@ import qualified Data.Map as M import Data.Char import Network.URI (uriPath, uriScheme, unEscapeString) import System.Directory +import System.Posix.Files import Common import Git.Types +import Utility.FileMode {- User-visible description of a git repo. -} repoDescribe :: Repo -> String @@ -111,8 +113,12 @@ gitDir repo hookPath :: String -> Repo -> IO (Maybe FilePath) hookPath script repo = do let hook = gitDir repo "hooks" script - ok <- doesFileExist hook - return $ if ok then Just hook else Nothing + e <- doesFileExist hook + if e + then do + m <- fileMode <$> getFileStatus hook + return $ if isExecutable m then Just hook else Nothing + else return Nothing {- Path to a repository's --work-tree, that is, its top. - diff --git a/Utility/FileMode.hs b/Utility/FileMode.hs index 6c1c06e82..571b03503 100644 --- a/Utility/FileMode.hs +++ b/Utility/FileMode.hs @@ -34,3 +34,10 @@ allowWrite f = do {- Checks if a file mode indicates it's a symlink. -} isSymLink :: FileMode -> Bool isSymLink mode = symbolicLinkMode `intersectFileModes` mode == symbolicLinkMode + +{- Checks if a file has any executable bits set. -} +isExecutable :: FileMode -> Bool +isExecutable mode = ebits `intersectFileModes` mode /= 0 + where + ebits = ownerExecuteMode `unionFileModes` + groupExecuteMode `unionFileModes` otherExecuteMode -- cgit v1.2.3 From c26fbecaf48b60f0bf9cb4e8e7880adcf19ceee3 Mon Sep 17 00:00:00 2001 From: "http://joey.kitenet.net/" Date: Wed, 14 Mar 2012 16:23:26 +0000 Subject: Added a comment --- .../comment_1_c8322d4b9bbf5eac80b48c312a42fbcf._comment | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 doc/forum/post-copy__47__sync_hook/comment_1_c8322d4b9bbf5eac80b48c312a42fbcf._comment diff --git a/doc/forum/post-copy__47__sync_hook/comment_1_c8322d4b9bbf5eac80b48c312a42fbcf._comment b/doc/forum/post-copy__47__sync_hook/comment_1_c8322d4b9bbf5eac80b48c312a42fbcf._comment new file mode 100644 index 000000000..04a6f4668 --- /dev/null +++ b/doc/forum/post-copy__47__sync_hook/comment_1_c8322d4b9bbf5eac80b48c312a42fbcf._comment @@ -0,0 +1,11 @@ +[[!comment format=mdwn + username="http://joey.kitenet.net/" + nickname="joey" + subject="comment 1" + date="2012-03-14T16:23:25Z" + content=""" +I've made git-annex-shell run the git `hooks/annex-content` after content is received or dropped. + +Note that the clients need to be running at least git-annex version 3.20120227 , which runs git-annex-shell commit, which runs the hook. + +"""]] -- cgit v1.2.3 From 6cb4743cfb105427a00b551ebd51fc5c9626bfea Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 14 Mar 2012 12:39:09 -0400 Subject: ignore hook exit status --- Command/Commit.hs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Command/Commit.hs b/Command/Commit.hs index 19b0bc250..1c82ed7df 100644 --- a/Command/Commit.hs +++ b/Command/Commit.hs @@ -22,7 +22,8 @@ seek = [withNothing start] start :: CommandStart start = next $ next $ do Annex.Branch.commit "update" - runhook =<< (inRepo $ Git.hookPath "annex-content") + _ <- runhook =<< (inRepo $ Git.hookPath "annex-content") + return True where runhook (Just hook) = liftIO $ boolSystem hook [] runhook Nothing = return True -- cgit v1.2.3