git-annex/doc/internals/lockdown.mdwn
Joey Hess 7189dfd77d git-annex (5.20131127) unstable; urgency=low
* webapp: Detect when upgrades are available, and upgrade if the user
    desires.
    (Only when git-annex is installed using the prebuilt binaries
    from git-annex upstream, not from eg Debian.)
  * assistant: Detect when the git-annex binary is modified or replaced,
    and either prompt the user to restart the program, or automatically
    restart it.
  * annex.autoupgrade configures both the above upgrade behaviors.
  * Added support for quvi 0.9. Slightly suboptimal due to limitations in its
    interface compared with the old version.
  * Bug fix: annex.version did not get set on automatic upgrade to v5 direct
    mode repo, so the upgrade was performed repeatedly, slowing commands down.
  * webapp: Fix bug that broke switching between local repositories
    that use the new guarded direct mode.
  * Android: Fix stripping of the git-annex binary.
  * Android: Make terminal app show git-annex version number.
  * Android: Re-enable XMPP support.
  * reinject: Allow to be used in direct mode.
  * Futher improvements to git repo repair. Has now been tested in tens
    of thousands of intentionally damaged repos, and successfully
    repaired them all.
  * Allow use of --unused in bare repository.

# imported from the archive
2013-11-27 18:41:44 -04:00

44 lines
2.2 KiB
Markdown

Object files stored in `.git/annex/objects` are each put in their own directory.
This allows the write bit to be removed from both the file, and its directory,
which prevents accidentially deleting or changing the file contents.
The reasoning for doing this follows:
Normally with git, once you have committed a file, editing the file in the
working tree cannot cause you to lose the committed version. This is an
important property of git. Of course you can `rm -rf .git` and delete
commits if you like (before you've pushed them). But you can't lose a
committed version of the file because of something you do with the working
tree version.
It's easy for git to do this, because committing a file makes a copy of it.
But git-annex does not make a local copy of a file added to it, because
the file could be very large.
So, it's important for git-annex to find another way to preserve the expected
property that once committed, you cannot accidentially lose a file.
The most important protection it makes is just to remove the write bit of
the file. Thus preventing programs from modifying it.
But, that does not prevent any program that might follow the symlink and
delete the symlinked file. This might seem an unlikely thing for a program to
do at first, but consider a command like:
`tar cf foo.tar foo --remove-files --dereference`
When I tested this, I didn't know if it would remove the file foo symlinked
to or not! It turned out that my tar doesn't remove it. But it could
have easily went the other way.
Rather than needing to worry about every possible program that might
decide to do something like this, git-annex removes the write bit from the
directory containing the annexed object, as well as removing the write
bit from the file. (The only bad consequence of this is that `rm -rf .git`
doesn't work unless you first run `chmod -R +w .git`)
----
It's known that this lockdown mechanism is incomplete. The worst hole in
it is that if you explicitly run `chmod +w` on an annexed file in the working
tree, this follows the symlink and allows writing to the file. It would be
better to make the files fully immutable. But most systems either don't
support immutable attributes, or only let root make files immutable.