devblog
This commit is contained in:
parent
07ba5a6991
commit
78449ed2ae
2 changed files with 89 additions and 0 deletions
29
doc/devblog/day_48__direct_mode_guard_design.mdwn
Normal file
29
doc/devblog/day_48__direct_mode_guard_design.mdwn
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
I've been investigating ways to implement a [[/todo/direct_mode_guard]].
|
||||||
|
Preventing a stray `git commit -a` or `git add` doing bad things in a
|
||||||
|
direct mode repository seems increasingly important.
|
||||||
|
|
||||||
|
First, considered moving `.git`, so git won't know it's a git repository.
|
||||||
|
This doesn't seem *too* hard to do, but there will certianly be unexpected
|
||||||
|
places that assume `.git` is the directory name.
|
||||||
|
|
||||||
|
I dislike it more and more as I think about it though, because it moves
|
||||||
|
direct mode git-annex toward being entirely separate from git, and I don't
|
||||||
|
want to write my own version control system. Nor do I want to complicate
|
||||||
|
the git ecosystem with tools needing to know about git-annex to work in
|
||||||
|
such a repository.
|
||||||
|
|
||||||
|
So, I'm happy that one of the other ideas I tried today seems quite
|
||||||
|
promising. Just set core.bare=true in a direct mode repository. This nicely
|
||||||
|
blocks all git commands that operate on the working tree from doing
|
||||||
|
anything, which is just what's needed in direct mode, since they don't know
|
||||||
|
how to handle the direct mode files. But it lets all git commands and other
|
||||||
|
tools that don't touch the working tree continue to be used. You can even
|
||||||
|
run `git log file` in such a repository (surprisingly!)
|
||||||
|
|
||||||
|
It also gives an easy out for anyone who really wants to use git commands
|
||||||
|
that operate on the work tree of their direct mode repository, by just
|
||||||
|
passing `-c core.bare=false`. And it's really easy to implement in
|
||||||
|
git-annex too -- it can just notice if a repo has core.bare and
|
||||||
|
annex.direct both set, and pass that parameter to every git command it
|
||||||
|
runs. I should be able to get by with only modifying 2 functions to
|
||||||
|
implement this.
|
|
@ -20,3 +20,63 @@ add`. The git wrapper could instead be another program, or it could be
|
||||||
something like `git annex git add`
|
something like `git annex git add`
|
||||||
|
|
||||||
--[[Joey]]
|
--[[Joey]]
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
Or, no git wrapper could be provided. Limit the commands to only git-annex
|
||||||
|
commands. This should be all that is needed to manage a direct mode
|
||||||
|
repository simply, and if the user is doing something complicated that
|
||||||
|
needs git access, they can set `GIT_DIR=.git-annex` and be careful not to
|
||||||
|
shoot off their foot. (Or can just switch to indirect mode!)
|
||||||
|
|
||||||
|
This wins on simplicity, and if it's the wrong choice a git wrapper
|
||||||
|
can be added later. --[[Joey]]
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Implementation: Pretty simple really. Already did the hard lifting to
|
||||||
|
support `GIT_DIR`, so only need to override the default git directory
|
||||||
|
in direct mode when that's not set to `.git-annex`.
|
||||||
|
|
||||||
|
A few things hardcode ".git", including Assistant.Threads.Watcher.ignored
|
||||||
|
and `Seek.withPathContents`, and parts of `Git.Construct`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Transition: git-annex should detect when it's in a direct mode repository
|
||||||
|
with a .git directory and no .git-annex directory, and transparently
|
||||||
|
do the move to transition to the new scheme. (And remember that `git annex
|
||||||
|
indirect` needs to move it back.)
|
||||||
|
|
||||||
|
# alternative approach: move index
|
||||||
|
|
||||||
|
Rather than moving .git, maybe move .git/index?
|
||||||
|
|
||||||
|
This would cause git to think that all files in the tree were deleted.
|
||||||
|
So git commit -a would make a commit that removes them from git history.
|
||||||
|
But, the files in the work tree are not touched by this.
|
||||||
|
|
||||||
|
Also, git checkout, git merge, and other things that manipulate the work
|
||||||
|
tree refuse to do anything if they'd change a file that they think is
|
||||||
|
untracked.
|
||||||
|
|
||||||
|
Hmm, this does't solve the user accidentially running git add on an annexed
|
||||||
|
file; the whole file still gets added.
|
||||||
|
|
||||||
|
# alternative approach: fake bare repo
|
||||||
|
|
||||||
|
Set core.bare to true. This prevents all work tree operations,
|
||||||
|
so prevents any foot shooting. It still lets the user run commands like
|
||||||
|
git log, even on files in the tree, and git fetch, and push, and git
|
||||||
|
config, etc.
|
||||||
|
|
||||||
|
Even better, it integrates with other tools, like `mr`, so they know
|
||||||
|
it's a git repo.
|
||||||
|
|
||||||
|
This seems really promising. But of course, git-annex has its own set of
|
||||||
|
behaviors in a bare repo, so will need to recognise that this repo is not
|
||||||
|
really bare, and avoid them.
|
||||||
|
|
||||||
|
(Git may also have some bare repo behaviors that are unwanted. One example
|
||||||
|
is that git allows pushes to the current branch in a bare repo,
|
||||||
|
even when `receive.denyCurrentBranch` is set.)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue