Make git_path() aware of file relocation in $GIT_DIR

We allow the user to relocate certain paths out of $GIT_DIR via
environment variables, e.g. GIT_OBJECT_DIRECTORY, GIT_INDEX_FILE and
GIT_GRAFT_FILE. All callers are not supposed to use git_path() or
git_pathdup() to get those paths. Instead they must use
get_object_directory(), get_index_file() and get_graft_file()
respectively. This is inconvenient and could be missed in review
(there's git_path("objects/info/alternates") somewhere in
sha1_file.c).

This patch makes git_path() and git_pathdup() understand those
environment variables. So if you set GIT_OBJECT_DIRECTORY to /foo/bar,
git_path("objects/abc") should return /tmp/bar/abc. The same is done
for the two remaining env variables.

"git rev-parse --git-path" is the wrapper of this function for scripts
to use. For third party scripts that want to support old versions as
well, something like this as a wrapper might help:

  git_path() { git rev-parse --git-path "$1" || echo "$GIT_DIR/$1"; }
*.sh: respect $GIT_INDEX_FILE
reflog: avoid constructing .lock path with git_path

git_path() soon understands the path given to it. Some paths "abc" may
become "def" while other "ghi" may become "ijk". We don't want
git_path() to interfere with .lock path construction. Concatenate
".lock" after the path has been resolved by git_path() so if "abc"
becomes "def", we'll have "def.lock", not "ijk".
fast-import: use git_path() for accessing .git dir instead of get_git_dir()

This allows git_path() to redirect info/fast-import to another place
if needed
commit: use SEQ_DIR instead of hardcoding "sequencer"
Add new environment variable $GIT_COMMON_DIR

This variable is intended to support multiple working directories
attached to a repository. Such a repository may have a main working
directory, created by either "git init" or "git clone" and one or more
linked working directories. These working directories and the main
repository share the same repository directory.

In linked working directories, $GIT_COMMON_DIR must be defined to point
to the real repository directory and $GIT_DIR points to an unused
subdirectory inside $GIT_COMMON_DIR. File locations inside the
repository are reorganized from the linked worktree view point:

 - worktree-specific such as 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_COMMON_DIR

Scripts are supposed to retrieve paths in $GIT_DIR with
"git rev-parse --git-path" if they may belong to $GIT_COMMON_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_COMMON_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_COMMON_DIR is a bit shorter and
hard coded in path.c:update_common_dir().

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

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

If $GIT_COMMON_DIR is set, it should be $GIT_COMMON_DIR/hooks/, not
$GIT_DIR/hooks/. Just let rev-parse --git-path handle it.
git-stash: avoid hardcoding $GIT_DIR/logs/....
setup.c: add multi-worktree support to is_git_directory()

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
setup.c: refactor path manipulation out of read_gitfile()
setup.c: add multi-worktree support to .git files

If a .git file contains

gitid: <id>
gitdir: <path>

then we set GIT_COMMON_DIR to <path> and GIT_DIR to
$GIT_COMMON_DIR/repos/<id>. This file is used to redirect to the real
repository from a linked worktree
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 multi-worktree .git file specified by $GIT_DIR
setup: support $GIT_COMMON_DIR as well as multi-worktree .git files

The same rules for git repo setup apply except:

- detect common .git files, set $GIT_COMMON_DIR accordingly

- if $GIT_COMMON_DIR is set (or specified by common .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_COMMON_DIR then GIT_WORK_TREE
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 main worktree is not in
"repos" and can't be seen this way. main worktree is mapped to
"main" 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 working directory linked to the
current one with the new .git file format. It then executes "git
checkout" again on the new worktree with the same arguments except
"--to" is taken out. The second checkout execution, which is not tamed
with any info from the current repository, will carry out normal
operations that 'checkout' does.

The end result is similar to "git stash" except that you don't have to
stash anything. Instead of switching to another branch temporarily
then back (and loses all timestamps), you can just create a separate
checkout, do your thing there then delete it.
checkout: clean up half-prepared directories in --to mode