support direct mode repositories with core.bare=true (not yet default)

Direct mode repositories can now have core.bare=true set, to prevent
accidentally running git commands that try to operate on the work tree,
and so do the wrong thing.

This is not yet the default, and it causes known problems for git-annex sync
due to receive.denyCurrentBranch not working in bare repositories.

This commit was sponsored by Richard Hartmann.
This commit is contained in:
Joey Hess 2013-11-05 14:24:28 -04:00
parent c2862d9585
commit 0e31234e8e
3 changed files with 48 additions and 26 deletions

View file

@ -12,7 +12,6 @@ module Annex (
AnnexState(..), AnnexState(..),
PreferredContentMap, PreferredContentMap,
new, new,
newState,
run, run,
eval, eval,
getState, getState,
@ -41,6 +40,7 @@ import Control.Concurrent
import Common import Common
import qualified Git import qualified Git
import qualified Git.Config import qualified Git.Config
import Git.Types hiding (remotes)
import Git.CatFile import Git.CatFile
import Git.CheckAttr import Git.CheckAttr
import Git.CheckIgnore import Git.CheckIgnore
@ -112,9 +112,9 @@ data AnnexState = AnnexState
} }
newState :: Git.Repo -> AnnexState newState :: Git.Repo -> AnnexState
newState gitrepo = AnnexState newState r = AnnexState
{ repo = gitrepo { repo = if annexDirect c then fixupDirect r else r
, gitconfig = extractGitConfig gitrepo , gitconfig = c
, backends = [] , backends = []
, remotes = [] , remotes = []
, output = defaultMessageState , output = defaultMessageState
@ -144,6 +144,8 @@ newState gitrepo = AnnexState
, inodeschanged = Nothing , inodeschanged = Nothing
, useragent = Nothing , useragent = Nothing
} }
where
c = extractGitConfig r
{- Makes an Annex state object for the specified git repo. {- Makes an Annex state object for the specified git repo.
- Ensures the config is read, if it was not already. -} - Ensures the config is read, if it was not already. -}
@ -247,3 +249,13 @@ withCurrentState :: Annex a -> Annex (IO a)
withCurrentState a = do withCurrentState a = do
s <- getState id s <- getState id
return $ eval s a return $ eval s a
{- Direct mode repos have core.bare=true, but are not really bare.
- Fix up the Repo to be a non-bare repo, and arrange for git commands
- run by git-annex to be passed parameters that override this setting. -}
fixupDirect :: Git.Repo -> Git.Repo
fixupDirect r@(Repo { location = Local { gitdir = d, worktree = Nothing } }) = r
{ location = Local { gitdir = d </> ".git", worktree = Just d }
, gitGlobalOpts = gitGlobalOpts r ++ [Param "-c", Param "core.bare=false"]
}
fixupDirect r = r

7
debian/changelog vendored
View file

@ -1,5 +1,10 @@
git-annex (4.20131102) UNRELEASED; urgency=low git-annex (4.20131102) UNRELEASED; urgency=low
* Direct mode repositories can now have core.bare=true set, to prevent
accidentally running git commands that try to operate on the work tree,
and so do the wrong thing.
* The -c option now not only modifies the git configuration seen by
git-annex, but it is passed along to every git command git-annex runs.
* Improve local pairing behavior when two computers both try to start * Improve local pairing behavior when two computers both try to start
the pairing process separately. the pairing process separately.
* sync: Work even when the local git repository is new and empty, * sync: Work even when the local git repository is new and empty,
@ -12,8 +17,6 @@ git-annex (4.20131102) UNRELEASED; urgency=low
* Fix zombie process that occurred when switching between repository * Fix zombie process that occurred when switching between repository
views in the webapp. views in the webapp.
* map: Work when there are gcrypt remotes. * map: Work when there are gcrypt remotes.
* The -c option now not only modifies the git configuration seen by
git-annex, but it is passed along to every git command git-annex runs.
-- Joey Hess <joeyh@debian.org> Sat, 02 Nov 2013 14:54:36 -0400 -- Joey Hess <joeyh@debian.org> Sat, 02 Nov 2013 14:54:36 -0400

View file

@ -4,8 +4,7 @@ git, and in turn point at the content of large files that is stored in
The advantage of direct mode is that you can access files directly, The advantage of direct mode is that you can access files directly,
including modifying them. The disadvantage is that most regular git including modifying them. The disadvantage is that most regular git
commands cannot safely be used, and only a subset of git-annex commands commands cannot be used in a direct mode repository.
can be used.
Normally, git-annex repositories start off in indirect mode. With some Normally, git-annex repositories start off in indirect mode. With some
exceptions: exceptions:
@ -21,7 +20,7 @@ exceptions:
Any repository can be converted to use direct mode at any time, and if you Any repository can be converted to use direct mode at any time, and if you
decide not to use it, you can convert back to indirect mode just as easily. decide not to use it, you can convert back to indirect mode just as easily.
Also, you can have one clone of a repository using direct mode, and another Also, you can have one clone of a repository using direct mode, and another
using indirect mode; direct mode interoperates. using indirect mode.
To start using direct mode: To start using direct mode:
@ -52,7 +51,6 @@ computers, and manage your files, this should not be a concern for you.
## use a direct mode repository ## use a direct mode repository
You can use most git-annex commands as usual in a direct mode repository. You can use most git-annex commands as usual in a direct mode repository.
A very few commands don't work in direct mode, and will refuse to do anything.
Direct mode also works well with the git-annex assistant. Direct mode also works well with the git-annex assistant.
@ -63,23 +61,32 @@ the changes to other repositories for `git annex sync` there to pick up,
and will pull and merge any changes made on other repositories into the and will pull and merge any changes made on other repositories into the
local repository. local repository.
While you generally will just use `git annex sync`, if you want to,
you can use `git commit --staged`, or plain `git commit`.
But not `git commit -a`, or `git commit <file>` ..
that'd commit whole large files into git!
## what doesn't work in direct mode ## what doesn't work in direct mode
`git annex status` shows incomplete information. A few other commands, A very few git-annex commands don't work in direct mode, and will refuse
like `git annex unlock` don't make sense in direct mode and will refuse to to do anything. For example, `git annex unlock` doesn't make sense in
run. direct mode.
As for git commands, you can probably use some git working tree As for git commands, direct mode prevents using any git command that would
manipulation commands, like `git checkout` and `git revert` in useful modify or access the work tree. So you cannot `git commit` or `git pull`
ways... But beware, these commands can replace files that are present in (use `git annex sync` for both instead), or run `git status`.
your repository with broken symlinks. If that file was the only copy you These git commands will complain "fatal: This operation must be run in a work tree".
had of something, it'll be lost.
This is one more reason it's wise to make git-annex untrust your direct mode The reason for this is that git doesn't understand how git-annex uses the
repositories. Still, you can lose data using these sort of git commands, so work tree in direct mode. Where git expects the symlinks that get checked
use extreme caution. into git to be checked out in the work tree, direct mode instead replaces
them with the actual content of files, as managed by git-annex.
There are still lots of git commands you can use in direct mode. For
example, you can run `git log` on files, run `git push`, `git config`,
`git remote add` etc.
## forcing git to use the work tree in direct mode
This is for experts only. You can lose data doing this, or check enormous
files directly into your git repository, and it's your fault if you do!
Also, there should be no good reason to need to do this, ever.
Ok, with the warnings out of the way, all you need to do to make any
git command access the work tree in direct mode is pass it
`-c core.bare=false`