26

I have a particular need for git to treat most file extensions as binary except a few extensions.

I'd like to treat all file extensions as binary, .pdf .doc .xls etc., except plain text files such as .txt .rb .py etc.

I've tried configuring .gitattributes like below to see how this might work:

# cat .gitattributes 
* binary
*.txt text

I thought perhaps the order in the configuration file would matter but it doesn't appear to. With the above configuration all files are still treated as binary.

Is there a way to configure .gitattributes or git any other way to treat all files one way, as binary, except for a few exceptions?

Update 1:

I tried the .gitattributes described below. It works!

# cat .gitattributes 
*.txt crlf diff
* binary


# git diff
diff --git a/file b/file
index d929b94..bee5cb1 100644
Binary files a/file and b/file differ

diff --git a/file.txt b/file.txt
index 632ae98..93d22b0 100644
--- a/file.txt
+++ b/file.txt
@@ -1 +1,3 @@
 Hey this is a .txt file
+Adding another line
+A new line

Update 2:

I believe crlf and text are the same i.e. the two below configurations for .gitattributes are the same:

# cat .gitattributes 
*.txt crlf diff
* binary

# cat .gitattributes 
*.txt text diff
* binary
caleban
  • 749
  • 1
  • 10
  • 16

2 Answers2

28

binary is a macro setting the attribute crlf and diff (actually here unsetting them)
See "USING ATTRIBUTE MACROS" from the .gitattribute man page.

Once an attribute is set or unset, if cannot be changed by a subsequent rule.

So you could try:

* -text
*.txt crlf diff

That way, crlf and diff being set for *.txt files, they won't be unset by the binary macro for those same *.txt files, while they will be unset for all the other files.

For LF or auto:

*.txt text eol=lf
#
*.txt text=auto

From the 2009 commit b9d14ff, those rules should go:

  • from the more general ones
  • to the more specific ones.
    ("a later line overrides an earlier line")
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • 2
    "Once an attribute is set or unset, if cannot be changed by a subsequent rule." Very helpful information! Thanks. – caleban Nov 24 '10 at 20:23
  • 1
    @caleban: yes, the "EXAMPLE" section of the `gitattribute` man page (http://www.kernel.org/pub/software/scm/git/docs/gitattributes.html#_example) gives a good illustration of that rule. – VonC Nov 24 '10 at 20:32
  • That section was so foreign to me, abstract whatever, when I was looking at it initially I didn't get it. Now I get it. – caleban Nov 24 '10 at 20:54
  • 3
    @VonC The [manual](https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html) also says *"When more than one pattern matches the path, a later line overrides an earlier line. This overriding is done per attribute. The rules how the pattern matches paths are the same as in .gitignore files; see gitignore(5)"* in the middle of the `Description` section. This means the wildcard star should be first and overriding should be done after that. Star at top works but not the contrary, did I misunderstood your post? – Matt Sep 17 '13 at 13:13
  • It actually doesn't work, because * binary cannot be overrided with `*.txt text=auto`, you can check it yourself. But I've fixed replacing `binary` with `-text` – Alex Zhukovskiy Oct 18 '20 at 15:18
3

git has no concept of "binary" and "text" files. It's all defined as a set of attributes which designate how should we do merges, diffs, CR/LF conversions, handle whitespaces, apply filters and zillions of other things.

binary and syntax like

*.o binary
is actually macro-based, i.e. binary is a macro that expands to a whole lot of various attributes that designate merging, diffing, CR/LF handling, etc.

There is no text macro as far as I see. binary expands to -crlf -diff, so disabling binary and going back to text-style processing seems to be crlf diff.

GreyCat
  • 16,622
  • 18
  • 74
  • 112
  • 1
    There's definitely a text macro defined now: http://git-scm.com/docs/gitattributes#_using_attribute_macros – skolima Oct 14 '13 at 16:52