Re: git's fascination with absolute paths
- From
Junio C Hamano <gitster@pobox.com>
- Date
- Dec 22, 2009, 06:30 UTC
- Message-ID
- <7vy6kv4j2u.fsf@alter.siamese.dyndns.org>
- In-Reply-To
- <7v637z6ehg.fsf@alter.siamese.dyndns.org>
Junio C Hamano <gitster@pobox.com> writes:
Show 45 quoted lines
> Not really. The scripts can work with ".." just fine, as long as they
> know how to use "cd_to_topdir" and "rev-parse --show-prefix" correctly.
>
> While I do not necessarily agree with the original claim that hiding
> higher level of hierarchies are "standard" practice in UNIX (it instead
> falls into "an unusual set-up that is permitted but you have to be
> careful" category), I don't think it is fundamental that we need read
> access all the way up to the root level. It is only that getcwd(3) does.
>
> At the basic level, work tree and index operations operate relative to the root
> of the work tree. Originally, almost no privision was made to run from a
> subdirectory of a work tree (you were expected to run from the top-level,
> having ./.git as the meta information sture), and we didn't have to run
> any getcwd(3). Later we added "look at parent directories until we find
> the one that has .git subdirectory, while remembering how many levels we
> went up", in order to support operations from a subdirectory of a work
> tree. The commands chdir up to the root of the work tree and would use
> the path they climbed as a pathspec to limit the scope of their operation.
>
> While "counting how many levels we went up" can be expressed by a sequence
> of "../", turning it to the directory prefix means at some point you would
> need to do what getcwd(3) does. It wants to be able to read ".." to give
> you an absolute path.
>
> By rewriting that part of the "root-level-discovery" code to do something
> like
>
> - while test -d .git is not true:
> - stat(".") to get the inum;
> - chdir(".."); and
> - opendir(".") and readdir() to find where we were;
>
> while going up every level, you should be able to construct the prefix
> without being to able to read all the way up to the filesystem root. You
> only need to be able to read your work tree.
>
> Admittedly the code complexity got worse later when we added support for
> GIT_WORK_TREE and also GIT_CEILING_DIRECTORIES, as they fundamentally need
> to know where you are relative to the root of the filesystem tree and need
> a working getcwd(3) support, which J Chapman's set-up refuses to give.
>
> Also I wouldn't be surprised if the support for these two features cheat
> in order to reduce code complexity by always using absolute paths even in
> places where a path relative to the root of the work tree might have
> sufficed.Clarificaiton.
The above, like many other messages from me, was not meant as a justification, but a mere explanation of the historical fact. IOW, don't get me wrong by interpreting that I am not interested in seeing a solution that does not use absolute paths.
While I think the original "higher levels in the filesystems may not be accessible" is a rather unusual set-up, making paths absolute and relying on being able to always do so have another drawback in a not-so-unusual setup. A work tree that is shallow (say, has only one t/ subdirectory and short filenames) may not be usable if it is so deep in the filesystem hierarchy that the result of getcwd(3) exceeds PATH_MAX. The "hand roll what getcwd(3) did in traditional UNIX while looking for the root level of the work tree" approach I outlined in the previous message will be a way to fix such a use case; as long as the deepest level of your work tree relative to the root of the work tree does not exceed PATH_MAX, you'll be Ok.
We have a few known issues in the GIT_WORK_TREE (IIRC, it has a funny interaction with alias expansion). When we reexamine the codepath that the introduction of the feature needed to touch, I would love to see us at least try to see if it is feasible to redo this without calling getcwd(3) when no GIT_WORK_TREE (or core.worktree) is set.