post-recive hook to make updateInstead work in direct mode and adjusted branches

* Added post-recieve hook, which makes updateInstead work with direct
  mode and adjusted branches.
* init: Set up the post-receive hook.

This commit was sponsored by Fernando Jimenez on Patreon.
This commit is contained in:
Joey Hess 2017-02-17 14:04:43 -04:00
parent 4594bece40
commit d074532aff
No known key found for this signature in database
GPG key ID: C910D9222512E3C7
12 changed files with 138 additions and 11 deletions

View file

@ -4,7 +4,7 @@
- not change, otherwise removing old hooks using an old version of - not change, otherwise removing old hooks using an old version of
- the script would fail. - the script would fail.
- -
- Copyright 2013-2014 Joey Hess <id@joeyh.name> - Copyright 2013-2017 Joey Hess <id@joeyh.name>
- -
- Licensed under the GNU GPL version 3 or higher. - Licensed under the GNU GPL version 3 or higher.
-} -}
@ -22,6 +22,9 @@ import qualified Data.Map as M
preCommitHook :: Git.Hook preCommitHook :: Git.Hook
preCommitHook = Git.Hook "pre-commit" (mkHookScript "git annex pre-commit .") preCommitHook = Git.Hook "pre-commit" (mkHookScript "git annex pre-commit .")
postReceiveHook :: Git.Hook
postReceiveHook = Git.Hook "post-receive" (mkHookScript "git annex post-receive")
preCommitAnnexHook :: Git.Hook preCommitAnnexHook :: Git.Hook
preCommitAnnexHook = Git.Hook "pre-commit-annex" "" preCommitAnnexHook = Git.Hook "pre-commit-annex" ""

View file

@ -83,8 +83,9 @@ initialize' mversion = do
checkLockSupport checkLockSupport
checkFifoSupport checkFifoSupport
checkCrippledFileSystem checkCrippledFileSystem
unlessM isBareRepo $ unlessM isBareRepo $ do
hookWrite preCommitHook hookWrite preCommitHook
hookWrite postReceiveHook
setDifferences setDifferences
unlessM (isJust <$> getVersion) $ unlessM (isJust <$> getVersion) $
setVersion (fromMaybe defaultVersion mversion) setVersion (fromMaybe defaultVersion mversion)
@ -114,6 +115,7 @@ initialize' mversion = do
uninitialize :: Annex () uninitialize :: Annex ()
uninitialize = do uninitialize = do
hookUnWrite preCommitHook hookUnWrite preCommitHook
hookUnWrite postReceiveHook
removeRepoUUID removeRepoUUID
removeVersion removeVersion

View file

@ -24,7 +24,7 @@ module Annex.Perms (
import Annex.Common import Annex.Common
import Utility.FileMode import Utility.FileMode
import Git.SharedRepository import Git.ConfigTypes
import qualified Annex import qualified Annex
import Config import Config

View file

@ -12,6 +12,9 @@ git-annex (6.20170215) UNRELEASED; urgency=medium
* sync: Improve integration with receive.denyCurrentBranch=updateInstead, * sync: Improve integration with receive.denyCurrentBranch=updateInstead,
displaying error messages from the remote then it fails to update displaying error messages from the remote then it fails to update
its checked out branch. its checked out branch.
* Added post-recieve hook, which makes updateInstead work with direct
mode and adjusted branches.
* init: Set up the post-receive hook.
* config group groupwanted numcopies schedule wanted required: * config group groupwanted numcopies schedule wanted required:
Avoid displaying extraneous messages about repository auto-init, Avoid displaying extraneous messages about repository auto-init,
git-annex branch merging, etc, when being used to get information. git-annex branch merging, etc, when being used to get information.

View file

@ -61,6 +61,7 @@ import qualified Command.AddUnused
import qualified Command.Unlock import qualified Command.Unlock
import qualified Command.Lock import qualified Command.Lock
import qualified Command.PreCommit import qualified Command.PreCommit
import qualified Command.PostReceive
import qualified Command.Find import qualified Command.Find
import qualified Command.FindRef import qualified Command.FindRef
import qualified Command.Whereis import qualified Command.Whereis
@ -148,6 +149,7 @@ cmds testoptparser testrunner =
, Command.Uninit.cmd , Command.Uninit.cmd
, Command.Reinit.cmd , Command.Reinit.cmd
, Command.PreCommit.cmd , Command.PreCommit.cmd
, Command.PostReceive.cmd
, Command.NumCopies.cmd , Command.NumCopies.cmd
, Command.Trust.cmd , Command.Trust.cmd
, Command.Untrust.cmd , Command.Untrust.cmd

View file

@ -17,9 +17,9 @@ cmd = command "merge" SectionMaintenance
paramNothing (withParams seek) paramNothing (withParams seek)
seek :: CmdParams -> CommandSeek seek :: CmdParams -> CommandSeek
seek ps = do seek _ = do
withNothing mergeBranch ps commandAction mergeBranch
withNothing mergeSynced ps commandAction mergeSynced
mergeBranch :: CommandStart mergeBranch :: CommandStart
mergeBranch = do mergeBranch = do

61
Command/PostReceive.hs Normal file
View file

@ -0,0 +1,61 @@
{- git-annex command
-
- Copyright 2017 Joey Hess <id@joeyh.name>
-
- Licensed under the GNU GPL version 3 or higher.
-}
{-# LANGUAGE CPP #-}
module Command.PostReceive where
import Command
import qualified Annex
import Config
import Annex.Version
import Annex.AdjustedBranch
import Git.Branch
import Git.Types
import Git.ConfigTypes
import qualified Command.Merge
cmd :: Command
cmd = command "post-receive" SectionPlumbing
"run by git post-receive hook"
paramNothing
(withParams seek)
seek :: CmdParams -> CommandSeek
seek _ = whenM needUpdateInsteadEmulation $ do
fixPostReceiveHookEnv
updateInsteadEmulation
{- When run by the post-receive hook, the cwd is the .git directory,
- and GIT_DIR=. It's not clear why git does this.
-
- Fix up from that unusual situation, so that git commands
- won't try to treat .git as the work tree. -}
fixPostReceiveHookEnv :: Annex ()
fixPostReceiveHookEnv = do
g <- Annex.gitRepo
case location g of
Local { gitdir = ".", worktree = Just "." } ->
Annex.adjustGitRepo $ \g' -> pure $ g'
{ location = (location g')
{ worktree = Just ".." }
}
_ -> noop
{- receive.denyCurrentBranch=updateInstead does not work in direct mode
- repositories or when an adjusted branch is checked out, so must be
- emulated. -}
needUpdateInsteadEmulation :: Annex Bool
needUpdateInsteadEmulation = updateinsteadset <&&> (isDirect <||> isadjusted)
where
updateinsteadset = (== UpdateInstead) . receiveDenyCurrentBranch
<$> Annex.getGitConfig
isadjusted = versionSupportsUnlockedPointers
<&&> (maybe False (isJust . getAdjustment) <$> inRepo Git.Branch.current)
updateInsteadEmulation :: Annex ()
updateInsteadEmulation = commandAction Command.Merge.mergeSynced

View file

@ -1,11 +1,11 @@
{- git core.sharedRepository handling {- git config types
- -
- Copyright 2012 Joey Hess <id@joeyh.name> - Copyright 2012, 2017 Joey Hess <id@joeyh.name>
- -
- Licensed under the GNU GPL version 3 or higher. - Licensed under the GNU GPL version 3 or higher.
-} -}
module Git.SharedRepository where module Git.ConfigTypes where
import Data.Char import Data.Char
@ -14,6 +14,7 @@ import Git
import qualified Git.Config import qualified Git.Config
data SharedRepository = UnShared | GroupShared | AllShared | UmaskShared Int data SharedRepository = UnShared | GroupShared | AllShared | UmaskShared Int
deriving (Eq)
getSharedRepository :: Repo -> SharedRepository getSharedRepository :: Repo -> SharedRepository
getSharedRepository r = getSharedRepository r =
@ -26,3 +27,14 @@ getSharedRepository r =
"world" -> AllShared "world" -> AllShared
"everybody" -> AllShared "everybody" -> AllShared
v -> maybe UnShared UmaskShared (readish v) v -> maybe UnShared UmaskShared (readish v)
data DenyCurrentBranch = UpdateInstead | RefusePush | WarnPush | IgnorePush
deriving (Eq)
getDenyCurrentBranch :: Repo -> DenyCurrentBranch
getDenyCurrentBranch r =
case map toLower $ Git.Config.get "receive.denycurrentbranch" "" r of
"updateinstead" -> UpdateInstead
"warn" -> WarnPush
"ignore" -> IgnorePush
_ -> RefusePush

View file

@ -18,7 +18,7 @@ import Common
import qualified Git import qualified Git
import qualified Git.Config import qualified Git.Config
import qualified Git.Construct import qualified Git.Construct
import Git.SharedRepository import Git.ConfigTypes
import Utility.DataUnits import Utility.DataUnits
import Config.Cost import Config.Cost
import Types.UUID import Types.UUID
@ -84,6 +84,7 @@ data GitConfig = GitConfig
, annexAddUnlocked :: Bool , annexAddUnlocked :: Bool
, coreSymlinks :: Bool , coreSymlinks :: Bool
, coreSharedRepository :: SharedRepository , coreSharedRepository :: SharedRepository
, receiveDenyCurrentBranch :: DenyCurrentBranch
, gcryptId :: Maybe String , gcryptId :: Maybe String
, gpgCmd :: GpgCmd , gpgCmd :: GpgCmd
} }
@ -137,6 +138,7 @@ extractGitConfig r = GitConfig
, annexAddUnlocked = getbool (annex "addunlocked") False , annexAddUnlocked = getbool (annex "addunlocked") False
, coreSymlinks = getbool "core.symlinks" True , coreSymlinks = getbool "core.symlinks" True
, coreSharedRepository = getSharedRepository r , coreSharedRepository = getSharedRepository r
, receiveDenyCurrentBranch = getDenyCurrentBranch r
, gcryptId = getmaybe "core.gcrypt-id" , gcryptId = getmaybe "core.gcrypt-id"
, gpgCmd = mkGpgCmd (getmaybe "gpg.program") , gpgCmd = mkGpgCmd (getmaybe "gpg.program")
} }

View file

@ -0,0 +1,34 @@
# NAME
git-annex post-receive - run by git post-receive hook
# SYNOPSIS
git annex post-receive
# DESCRIPTION
This is meant to be called from git's post-receive hook. `git annex init`
automatically creates a post-receive hook using this.
When a repository is configured with receive.denyCurrentBranch=updateInstead,
pushes to the repository update its work tree. However, that does not work
for repositories that use direct mode or have an adjusted branch checked
out. The hook updates the work tree when run in such a repository,
the same as running `git-annex merge` would.
# SEE ALSO
[[git-annex]](1)
[[git-annex-direct]](1)
[[git-annex-adjust]](1)
[[git-annex-merge]](1)
# AUTHOR
Joey Hess <id@joeyh.name>
Warning: Automatically converted into a man page by mdwn2man. Edit with care.

View file

@ -542,6 +542,13 @@ subdirectories).
See [[git-annex-pre-commit]](1) for details. See [[git-annex-pre-commit]](1) for details.
* `post-receive`
This is meant to be called from git's post-receive hook. `git annex init`
automatically creates a post-receive hook using this.
See [[git-annex-post-receive]](1) for details.
* `lookupkey [file ...]` * `lookupkey [file ...]`
Looks up key used for file. Looks up key used for file.

View file

@ -743,6 +743,7 @@ Executable git-annex
Command.NotifyChanges Command.NotifyChanges
Command.NumCopies Command.NumCopies
Command.P2P Command.P2P
Command.PostReceive
Command.PreCommit Command.PreCommit
Command.Proxy Command.Proxy
Command.ReKey Command.ReKey
@ -814,6 +815,7 @@ Executable git-annex
Git.Command Git.Command
Git.Command.Batch Git.Command.Batch
Git.Config Git.Config
Git.ConfigTypes
Git.Construct Git.Construct
Git.CurrentRepo Git.CurrentRepo
Git.DiffTree Git.DiffTree
@ -839,7 +841,6 @@ Executable git-annex
Git.Remote.Remove Git.Remote.Remove
Git.Repair Git.Repair
Git.Sha Git.Sha
Git.SharedRepository
Git.Status Git.Status
Git.Tree Git.Tree
Git.Types Git.Types