threads / discuss / 39415

git status doesn't ignore GIT_DIR directory?

Subject: git status doesn't ignore GIT_DIR directory?

## tl;dr

10 messages between May 23, 2015 and May 23, 2015.

replies: 9people: 4as markdown or json

Thorsten von Eicken· May 23, 2015, 01:03 UTC · lore

I renamed my .git directory to _git and I'm surprised that git status thinks that it's an untracked file:

$ GIT_DIR=_git git status On branch master Your branch is up-to-date with 'origin/master'.

Untracked files:
   (use "git add <file>..." to include in what will be committed)
         _git/
nothing added to commit but untracked files present (use "git add" to track)

This doesn't seem to make sense, shouldn't git ignore whatever $GIT_DIR points to? Or is there some other magic option I need to use for it to do what I expect?

Junio C Hamano· May 23, 2015, 02:03 UTC · re: Thorsten von Eicken · lore

Re: git status doesn't ignore GIT_DIR directory?

As far as I know, GIT_DIR was prepared as a mechanism to point at another .git directory that does not live inside the working tree, not as a mechanism to rename it to arbitrary name. E.g.

 $ git init
 $ mv .git .svn
 $ GIT_DIR=$(pwd)/.svn ; export GIT_DIR
is not expected to work.
On Fri, May 22, 2015 at 6:03 PM, Thorsten von Eicken <tve@rightscale.com> wrote:
Show 21 quoted lines
> I renamed my .git directory to _git and I'm surprised that git status thinks
> that it's an untracked file:
>
> $ GIT_DIR=_git git status
> On branch master
> Your branch is up-to-date with 'origin/master'.
>
> Untracked files:
>   (use "git add <file>..." to include in what will be committed)
>
>         _git/
>
> nothing added to commit but untracked files present (use "git add" to track)
>
> This doesn't seem to make sense, shouldn't git ignore whatever $GIT_DIR
> points to? Or is there some other magic option I need to use for it to do
> what I expect?
> --
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
Duy Nguyen· May 23, 2015, 02:22 UTC · re: Junio C Hamano · lore

Re: git status doesn't ignore GIT_DIR directory?

On Fri, May 22, 2015 at 07:03:48PM -0700, Junio C Hamano wrote:
Show 9 quoted lines
> As far as I know, GIT_DIR was prepared as a mechanism to point at
> another .git directory that does not live inside the working tree, not
> as a mechanism to rename it to arbitrary name. E.g.
> 
>  $ git init
>  $ mv .git .svn
>  $ GIT_DIR=$(pwd)/.svn ; export GIT_DIR
> 
> is not expected to work.

This is not the first time we get this report. Perhaps we should document it.

-- 8< --
Subject: git.txt: mention the special name ".git" in GIT_DIR
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 90c5f37..91d6dd2 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -691,6 +691,9 @@ Git so take care if using Cogito etc.
 	specifies a path to use instead of the default `.git`
 	for the base of the repository.
 	The '--git-dir' command-line option also sets this value.
++
+Note that if GIT_DIR is set explicitly to a directory inside working
+tree, the directory name must be ".git".
 
 'GIT_WORK_TREE'::
 	Set the path to the root of the working tree.
-- 8< --
Thorsten von Eicken· May 23, 2015, 04:41 UTC · re: Duy Nguyen · lore

Re: git status doesn't ignore GIT_DIR directory?

On 5/22/2015 7:22 PM, Duy Nguyen wrote:
Show 14 quoted lines
> On Fri, May 22, 2015 at 07:03:48PM -0700, Junio C Hamano wrote:
>> As far as I know, GIT_DIR was prepared as a mechanism to point at
>> another .git directory that does not live inside the working tree, not
>> as a mechanism to rename it to arbitrary name. E.g.
>>
>>  $ git init
>>  $ mv .git .svn
>>  $ GIT_DIR=$(pwd)/.svn ; export GIT_DIR
>>
>> is not expected to work.
>
> ++
> +Note that if GIT_DIR is set explicitly to a directory inside working
> +tree, the directory name must be ".git".

This is not at all what I was hoping to hear, but thanks for the response. Thorsten

Duy Nguyen· May 23, 2015, 11:53 UTC · re: Thorsten von Eicken · lore

Re: git status doesn't ignore GIT_DIR directory?

On Sat, May 23, 2015 at 11:41 AM, Thorsten von Eicken <tve@rightscale.com> wrote:

Show 16 quoted lines
> On 5/22/2015 7:22 PM, Duy Nguyen wrote:
>> On Fri, May 22, 2015 at 07:03:48PM -0700, Junio C Hamano wrote:
>>> As far as I know, GIT_DIR was prepared as a mechanism to point at
>>> another .git directory that does not live inside the working tree, not
>>> as a mechanism to rename it to arbitrary name. E.g.
>>>
>>>  $ git init
>>>  $ mv .git .svn
>>>  $ GIT_DIR=$(pwd)/.svn ; export GIT_DIR
>>>
>>> is not expected to work.
>>
>> ++
>> +Note that if GIT_DIR is set explicitly to a directory inside working
>> +tree, the directory name must be ".git".
> This is not at all what I was hoping to hear, but thanks for the response.

To elaborate a bit more, I think ".git" was cooked in the code near the beginning and for too long. By the time people wanted flexibility, ".git" string was already all over the place and changing it may require some (and maybe big) code reorganization, and all that is for a rare use case.. I think I saw at least two attempts to fix this but they went nowhere. On the bright side, you can work around this easily by adding ".svn" to your ignore list.

-- 
Duy
Mike Hommey· May 23, 2015, 05:39 UTC · re: Duy Nguyen · lore

Re: git status doesn't ignore GIT_DIR directory?

On Sat, May 23, 2015 at 09:22:56AM +0700, Duy Nguyen wrote:
Show 30 quoted lines
> On Fri, May 22, 2015 at 07:03:48PM -0700, Junio C Hamano wrote:
> > As far as I know, GIT_DIR was prepared as a mechanism to point at
> > another .git directory that does not live inside the working tree, not
> > as a mechanism to rename it to arbitrary name. E.g.
> > 
> >  $ git init
> >  $ mv .git .svn
> >  $ GIT_DIR=$(pwd)/.svn ; export GIT_DIR
> > 
> > is not expected to work.
> 
> This is not the first time we get this report. Perhaps we should
> document it.
> 
> -- 8< --
> Subject: git.txt: mention the special name ".git" in GIT_DIR
> 
> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
> ---
> diff --git a/Documentation/git.txt b/Documentation/git.txt
> index 90c5f37..91d6dd2 100644
> --- a/Documentation/git.txt
> +++ b/Documentation/git.txt
> @@ -691,6 +691,9 @@ Git so take care if using Cogito etc.
>  	specifies a path to use instead of the default `.git`
>  	for the base of the repository.
>  	The '--git-dir' command-line option also sets this value.
> ++
> +Note that if GIT_DIR is set explicitly to a directory inside working
> +tree, the directory name must be ".git".

Isn't the requirement that it _ends_ with ".git" (that is, GIT_DIR=/path/to/foo.git would work)

Mike
Duy Nguyen· May 23, 2015, 11:42 UTC · re: Mike Hommey · lore

Re: git status doesn't ignore GIT_DIR directory?

On Sat, May 23, 2015 at 12:39 PM, Mike Hommey <mh@glandium.org> wrote:
Show 13 quoted lines
> On Sat, May 23, 2015 at 09:22:56AM +0700, Duy Nguyen wrote:
>> --- a/Documentation/git.txt
>> +++ b/Documentation/git.txt
>> @@ -691,6 +691,9 @@ Git so take care if using Cogito etc.
>>       specifies a path to use instead of the default `.git`
>>       for the base of the repository.
>>       The '--git-dir' command-line option also sets this value.
>> ++
>> +Note that if GIT_DIR is set explicitly to a directory inside working
>> +tree, the directory name must be ".git".
>
> Isn't the requirement that it _ends_ with ".git" (that is,
> GIT_DIR=/path/to/foo.git would work)

If $GIT_DIR points to somewhere inside worktree, ".git" exactly (it's strcmp(), not ends_with()) is the only exception. If it points outside worktree, the directory name could be anything.

-- 
Duy
Junio C Hamano· May 23, 2015, 16:54 UTC · re: Mike Hommey · lore

Re: git status doesn't ignore GIT_DIR directory?

Mike Hommey <mh@glandium.org> writes:
Show 18 quoted lines
> On Sat, May 23, 2015 at 09:22:56AM +0700, Duy Nguyen wrote:
>> On Fri, May 22, 2015 at 07:03:48PM -0700, Junio C Hamano wrote:
>> > As far as I know, GIT_DIR was prepared as a mechanism to point at
>> > another .git directory that does not live inside the working tree, not
>> > as a mechanism to rename it to arbitrary name. E.g.
>> > 
>> >  $ git init
>> >  $ mv .git .svn
>> >  $ GIT_DIR=$(pwd)/.svn ; export GIT_DIR
>> > 
>> > is not expected to work.
>> ...
>> ++
>> +Note that if GIT_DIR is set explicitly to a directory inside working
>> +tree, the directory name must be ".git".
>
> Isn't the requirement that it _ends_ with ".git" (that is,
> GIT_DIR=/path/to/foo.git would work)
I think both of you are wrong ;-)

The thing is, what you are seeing does not have much to do with GIT_DIR. It is "what Git does when it finds a directory inside the working tree of a project". And ".git" is the only special thing in that context.

When we find a directory whose name is ".git", whether it is the same as GIT_DIR or not (and "not" case includes when you do not have GIT_DIR defined), "git add" thinks "Ah, that is a repository proper, and I wouldn't add it to my project". It can do two things. (1) if it is not at the top of the working tree, i.e. some/directory/.git, then some/directory is a submodule of the project that has the working tree we are talking about (unless some/.git exists which makes some/directory/.git a submodule of the project that has some/ as its working tree, of course), so "git add" would treat some/directory as a thing to add. (2) if it is at the top of the working tree, it does not do anything to it, as it does not make sense to add the whole working tree as a separate submodule of ourselves.

The same for "git status". (1) is treated as a submodule and we do not consider individual files in some/directory/.git as untracked. (2) we do not cconsider individual files in .git as untracked.

GIT_DIR further comes into play when it is _not_ defined. In that case we try upwards to find a directory that has ".git" subdirectory and contains our $(cwd), and then declare it as our repository.

And when GIT_DIR points at somewhere that does not affect all of the above (i.e. trying to see if a random directory inside our working tree is a ".git" repository), it can be named anything. If you are working in /path/to/my/work/tree with GIT_DIR set, it can point at /path/to/my/repository_git (note that it does not end with ".git", and note also that it is outside our working tree) just fine.

If you move that directory to /path/to/my/worktree/repository_git, and point at it with GIT_DIR, we will notice that is our repository metadata, but "git add" and friends will see "repository_git" is different from ".git" and the special casing rules for directories inside working tree do not kick in.

Junio C Hamano· May 23, 2015, 17:00 UTC · re: Junio C Hamano · lore

Re: git status doesn't ignore GIT_DIR directory?

Junio C Hamano <gitster@pobox.com> writes:
Show 6 quoted lines
> I think both of you are wrong ;-)
>
> The thing is, what you are seeing does not have much to do with
> GIT_DIR.  It is "what Git does when it finds a directory inside the
> working tree of a project".  And ".git" is the only special thing in
> that context.

In short, I think Duy's "how about this" means well, but adds documentation at a wrong place.

Having said all that, the message I am responding to showed the right way to look at, understand, and explain the current behaviour. It is a separate issue if the current behaviour is optimal from the usability point of view. It is not entirely implausible to extend the special casing rules from "a directory named '.git' only" to "in addition, the directory pointed at by GIT_DIR, if exists, is treated the same way".

Junio C Hamano· May 23, 2015, 17:39 UTC · re: Junio C Hamano · lore

Re: git status doesn't ignore GIT_DIR directory?

Junio C Hamano <gitster@pobox.com> writes:
Show 19 quoted lines
> Junio C Hamano <gitster@pobox.com> writes:
>
>> I think both of you are wrong ;-)
>>
>> The thing is, what you are seeing does not have much to do with
>> GIT_DIR.  It is "what Git does when it finds a directory inside the
>> working tree of a project".  And ".git" is the only special thing in
>> that context.
>
> In short, I think Duy's "how about this" means well, but adds
> documentation at a wrong place.
>
> Having said all that, the message I am responding to showed the
> right way to look at, understand, and explain the current behaviour.
> It is a separate issue if the current behaviour is optimal from the
> usability point of view.  It is not entirely implausible to extend
> the special casing rules from "a directory named '.git' only" to "in
> addition, the directory pointed at by GIT_DIR, if exists, is treated
> the same way".

If somebody is interested in pursuing this further in the direction of changing the behaviour (so that Thorsten's original would work as expected), one thing to be careful about is the case (1) (case (2) is more or less straight-forward and obvious).

If you do
    $ GIT_DIR=/path/to/worktree/sub/repo.git
    $ GIT_WORK_TREE=/path/to/worktree
    $ export GIT_DIR GIT_WORK_TREE
    $ cd $GIT_WORK_TREE
    $ git add sub

with the current rule, because sub/repo.git does not trigger the special casing, we may end up adding everything inside our own repository, which is clearly crazy. But if you change the rule to special case the directory pointed at by $GIT_DIR, then we would start treating that directory as "ah, there is a Git repository". But the updated code must not say "hence, sub/ is the top level of the working tree of that repository, so we add it as a submodule".

It instead should just ignore that repo.git directory, just like a plain vanilla "git add ." ignores ".git" at the top-level, and add other things in sub/ directory, i.e. treating sub/ as just a normal subdirectory in our working tree.

I am not planning to do this in a near future myself, but I thought I should caution in case anybody is interested.

Thanks.

← back to recent threads