All of lore.kernel.org
 help / color / mirror / Atom feed
* Git attributes ignored for root directory
@ 2011-10-04 18:52 Gioele Barabucci
  2011-10-05 12:05 ` Michael Haggerty
  0 siblings, 1 reply; 13+ messages in thread
From: Gioele Barabucci @ 2011-10-04 18:52 UTC (permalink / raw)
  To: git

Hello,

I just updated to git v1.7.7 using the Ubuntu Lucid PPA and I found that 
`git check-attr` is broken now.

I have this attribute in my `$HOME/.gitattributes` file:

     /. show_in_prompt=no

Now, if I go to `$HOME` and run

     git check-attr show_in_prompt -- .

With git v1.7.6 this is the answer I got:

     .: show_in_prompt: no

With the newer v1.7.7 I get this, instead:

     .: show_in_prompt: unspecified

Also, if I use the `--all` option, `check-attr` does not show any 
attribute at all.

I see in the release notes of 1.7.7-rc1 that `check-attr` has been 
changed to allow relative paths to be specified. Maybe this error is 
related to that change.

Best,

-- 
Gioele Barabucci <gioele@svario.it>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Git attributes ignored for root directory
  2011-10-04 18:52 Git attributes ignored for root directory Gioele Barabucci
@ 2011-10-05 12:05 ` Michael Haggerty
  2011-10-05 14:47   ` Gioele Barabucci
  2011-10-05 17:38   ` Junio C Hamano
  0 siblings, 2 replies; 13+ messages in thread
From: Michael Haggerty @ 2011-10-05 12:05 UTC (permalink / raw)
  To: Gioele Barabucci; +Cc: git

On 10/04/2011 08:52 PM, Gioele Barabucci wrote:
> I just updated to git v1.7.7 using the Ubuntu Lucid PPA and I found that
> `git check-attr` is broken now.
> 
> I have this attribute in my `$HOME/.gitattributes` file:
> 
>     /. show_in_prompt=no
> 
> Now, if I go to `$HOME` and run
> 
>     git check-attr show_in_prompt -- .
> 
> With git v1.7.6 this is the answer I got:
> 
>     .: show_in_prompt: no
> 
> With the newer v1.7.7 I get this, instead:
> 
>     .: show_in_prompt: unspecified
> 
> Also, if I use the `--all` option, `check-attr` does not show any
> attribute at all.
> 
> I see in the release notes of 1.7.7-rc1 that `check-attr` has been
> changed to allow relative paths to be specified. Maybe this error is
> related to that change.

Indeed, your use case is broken by

f5114a40c0d0276ce6ff215a3dc51eb19da5b420

In fact the support for gitattributes using patterns involving "." was
pretty spotty in v1.7.6 too.  For example,

-------------------------------------------
echo ". foo" >./.gitattributes
git check-attr foo -- . ./ ./. x x/ ./x x/.
.: foo: set
./: foo: unspecified      WRONG
./.: foo: set
x: foo: unspecified       WRONG?
x/: foo: unspecified      WRONG?
./x: foo: unspecified     WRONG?
x/.: foo: set             RIGHT?

-------------------------------------------
echo "/. foo" >./.gitattributes
git check-attr foo -- . ./ ./. x x/ ./x x/.
.: foo: set
./: foo: unspecified      WRONG
./.: foo: set
x: foo: unspecified
x/: foo: unspecified
./x: foo: unspecified
x/.: foo: unspecified

-------------------------------------------
echo ". foo" >x/.gitattributes
git check-attr foo -- . ./ ./. x x/ ./x x/.
.: foo: unspecified
./: foo: unspecified
./.: foo: unspecified
x: foo: unspecified       WRONG?
x/: foo: unspecified      WRONG?
./x: foo: unspecified     WRONG?
x/.: foo: set             RIGHT?

-------------------------------------------
echo "/. foo" >x/.gitattributes
git check-attr foo -- . ./ ./. x x/ ./x x/.
.: foo: unspecified
./: foo: unspecified
./.: foo: unspecified
x: foo: unspecified       WRONG
x/: foo: unspecified      WRONG
./x: foo: unspecified     WRONG
x/.: foo: set

-------------------------------------------

I conclude that this functionality was never really defined correctly,
and you were pretty lucky that your case worked at all :-)

It's not to hard to fix your particular use case.  But for a real fix,
we would need to decide what is the correct behavior in all of the lines
above marked "?"; specifically, should "." match every subdirectory
under a given directory, does it match only the directory containing the
.gitattributes file, or is this construct illegal?

Michael

-- 
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Git attributes ignored for root directory
  2011-10-05 12:05 ` Michael Haggerty
@ 2011-10-05 14:47   ` Gioele Barabucci
  2011-10-05 17:38   ` Junio C Hamano
  1 sibling, 0 replies; 13+ messages in thread
From: Gioele Barabucci @ 2011-10-05 14:47 UTC (permalink / raw)
  To: Michael Haggerty; +Cc: git

On 05/10/2011 14:05, Michael Haggerty wrote:
> On 10/04/2011 08:52 PM, Gioele Barabucci wrote:
>> With the newer v1.7.7 I get this, instead:
>>
>>      .: show_in_prompt: unspecified
>>
>> I see in the release notes of 1.7.7-rc1 that `check-attr` has been
>> changed to allow relative paths to be specified. Maybe this error is
>> related to that change.
>
> Indeed, your use case is broken by
>
> f5114a40c0d0276ce6ff215a3dc51eb19da5b420

Wow, debug-by-changelog :)

> In fact the support for gitattributes using patterns involving "." was
> pretty spotty in v1.7.6 too.  For example,

[...]

> It's not to hard to fix your particular use case.  But for a real fix,
> we would need to decide what is the correct behavior in all of the lines
> above marked "?"; specifically, should "." match every subdirectory
> under a given directory, does it match only the directory containing the
> .gitattributes file, or is this construct illegal?

I do not know what the correct behavior should be, but here is my use case.

I use git to version almost all my $HOME dir. In addition to my usual 
files there are also separate project repositories under $HOME. I enjoy 
using a git-enabled prompt in those projects' dirs but not in my $HOME dir.

So I have this code somewhere in my `~/.bashrc`:

     local show_status="$(git check-attr show_in_prompt -- .)"
     local show_pattern='^\.: show_in_prompt: (.*)$'

     # add the following line to .gitattributes
     #
     #     /. show_in_prompt=no
     local show_in_prompt='yes'
     if [[ ${show_status} =~ ${show_pattern} ]]; then
            show_in_prompt="${BASH_REMATCH[1]}"
     fi

     if [ "${show_in_prompt}" == 'no' ]; then
             return
     fi

As you see in my the line of this code, I exploit the fact that "." 
refers to the root git dir, not to the current dir, to simplify the 
code. Otherwise I would had to discover what is the path of the current 
dir relative to its root git dir, something that I'd like to avoid as 
this code runs every time the prompt is shown.

This is just my personal use case. On the other hand, the first time I 
looked at check-attr I found it strange that paths were meant as 
relative to the root git dir ("." in "/foo" = "/") and not expanded from 
the current dir ("." in "/foo" = "/foo").

Bye,

-- 
Gioele Barabucci <gioele@svario.it>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Git attributes ignored for root directory
  2011-10-05 12:05 ` Michael Haggerty
  2011-10-05 14:47   ` Gioele Barabucci
@ 2011-10-05 17:38   ` Junio C Hamano
  2011-10-05 17:56     ` Gioele Barabucci
  2011-10-12 22:35     ` Michael Haggerty
  1 sibling, 2 replies; 13+ messages in thread
From: Junio C Hamano @ 2011-10-05 17:38 UTC (permalink / raw)
  To: Michael Haggerty; +Cc: Gioele Barabucci, git

Michael Haggerty <mhagger@alum.mit.edu> writes:

> Indeed, your use case is broken by
>
> f5114a40c0d0276ce6ff215a3dc51eb19da5b420
>
> In fact the support for gitattributes using patterns involving "." was
> pretty spotty in v1.7.6 too.  For example,
> ...
> I conclude that this functionality was never really defined correctly,
> and you were pretty lucky that your case worked at all :-)

The attribute patterns (or exclude patterns for that matter) were never
designed to name "the current directory". The way to name "everything *in*
this directory" has always been to say "*" (the "* text=auto" example in
the documentation says it shows how to set the attribute "for all
files"). Admittedly the pattern may miss ".*" files.

I have to agree that things like "./" and "."  were outside the scope of
the design; in some cases undefined behaviour given to such patterns may
have made sense but that was mere accident.

If we were to give some defined behaviour to these patterns, updating the
"Pattern Format" section of Documentation/gitignore.txt is the first thing
to do. The text currently reads like this:

PATTERN FORMAT
--------------

 - A blank line matches no files, so it can serve as a separator
   for readability.

 - A line starting with # serves as a comment.

 - An optional prefix '!' which negates the pattern; any
   matching file excluded by a previous pattern will become
   included again.  If a negated pattern matches, this will
   override lower precedence patterns sources.

 - If the pattern ends with a slash, it is removed for the
   purpose of the following description, but it would only find
   a match with a directory.  In other words, `foo/` will match a
   directory `foo` and paths underneath it, but will not match a
   regular file or a symbolic link `foo` (this is consistent
   with the way how pathspec works in general in git).

 - If the pattern does not contain a slash '/', git treats it as
   a shell glob pattern and checks for a match against the
   pathname relative to the location of the `.gitignore` file
   (relative to the toplevel of the work tree if not from a
   `.gitignore` file).

 - Otherwise, git treats the pattern as a shell glob suitable
   for consumption by fnmatch(3) with the FNM_PATHNAME flag:
   wildcards in the pattern will not match a / in the pathname.
   For example, "Documentation/{asterisk}.html" matches
   "Documentation/git.html" but not "Documentation/ppc/ppc.html"
   or "tools/perf/Documentation/perf.html".

 - A leading slash matches the beginning of the pathname.
   For example, "/{asterisk}.c" matches "cat-file.c" but not
   "mozilla-sha1/sha1.c".

I think adding the following before the 5th rule ("If the pattern does not
contain a slash") would be sufficient:

 - If the pattern is a single dot and nothing else, it matches everything
   in the current directory.

So "./" in .gitignore or .gitattributes at the toplevel would match all
the top-level directories and files but does not apply to the paths
contained in the matched directories. "." in .gitignore or .gitattributes
at the toplevel would match everything under the sun.

Personally I do not think it is an improvement. You can certainly say "we
have one less undefined case and are more consistent", but the downside of
that consistency is that it is very confusing and error prone for the end
users. Would it be sensible to assume that users would not be surprised if
". text=auto" meant that the attribute applies to every file in the
worktree?

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Git attributes ignored for root directory
  2011-10-05 17:38   ` Junio C Hamano
@ 2011-10-05 17:56     ` Gioele Barabucci
  2011-10-05 18:35       ` Junio C Hamano
  2011-10-12 22:35     ` Michael Haggerty
  1 sibling, 1 reply; 13+ messages in thread
From: Gioele Barabucci @ 2011-10-05 17:56 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Michael Haggerty, git

On 05/10/2011 19:38, Junio C Hamano wrote:
>> In fact the support for gitattributes using patterns involving "." was
>> pretty spotty in v1.7.6 too.  For example,
>
> The attribute patterns (or exclude patterns for that matter) were never
> designed to name "the current directory". The way to name "everything *in*
> this directory" has always been to say "*" (the "* text=auto" example in
> the documentation says it shows how to set the attribute "for all
> files"). Admittedly the pattern may miss ".*" files.

What if I do not want to say things about the "content" of the directory 
but about the directory itself? This is exactly my case.


> I have to agree that things like "./" and "."  were outside the scope of
> the design; in some cases undefined behaviour given to such patterns may
> have made sense but that was mere accident.

Actually what I have in my `~/.gitattributes` is

     /. show_in_prompt=no

Anyway, I see a conflict between

>   - A leading slash matches the beginning of the pathname.
>     For example, "/{asterisk}.c" matches "cat-file.c" but not
>     "mozilla-sha1/sha1.c".

and

>   - If the pattern is a single dot and nothing else, it matches everything
>     in the current directory.

in the first case `.` is treated as a "glob dot", while in the second 
case it is treated as a "regexp dot". I would find this confusing.

Patterns can match directories using `/foo`. Why don't you just say that 
`.` is equivalent to `./` and `/foo/.` is equivalent to `/foo`?


> So "./" in .gitignore or .gitattributes at the toplevel would match all
> the top-level directories and files but does not apply to the paths
> contained in the matched directories. "." in .gitignore or .gitattributes
> at the toplevel would match everything under the sun.

In the case of `.gitignore`, `/foo/.` and `/foo/` would have the same 
effect and they look sane to me.


> Would it be sensible to assume that users would not be surprised if
> ". text=auto" meant that the attribute applies to every file in the
> worktree?

I would be surprised as I expect `.` to be a "glob dot". But maybe it is 
just me and my prejudices :)

Bye,

-- 
Gioele Barabucci <gioele@svario.it>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Git attributes ignored for root directory
  2011-10-05 17:56     ` Gioele Barabucci
@ 2011-10-05 18:35       ` Junio C Hamano
  2011-10-05 20:17         ` Gioele Barabucci
  0 siblings, 1 reply; 13+ messages in thread
From: Junio C Hamano @ 2011-10-05 18:35 UTC (permalink / raw)
  To: Gioele Barabucci; +Cc: Michael Haggerty, git

Gioele Barabucci <gioele@svario.it> writes:

> On 05/10/2011 19:38, Junio C Hamano wrote:
>>> In fact the support for gitattributes using patterns involving "." was
>>> pretty spotty in v1.7.6 too.  For example,
>>
>> The attribute patterns (or exclude patterns for that matter) were never
>> designed to name "the current directory". The way to name "everything *in*
>> this directory" has always been to say "*" (the "* text=auto" example in
>> the documentation says it shows how to set the attribute "for all
>> files"). Admittedly the pattern may miss ".*" files.
>
> What if I do not want to say things about the "content" of the
> directory but about the directory itself? This is exactly my case.

Oh, that is totally different. We do not store directories, and they do
not have attributes, period.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Git attributes ignored for root directory
  2011-10-05 18:35       ` Junio C Hamano
@ 2011-10-05 20:17         ` Gioele Barabucci
  2011-10-05 20:25           ` Junio C Hamano
  0 siblings, 1 reply; 13+ messages in thread
From: Gioele Barabucci @ 2011-10-05 20:17 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Michael Haggerty, git

On 05/10/2011 20:35, Junio C Hamano wrote:
>> What if I do not want to say things about the "content" of the
>> directory but about the directory itself? This is exactly my case.
>
> Oh, that is totally different. We do not store directories, and they do
> not have attributes, period.

While that is true (yet many beg git to natively support empty dirs…), 
`.gitignore` does deal with directories. As you quoted,

 > If the pattern ends with a slash, it is removed for the purpose
 > of the following description, but it would only find a match with
 > a directory. In other words, foo/ will match a directory foo and
 > paths underneath it

Isn't applying the same logic to `.gitattributes` be the most 
straightforward solution? Also code-wise, I suppose.

Bye,

-- 
Gioele Barabucci <gioele@svario.it>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Git attributes ignored for root directory
  2011-10-05 20:17         ` Gioele Barabucci
@ 2011-10-05 20:25           ` Junio C Hamano
  0 siblings, 0 replies; 13+ messages in thread
From: Junio C Hamano @ 2011-10-05 20:25 UTC (permalink / raw)
  To: Gioele Barabucci; +Cc: Michael Haggerty, git

Gioele Barabucci <gioele@svario.it> writes:

> ...  As you quoted,
>
>> If the pattern ends with a slash, it is removed for the purpose
>> of the following description, but it would only find a match with
>> a directory. In other words, foo/ will match a directory foo and
>> paths underneath it

But the "will match a directory foo and" part in that description, while
makes it easier to read, is technically unnecessary and even misleading.

The ignore patterns ultimately decides which paths are not to be added to
the index. Colloquially we could say "foo directory is ignored", but such
a statement is just a short-hand for "everything in foo is ignored";
technically "foo directory is ignored" is not necessary because we never
add the directory itself to the index.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Git attributes ignored for root directory
  2011-10-05 17:38   ` Junio C Hamano
  2011-10-05 17:56     ` Gioele Barabucci
@ 2011-10-12 22:35     ` Michael Haggerty
  2011-10-12 23:12       ` Junio C Hamano
  1 sibling, 1 reply; 13+ messages in thread
From: Michael Haggerty @ 2011-10-12 22:35 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Gioele Barabucci, git

On 10/05/2011 07:38 PM, Junio C Hamano wrote:
>  - If the pattern is a single dot and nothing else, it matches everything
>    in the current directory.

This disagrees with shell usage, where "." represents a directory
itself, not the files within a directory.  By the trailing slash rule
that you quoted, "./" should also represent the containing directory.

Given that git currently tries to ignore directories and only think
about files, the consistent thing to do would be to declare "." and "./"
as undefined.  Because someday git *may* want to get a bit smarter about
directories, and at that time it would be a shame not to have "." and/or
"./" available to represent the containing directory.  (But implementing
it will require some special-casing within the attr module, which is
currently pretty stupid.)

Michael

-- 
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Git attributes ignored for root directory
  2011-10-12 22:35     ` Michael Haggerty
@ 2011-10-12 23:12       ` Junio C Hamano
  2011-10-13 10:49         ` Gioele Barabucci
  0 siblings, 1 reply; 13+ messages in thread
From: Junio C Hamano @ 2011-10-12 23:12 UTC (permalink / raw)
  To: Michael Haggerty; +Cc: Gioele Barabucci, git

Michael Haggerty <mhagger@alum.mit.edu> writes:

> On 10/05/2011 07:38 PM, Junio C Hamano wrote:
>>  - If the pattern is a single dot and nothing else, it matches everything
>>    in the current directory.
>
> This disagrees with shell usage, where "." represents a directory
> itself, not the files within a directory.

Either you misread me, or what I wrote was fuzzy, or perhaps both.

The suggested update to the list of rules very much wants a '.' to mean
the directory itself.  The problem I was solving, which turned out to be
something different from the original issue in the thread was this.

Suppose you have a directory "foo" and want to say "I want to ignore
everything in that directory". You would say "foo/" in .gitignore in the
higher level and you are happy.

How would you say the same thing if the directory to be ignored weren't
"foo" but at the top-level of the working tree? There is no such level
higher than the top-level where you can say "<the name of your project>/"
in its .gitignore file.

The best you could do is to say "./" in the .gitignore file at the
top-level directory, and the update rule you quoted is specifically
designed to address it.

Of course, you could list both ".*" and "*" in the .gitignore file at the
top-level directory for the same effect, but that works only because you
do not have to give values to the entry in .gitignore mechanism. It would
be cumbersome to duplicate two entries in .gitattributes file like that as
a workaround.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Git attributes ignored for root directory
  2011-10-12 23:12       ` Junio C Hamano
@ 2011-10-13 10:49         ` Gioele Barabucci
  2011-10-13 13:16           ` Johannes Sixt
  2011-10-13 17:38           ` Junio C Hamano
  0 siblings, 2 replies; 13+ messages in thread
From: Gioele Barabucci @ 2011-10-13 10:49 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Michael Haggerty, git

On 13/10/2011 00:12, Junio C Hamano wrote:
> Suppose you have a directory "foo" and want to say "I want to ignore
> everything in that directory". You would say "foo/" in .gitignore in the
> higher level and you are happy.
>
> How would you say the same thing if the directory to be ignored weren't
> "foo" but at the top-level of the working tree? There is no such level
> higher than the top-level where you can say "<the name of your project>/"
> in its .gitignore file.

Shouldn't `/.` or `/./` work?

I see that `/*/` in `.gitignores` successfully ignores all the 
non-hidden directories in the root project directory. Another accidental 
success? :)

-- 
Gioele Barabucci <gioele@svario.it>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Git attributes ignored for root directory
  2011-10-13 10:49         ` Gioele Barabucci
@ 2011-10-13 13:16           ` Johannes Sixt
  2011-10-13 17:38           ` Junio C Hamano
  1 sibling, 0 replies; 13+ messages in thread
From: Johannes Sixt @ 2011-10-13 13:16 UTC (permalink / raw)
  To: Gioele Barabucci; +Cc: Junio C Hamano, Michael Haggerty, git

Am 10/13/2011 12:49, schrieb Gioele Barabucci:
> I see that `/*/` in `.gitignores` successfully ignores all the non-hidden
> directories in the root project directory. Another accidental success? :)

No, that's by design. The first slash means "apply only in this directory,
not any subdirectories", and the slash at the end means "match only if the
name is a directory".

-- Hannes

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Git attributes ignored for root directory
  2011-10-13 10:49         ` Gioele Barabucci
  2011-10-13 13:16           ` Johannes Sixt
@ 2011-10-13 17:38           ` Junio C Hamano
  1 sibling, 0 replies; 13+ messages in thread
From: Junio C Hamano @ 2011-10-13 17:38 UTC (permalink / raw)
  To: Gioele Barabucci; +Cc: Michael Haggerty, git

Gioele Barabucci <gioele@svario.it> writes:

> On 13/10/2011 00:12, Junio C Hamano wrote:
> ...
>> How would you say the same thing if the directory to be ignored weren't
>> "foo" but at the top-level of the working tree? There is no such level
>> higher than the top-level where you can say "<the name of your project>/"
>> in its .gitignore file.
>
> Shouldn't `/.` or `/./` work?
>
> I see that `/*/` in `.gitignores` successfully ignores all the
> non-hidden directories in the root project directory. Another
> accidental success? :)

Hannes correctly explained how /*/ works already; armed with that
knowledge, we can understand that:

        /.      would mean "what matches dot only in this directory."

        /./     would mean "what matches dot only in this directory
                but the thing that matches must be a directory."

        ./      would mean "what matches dot in this directory and its
                subdirectories, but the thing that matches must be a
                directory."

Given that "." does _not_ match the directory that has the .gitignore or
the .gitattribute file with the current system, none of the above patterns
can be used to match everything in the top level directory in a way
similar to how you can say "foo/" to match everything in "foo" directory
from the top-level directory.

The answer to your question is no, it shouldn't work.

Without adding a rule to the "Pattern Format" section as I suggested in my
message that Michael quoted in his question, that is.

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2011-10-13 17:38 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-10-04 18:52 Git attributes ignored for root directory Gioele Barabucci
2011-10-05 12:05 ` Michael Haggerty
2011-10-05 14:47   ` Gioele Barabucci
2011-10-05 17:38   ` Junio C Hamano
2011-10-05 17:56     ` Gioele Barabucci
2011-10-05 18:35       ` Junio C Hamano
2011-10-05 20:17         ` Gioele Barabucci
2011-10-05 20:25           ` Junio C Hamano
2011-10-12 22:35     ` Michael Haggerty
2011-10-12 23:12       ` Junio C Hamano
2011-10-13 10:49         ` Gioele Barabucci
2011-10-13 13:16           ` Johannes Sixt
2011-10-13 17:38           ` Junio C Hamano

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.