简体   繁体   中英

Does git takes into account my .gitattributes for *.vbs text eol=crlf?

I'm currently working on VBScript (*.vbs) files, meant to be run on Windows only.

I want them to be checkout with CRLF disregarding of how developers have set their core.autocrlf . BTW, mine seems set to false when running git config --get core.autocrlf

So I created a .gitattributes file with this:

*.vbs text eol=crlf

Commited both the files (with their CRLF EOL's) and this .gitattributes one.

But now I've done some changes to a file, without changing the EOL's, when I want to see a diff eg in gitk I have to check Ignore space change to properly see the line differences, otherwise the whole file is considered to have changed.

What did I do wrong?

Note: especially here on SO and other forums, I read people saying to use eg *.vbs binary to avoid Git from altering EOL's - in the same way it's advised to do so on *.jpg files in the Git online doc - however binary means -text -diff and I don't want to (un)set -diff because I want to have diffs!!

If you tell Git not to muck about with your files, you must live with the fact that some files have been permanently stored with LF-only line endings and others have been permanently stored with CRLF line endings.

If you tell Git to mess with your files, it will do that not only while extracting ( git checkout ) or adding ( git add ) files to be saved in their permanent format, but also while extracting files for diff purposes.

That's part of what you must choose now, because it's clear that you have existing committed copies that have LF-ony line endings.

How this all works

The declaration:

<pattern> text eol=crlf

is, in effect, a command to Git that tells it:

  • When you take a file out of the freeze-dried format (as stored in the repository and in the index / staging-area, to put it into the work-tree where you can see it and use it), change any newline-only end-of-lines into CRLF end-of-lines.

  • When you freeze-dry a file, ie, store a work-tree file into the index so that it will go into the next commit, and it has CRLF line endings, change them to newline-only line-endings.

In other words, you're telling Git: Please muck about with my files. The eol=... part tells it how to muck with the files. The pattern part of the line tells Git which files, and the text directive tells Git: These are text files, so they show up OK on my screen in diffs, and you should mess with them.

If you use binary as an attribute, you're telling Git: These are binary files, so they don't show up OK on my screen in diffs, and you should not mess with them at all.

As phd noted in a comment , you can use -text to say do not mess with them without also saying they cannot be displayed . But saying do not mess with them means do not mess with them , and that includes when extracting the dehydrated contents in order to make diffs.

All of Git's messing with files occurs during either the rehydrating phase, when a freeze-dried file is turned back into a usable one, or the freeze-drying phase, when a regular file is turned into one that can be stored inside Git. Furthermore, all of Git's built-in modification processes for text files store them inside Git with LF-only line endings. If these *.vbs files must have CRLFs inside them while stored inside Git, 1 they must not be modified on the way in, and therefore you cannot use any of Git's built-in modification options.

If the files may (are permitted to) have LF-only line endings while stored inside Git, you can use the built-in modifications. If they must have CRLF line endings when in your work-tree (or any form in which you can see and work with them), and existing committed copies stored inside Git already have LF-only line endings, then you must choose to have Git make changes to the files on their way in and out of the freeze-dried formats, because no existing freeze-dried file stored inside Git now can ever be changed. 2

If you can live with existing freeze-dried copies that don't have CRLF line endings, staying that way when they come back out, while new files get stored inside Git with their CRLF line endings and keep their CRLF line endings during the copies in and out, you can use -text (or use nothing at all 3 ) and just not have Git mess with them.


1 It's not clear to me why this would ever be required, since only Git can read Git's freeze-dried stored files. I put it this way because it's easier to think about it this way, and then move from "it absolutely must be done this way" to "I would prefer to do it this way" as you relax your constraints.

2 You do, of course, have the option of taking some existing repository and transforming it into a new and different repository, with new and different commits, that have the files in some other form. You can do this over an entire repository, using git filter-branch ... --all , or some subset of a repository. The upside of doing this is that you end up with a "clean" repository, as if you had, long ago, been following whatever practice you establish now. The downside is that you must get everyone who has a clone of the original repository to switch to using the replacement commits you come up with today.

3 The original concept for Git was that it was to preserve, forever, all files exactly as they appeared in the index at commit time. That concept remains, but the introduction of these modifications—of "smudging" files as they come out of the index into the work-tree, then "cleaning" them as they go back in for the next commit—enables Windows users, who demand CRLF line endings, to get along with Linux users, who demand LF-only line endings. But it also introduces this clumsy situation in which Git must now know which files should get messed-with—which ones are "text"—and which files should not, because they're "binary". Eliminate the mucking-about with your data, and you eliminate the need to describe which files get which treatment.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM