Add new environment variable $GIT_SUPER_DIR

If $GIT_SUPER_DIR is defined, the repository is split into two places:

 - HEAD, logs/HEAD, index, other top-level refs and unrecognized files
   are from $GIT_DIR

 - the rest like objects, refs, info, hooks, packed-refs, shallow...
   are from $GIT_SUPER_DIR

 - $GIT_DIR/shared is the new thing, intended for third party commands
   because if they put things any unknown places, they will be
   considered worktree-specific and are only visible by one repo

Scripts are supposed to retrieve paths in $GIT_DIR with
"git rev-parse --git-path" if they may belong to $GIT_SUPER_DIR.

Note that logs/refs/.tmp-renamed-log is used to prepare new reflog
entry and it's supposed to be on the same filesystem as the target
reflog file. This is not guaranteed true for logs/HEAD when it's
mapped to repos/xx/logs/HEAD because the user can put "repos"
directory on different filesystem. Don't mess with .git unless you
know what you're doing.

The redirection is done by git_path(), git_pathdup() and
strbuf_git_path(). The selected list of paths goes to $GIT_SUPER_DIR,
not the other way around in case a developer adds a new
worktree-specific file and it's accidentally promoted to be shared
across repositories (this includes unknown files added by third party
commands)

The list of known files that belong to $GIT_DIR are:

ADD_EDIT.patch BISECT_ANCESTORS_OK BISECT_EXPECTED_REV BISECT_LOG
BISECT_NAMES CHERRY_PICK_HEAD COMMIT_MSG FETCH_HEAD HEAD MERGE_HEAD
MERGE_MODE MERGE_RR NOTES_EDITMSG NOTES_MERGE_WORKTREE ORIG_HEAD
REVERT_HEAD SQUASH_MSG TAG_EDITMSG fast_import_crash_* logs/HEAD
next-index-* rebase-apply rebase-merge rsync-refs-* sequencer/*
shallow_*

The list of those belonging to $GIT_SUPER_DIR is a bit shorter and
hard coded in path.c:update_super_dir().

Path mapping is NOT done for git_path_submodule(). Split-repos are not
supported as submodules.
git-sh-setup.sh: use rev-parse --git-path to get $GIT_DIR/objects

If $GIT_SUPER_DIR is set, $GIT_OBJECT_DIRECTORY should be
$GIT_SUPER_DIR/objects. Just let rev-parse --git-path handle it.
*.sh: avoid hardcoding $GIT_DIR/hooks/...

If $GIT_SUPER_DIR is defined, it should become
$GIT_SUPER_DIR/hooks/... Just let rev-parse --git-path handle it.
git-stash: avoid hardcoding $GIT_DIR/logs/....
setup.c: refactor path manipulation out of read_gitfile()
setup.c: add split-repo support to is_git_directory()

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
setup.c: add split-repo support to .git files

If a .git file contains

gitsuper: <path>
gitdir: <id>

then we set GIT_SUPER_DIR to <path> and GIT_DIR to
$GIT_SUPER_DIR/repos/<id>.
setup.c: reduce cleanup sites in setup_explicit_git_dir()

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
environment.c: support super .git file specified by $GIT_DIR
setup: support $GIT_SUPER_DIR as well as super .git files

The same rules for git repo setup apply except:

- detect super .git files, set $GIT_SUPER_DIR accordingly

- if $GIT_SUPER_DIR is set (or specified by super .git files), look
  for non-worktree stuff in this directory instead of $GIT_DIR. This
  mostly affects is_git_directory() and check_repository_format()

- the worktree setting precedence goes from lower to higher:
  core.worktree, GIT_SUPER_DIR then GIT_WORK_TREE
path.c: update enter_repo() to support super .git files

This allow the split repo to be fetched from, or pushed to using smart
protocols.
git_path: visibility of worktree information from other worktrees

This makes "repos" a shared repository, which means all split-repos
can see HEAD of others. HEAD of the original worktree is not in
"repos" and can't be seen this way. Original worktree is mapped to
"super" instead.
wrapper.c: wrapper to open a file, fprintf then close
use new wrapper write_file() for simple file writing

This fixes common problems in these code about error handling,
forgetting to close the file handle after fprintf() fails, or not
printing out the error string..
checkout: support checking out into a new working directory

"git checkout --to" sets up a new repository linked to the current one
with the new .git file format. It then creates a fake commit with
empty tree and executes "git checkout" again on the new worktree with
the same arguments except "--to" is taken out. The second checkout,
which is not tamed with any info from the current repository, will
carry out normal operations that checkout does.

$GIT_DIR/repos is made shared across working directories so all can
see how many working directories are attached to a repository and take
appropriate action.
checkout: clean up half-prepared directories in --to mode
setup.c: keep track of the .git file location if read
prune: strategies for split repositories

alias REPO=$GIT_SUPER_DIR/repos/<id>

 - split repos are supposed to update mtime of $REPO/gitdir

 - split repos are supposed to keep its location in $REPO/gitdir up to
   date

 - "git checkout --to" is supposed to create $REPO/locked if the new
   repo is on a different partition than the shared one.

 - "git checkout --to" is supposed to make hardlink named $REPO/link
   pointing to the .git file

The pruning rules are:

 - if $REPO/locked exists, repos/<id> is not supposed to be pruned.

 - if $REPO/locked exists and $REPO/gitdir's mtimer is older than a
   really long limit, warn about old unused repo.

 - if $REPO/link exists and its link count is 1, repos/<id> is to be
   pruned.

 - if $REPO/gitdir's mtime is older than a limit, and it points to
   nowhere, repos/<id> is to be pruned. Warn about it some time before
   the prune time.
refs: adjust reflog path for repos/<id>/HEAD and super/logs/HEAD

The normal rule is given ref "abc", its reflog path is
"logs/abc". It's not true for "repos/<id>/HEAD" because the correct
reflog path is "repos/<id>/logs/HEAD", not "logs/repos/<id>/HEAD".
The same rule applies to "super/HEAD".
refs: detach split repos' HEAD when the linked ref is updated/deleted

This is effective when a ref is updated from the super repository as
well as all linked repositories because "repos" directory is shared
between all repos.

We could even forbid a ref update if it's some repo's HEAD. But I'd
rather see a generic, permanent ref locking mechanism in place first
and make use of it.