Subject: Re: [PATCH 22/32] checkout: support checking out into a new working directory

From: Marc Branchaud <[email-masked]>
Date: Tue, 02 Sep 2014 10:51:47 -0400

On 14-09-02 08:27 AM, Duy Nguyen wrote:
> After reading this "multiple checkout mode" in git-checkout.txt, I'm
> tempted to rewrite it like this. I think the example makes it clearer
> what I mean. If nobody has any comments, I'm going to send v2 with
> this (and other comments collected so far)

Overall I think focusing on the word "checkout" for this feature makes the
documentation confusing.  It's also not a "mode" but just another git
feature.  Since this is all about multiple working directories (the phrase is
actually "working tree" in the existing docs) we should just stick to that
rather than introduce new terminology.

Finally, a bit of bikeshedding, but I think "$GIT_DIR/repos" is also an
unfortunate choice and that "$GIT_DIR/worktrees" would be better.

So I suggest the following for the new section:

MULTIPLE WORKING TREES
----------------------

A git repository can support multiple working trees, allowing you to check
out more than one branch at a time.  With `git checkout --to` a new working
tree is associated with the repository.  This new working tree is called a
"linked working tree" as opposed to the "main working tree" prepared by "git
init" or "git clone".  A repository has one main working tree (if it's not a
bare repository) and zero or more linked working trees.

Each linked working tree has a private sub-directory in the repository's
$GIT_DIR/worktrees directory.  The private sub-directory's name is usually
the base name of the linked working tree's path, possibly appended with a
number to make it unique.  For example, when `$GIT_DIR=/path/main/.git` the
command `git checkout --to /path/other/test-next next` creates the linked
working tree in `/path/other/test-next` and also creates a
`$GIT_DIR/worktrees/test-next` directory (or `$GIT_DIR/worktrees/test-next1`
if `test-next` is already taken).

Within a linked working tree, $GIT_DIR is set to point to this private
directory (e.g. `/path/main/.git/worktrees/test-next` in the example) and
$GIT_COMMON_DIR is set to point back to the main working tree's $GIT_DIR
(e.g. `/path/main/.git`). These settings are made in a `.git` file located at
the top directory of the linked working tree.

Path resolution via `git rev-parse --git-path` uses either
$GIT_DIR or $GIT_COMMON_DIR depending on the path. For example, in the
linked working tree `git rev-parse --git-path HEAD` returns
`/path/main/.git/worktrees/test-next/HEAD` (not
`/path/other/test-next/.git/HEAD` or `/path/main/.git/HEAD`) while `git
rev-parse --git-path refs/heads/master` uses
$GIT_COMMON_DIR and returns `/path/main/.git/refs/heads/master`,
since refs are shared across all working trees.

See linkgit:gitrepository-layout[5] for more information. The rule of
thumb is do not make any assumption about whether a path belongs to
$GIT_DIR or $GIT_COMMON_DIR when you need to directly access something
inside $GIT_DIR. Use `git rev-parse --git-path` to get the final path.

		M.