In the same vein as #917492: Add a sensible .gitignore file, we should also provide a .gitattributes
.
In particular, we could specify the file type for certain extensions (like *.module is a PHP file) so that the hunk headers are more useful. From http://www.kernel.org/pub/software/scm/git/docs/gitattributes.html
diff
The attribute diff affects how git generates diffs for particular files. It can tell git whether to generate a textual patch for the path or to treat the path as a binary file. It can also affect what line is shown on the hunk header @@ -k,l +n,m @@ line, tell git to use an external command to generate the diff, or ask git to convert binary files to a text format before generating the diff.
So the .gitattributes
file could be something like
*.engine diff=php
*.inc diff=php
*.install diff=php
*.module diff=php
...
Later additions could deal with attribute substitution on export:
export-subst
If the attribute export-subst is set for a file then git will expand several placeholders when adding this file to an archive. The expansion depends on the availability of a commit ID, i.e., if git-archive(1) has been given a tree instead of a commit or a tag then no replacement will be done. The placeholders are the same as those for the option --pretty=format: of git-log(1), except that they need to be wrapped like this: $Format:PLACEHOLDERS$ in the file. E.g. the string $Format:%H$ will be replaced by the commit hash
Comment | File | Size | Author |
---|---|---|---|
#49 | core-gitattributes-1111224-49.patch | 1.71 KB | nod_ |
#48 | 1111224-48-new-.gitattributes.patch | 2.13 KB | marvil07 |
#45 | drupal-1111224-45.patch | 2.56 KB | tim.plunkett |
#28 | sh1.png | 49.53 KB | carwin |
#28 | sh2.png | 54.65 KB | carwin |
Issue fork drupal-1111224
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #1
bfroehle CreditAttribution: bfroehle commentedI think this is a complete list of file extensions used by Drupal, but I might have missed one or two.
Comment #2
bfroehle CreditAttribution: bfroehle commentedFixing the title. Long day, I guess.
Comment #3
pillarsdotnet CreditAttribution: pillarsdotnet commentedHow about adding the following?
Then we could close #1170538: Rename core .gitignore file to example.gitignore and add explanatory comments as a duplicate.
Comment #4
bfroehle CreditAttribution: bfroehle commentedSounds like a great idea to me. I suppose we should also add
Comment #5
webchickQuestion. Since #917492: Add a sensible .gitignore file was well-intentioned, but ended up royally screwing a number of people by enforcing incorrect assumptions on them, how likely is this addition to do the same? Is it fairly common that someone deploying sites from Git would have their own custom .gitattributes doing their own special things, which we would then obliterate by adding this change?
Comment #6
pillarsdotnet CreditAttribution: pillarsdotnet commentedWell, if you're deploying by git, then you can also maintain a local branch and merge with origin. That's what git is for, no?
Comment #7
webchickWell, I think people must have different workflows they use, at least one of which collides very badly with core adding files like this.
See the discussion at #1170538: Rename core .gitignore file to example.gitignore and add explanatory comments as well as http://randyfay.com/node/102
Comment #8
webchickIt might be that .gitattributes is a much less-used file and doesn't suffer from these kinds of potential complications, but I'll just say I'm leery about core forcing any assumptions until some of these workflow issues become more smoothed out.
Comment #9
marvil07 CreditAttribution: marvil07 commented@bfroehle: It would be great if you or someone else can provide an example about how different the git diff hunks will be, so we can take an informed decision.
Comment #10
sunBetter title :)
Stumbling over Mind the End of your Line, the new
.gitattributes
can do a lot more for the benefit of our project's contributors.I carefully crafted a .gitattributes file for Drupal core, including docs that explain what each flag is doing.
The list of the file extensions is complete; it was auto-generated on HEAD with a little command line fu:
Comment #11
sunAdding a nice little new tag :)
Comment #12
joachim CreditAttribution: joachim commentedThis is still something people would have to add globally to cover all their various contrib repos too though? Would be worth announcing it on planet/front page for that.
Comment #13
sunoh, and to answer @marvil07's concern in #9:
By default, git diff does not use any special algorithm for detecting the proper diff context, even if the file extension is
.php
. I've seen countless of patches that contain hunk headers like the following, and I cannot express how awkward they are for reviewers without using explicit language...With the added
.gitattributes
, git diff suddenly understands PHP, and you see hunk headers like this:Check the patches in #56 and #57 on #1215104-56: Use the non-interactive installer in WebTestBase::setUp() to see it yourself. :)
Comment #14
webchickHm. Last time we tried to help people by pre-packaging Git configuration files like this #1170538: Rename core .gitignore file to example.gitignore and add explanatory comments, it caused all manner of problems/workarounds. :( I think if we're going to do this, it needs to be example.gitattributes ala what we did with .gitignore in D8.
Comment #15
marvil07 CreditAttribution: marvil07 commentedThanks for the explanatory link on 10. It totally make sense to use git to help us deal with sharing code in an easier way.
I have some minor comments:
Better a link to official docs http://git-scm.com/docs/gitattributes
java means java code, not javascript, are you sure you want to set to that?
One other thing I think is missing is to exclude vendor directory. It seems like .gitattributes have only matching rules, but there seems to not be an easy way to exclude. So, I guess we need to define the the matching rules to prevent applying them to vendor directory files.
PS: I really like that new tag!
Comment #16
sun#14: On example.gitattributes vs. .gitattributes:
I doubt that's going to be necessary here. The file essentially does two things:
1) It ensures and enforces that files are checked out and in with proper line-endings on all platforms (LF vs. CRLF). This is the standard, not only for Drupal. Most git clients should actually be configured correctly by default already, but given how many patches we see in the queue that have CRLF line-endings in the mix, there still must be a couple of misconfigured git clients.
2) It configures git diff to treat the right files as text, and the right files as binary, using the proper diff algorithm, plus .patch support, for each.
#15:
- The funny and strange thing is that those official docs pages are not parsed and formatted correctly... we can change the link, but the bogus and overly fancy output makes me vote -1 on that. http://schacon.github.com/git/git.html mirrors the latest git manual pages AFAIK, and the output is identical to what people are seeing in their local git manual.
- There's no diff algorithm for javascript, so java comes syntactically closest. Definitely better than nothing.
- As mentioned in 1) above, there's no need to exclude vendor directories, since at least with regard to this, this is a widely adopted standard, especially by open-source projects. In any case, the attributes affect the local checkout only. Git stores everything in LF internally.
Comment #17
marvil07 CreditAttribution: marvil07 commentedThanks for the answers!
Then, let's use kernel.org, which use also the default asciidoc theme and have more recent docs(see last updated at the bottom):
http://www.kernel.org/pub/software/scm/git/docs/gitattributes.html
Make sense. Maybe it worths a little comment ;-)
OK. That means for example, if we are adding one new project to vendor, we will be changing its line ending to conform our standard instead of using what they use. I just wanted to mention it, and I am fine with that, we always have
git diff --ignore-all-space
.Comment #18
sunI guess we ultimately won't notice, regardless of what the project's line-endings are. That is, because the .gitattributes ensure that all input and output is in one style only.
Comment #19
marvil07 CreditAttribution: marvil07 commentedHere the two little changes mentioned on comment 17
Comment #20
dstolUpdated the documentation for js java diff usage.
Comment #21
xjm#20: gitattributes.20.patch queued for re-testing.
Comment #22
xjmAwesome patch. Wish I'd actually read it when I retested it.
To address @webchick's concerns, here's the text from the summary of #1170538: Rename core .gitignore file to example.gitignore and add explanatory comments:
Here's why I think this is a different situation:
.gitignore
overwrote production code. We're not doing that here.For the sake of completeness, to get this in, let's have some folks do some manual testing and document the before-and-after. We don't even need to worry about the case where the user has a
.gitattributes
in the repo before we add this, because we're going to assume D8 ships with this.Testing for any platform
git diff --color
before applying the patch. Apply the patch and repeat.git diff
before applying the patch. Apply the patch and repeat. You can post before-and-after code snippets to illustrate the difference for reviewers.git diff
before applying the patch. Apply the patch and repeat. (You can code snippets, but truncate the binary data to just a couple lines. We don't need an entire binary file in ASCII in an issue comment.) :).gitattributes
file to your.gitconfig
, and add some rules to it that are different from the ones in the patch. Document the results of using this with the patch.Windows testing
crlf-do-not-test.patch
) for other Windows and non-Windows users to test with.Comment #23
webchickThe fact that most of the issues w/ .gitignore were because it was in 7.2 vs. 7.0 is a good point. It's also a good point that this is generally speaking, git attributes affect much less destructive stuff than .gitignore.
I would nevertheless still love to see at least one report back on that "advanced" test case before committing this.
Comment #24
plachI am on windows and thanks to Eclipse I face newline issues constantly. Will perform the tests in #22 and report.
Comment #25
carwin CreditAttribution: carwin commentedTested whitespace errors before and after patch, and because my work environment already highlights whitespace errors in diffs there really isn't much visual change here, however xjm told me this was still relevant and that I should post it. I suppose the thought is that since nothing changed between what my default settings are and what the patch did that the patch is working as expected there.
I have some more tests that I did where I created a patch with whitespace errors before and after the patch presented in 20 which I'll post later as soon as I confirm that I get the same result more than once.
On testing a binary file, should I just modify a jpg or something to git diff?
Attached is the before and after of a
git diff --color filename
before/after patch in #20 within my working environment.Comment #26
plachWindows XP, git version 1.7.11.msysgit.0
Note: I had to convert newlines from CRLF to LF just to stage the .gitattributes file locally, otherwise:
Also commenting my global autocrlf/safecrlf settings (both TRUE) worked.
Before: trailing whitespaces outlined on terminal.
After: trailing whitespaces outlined on terminal.
Before:
Patch snippet:
After:
Terminal output:
Patch snippet:
Before:
Patch snippet:
After:
Patch created, cannot paste/attach.
Before:
Terminal output:
Patch applied. Whitespace error introduced.
After:
Same result.
Before:
Problematic line outlined on terminal.
Terminal output:
After:
Same result but without the warning.
Before:
Terminal output:
Patch not applied.
After:
Same result.
Before:
Terminal output:
Patch not applied.
After:
Same result.
Before:
Terminal output:
After:
Same result.
Patch created with whitespaces in it, no warning.
The local file takes precedence, global attributes are overridden.
Before:
Checked out index.php (CRLF). Changed index.php. Patch created.
Converted modified index.php to LF. Patch created. Terminal output:
LF patch applied with no warning.
After:
Checked out index.php (LF). Changed index.php. Patch created. Terminal output:
Converted modified index.php to CFLF. Patch created. Terminal output:
LF patch applied with no warning.
Converted patch to CRLF. Tried to apply patch. Terminal output:
Comment #27
xjmAwesome testing, thanks @plach!
Comment #28
carwin CreditAttribution: carwin commentedI'll have to finish the rest of the testing requests another night, here's what I got through at tonight's core office hours session:
Before the patch:
@see sh1-1.png attached.
After the patch:
@see sh2-2.png attached.
Before the patch
After the patch
Before the patch
After the patch
Comment #29
carwin CreditAttribution: carwin commentedJust to confirm because xjm asked me to, I ran the binary file test again and here's the output.
Before applying patch in #20, clean branch of 8.x
After applying patch in #20
Steps to produce
Comment #30
xjmThanks @carwin for confirming the result with the binary.
I'd be interested to see what this does with a patch that updates the db dumps, e.g. #1778986: drupal-7.filled.standard_all test db dump has invalid widget info.
Comment #31
sun@xjm: How many more confirmations do you want for the simple answer of:
? ;)
Comment #32
xjmSmart aleck. It actually seems like a UX regression to me from "Binary file changed" with no garbage, which is why I asked carwin to double-check, because it seemed like the opposite of what we should be doing.
Comment #33
xjmFor clarity, my comment in #30 is that I was curious how a binary diff of a tarball would differ. If it bears any relationship to the size of the change, fine, but with the file compressed I wouldn't expect it to. So I guess I don't really see the benefit.
Comment #34
sunBinary diffs of tarballs and zip files are currently only possible by supplying the additional
--binary
flag to git diff. That's the only way you can currently submit a patch to such issues in the first place.Making them less of an edge-case is one of the primary purposes of this patch:
Stop the edge-cases. Don't make me ask. Just diff.
Comment #35
xjmOkay, I can buy that. I misunderstood the intent of that configuration, then.
My remaining concerns are then from @plach's testing:
Seems backwards to me that the warning would go away, but I guess that's again the expected behavior and I'm just misunderstanding.
And:
So here, the configuration Drupal enforces overrides whatever is configured globally. I'd call that by design, though when I spoke to @webchick about this issue in IRC, she brought up the case of Silly Company X that mandates some particular configuration, say, ten-space indentation. I think it's such an edge case to be a nonissue. Consider the scenario:
.htaccess
, the.gitattributes
gets overwritten.BUT! They could work around this by using git, and presumably since they're using git, they're using git. git it? ;)
And also? They'd have to be committing their wild-and-crazy ten-space tabs in core, in which case they have a lot more to worry about when updating core than the
.gitattributes
itself. ;) Any custom module could have its own.gitattributes
for the rebel tabs, thus circumventing the problem.So I'm going to take the plunge and call this RTBC, and not just because @sun is a smartypants.
P.S.: This is my favorite thing:
Method names in class diffs, yay!
Comment #36
xjmComment #37
webchickOk, awesome. Thanks for the thorough testing on this, folks.
Committed and pushed to 8.x. Hopefully this will help increase our contributor velocity going forward.
Let's get a change notice for this, please. (Quickly, if at all possible, since we're bumping up against thresholds.)
Comment #38
tim.plunkettA Symfony file has incorrect line endings, and this is causing it to throw errors, and apparently is wreaking havoc on the testbots.
Comment #39
bleen CreditAttribution: bleen commentedshouldn't this be backported to D7?
Comment #40
tim.plunkettInteresting enough, it only affects D7 (and D6 I suppose), because for D8 tests it doesn't have to change branches.
http://qa.drupal.org/pifr/test/27332
Comment #41
tim.plunkettSo we can either revert this whole patch, or just strip out the line endings in that file and move forward (since future commits will be automatically fixed).
Comment #42
nod_JavaScript is nothing like java, the diff algorithm is now giving useless method information in the diff. Please remove the
diff=java
from the javascript line.#16 How is having
java
better than nothing? "nothing" gives better informations and a less fragmented patch that is easier to review: here are two version of the same patch as example: #1799594: Update to jQuery 1.9.Comment #43
tim.plunkettWe've temporarily switched the default branch as an attempt to fix this until a new commit can be made.
#1799620: Temporarily switch the default git branch for Drupal core to 7.x
Retesting, will post back with results.EDIT: This has temporarily fixed the problem with the D7 testbots.
Comment #44
webchickWell that'll learn me to commit patches before getting on planes. :P~
Reverted.
Now, can someone explain how in the hell I broke *D7* by committing this patch?? And also why testbot didn't freak out before now?
Comment #45
tim.plunkettD8 current has a file with CRLF line endings in it. This .gitattributes file prevents CRLF from being committed. Therefore, it flagged that file as having changes. This prevents you from checking out another branch, which is why it didn't break D8, but it broke D7.
All new files from now on will not be able to be added with CRLF, so we should never have this problem again.
This patch is the same as above, but replaces the CRLF with LF.
Comment #46
bfroehle CreditAttribution: bfroehle commentedUhh, shouldn't we treat .phar files as binary?
Comment #47
pounardphar are archives, so I guess yes.
Comment #48
marvil07 CreditAttribution: marvil07 commentedAfter adding phar as binary, the hunk about changing the phar file should not be needed anymore.
Comment #49
nod_Removed the diff=java and comment for the js line.
Comment #50
tim.plunkettBoth of those changes are good, and adding *.phar is certainly better than my fix.
Sorry webchick, for all of the confusion!
Comment #51
bleen CreditAttribution: bleen commentedI still contend that the new .gitattributes file should be backported to D7...
Comment #52
pounardAgree with #51.
Comment #53
webchickHm. Last time I committed a dot-git-anything to D7, I got angry blog posts, emails, tweets, IRC lashes, and issue queue rage. Definitely not looking forward to that again. :P~ Fortunately, it's not my call anymore, and you can try asking David if he wants to take the risk 18 months into a stable release. ;)
For 8.x though, this seems fine, as long as it doesn't destroy the universe again.
Committed and pushed to 8.x again. Fingers crossed...
Comment #54
tim.plunkettPosted http://drupal.org/node/1803766, please review.
Comment #55
Berdir> It is recursive for all sub-directories that do not contain their own .gitattributes file.
So if a sub-directory contains a .gitattributes file, this one is completely ignored? Or can the one below extend/change what has been set?
Can this be clarified? looks good otherwise.
Comment #56
tim.plunkettGood point @Berdir. I clarified it.
http://drupal.org/node/1803766/revisions/view/2385820/2386704
Comment #57
star-szrChange notice looks good, thanks @tim.plunkett!
Comment #58
bleen CreditAttribution: bleen commentedLets see what David thinks of backporting ...
Comment #59
Jonathan Webb CreditAttribution: Jonathan Webb commentedIf Drupal core is installed in a subdirectory of a repo, the .gitattributes causes git status to complain, and even report phar files as modified. For example if my hosting provider requires the DocumentRoot to be a subdirectory of my Git repository, and I want to maintain Drupal using subtree merges here's what happens when I try to set that up:
Example A:
So Git thinks I've modified ProjectWithXsdExtensionInPhar.phar? Huh???
It's not just an issue with git read-tree. Using rsync or similarly copying Drupal into the docroot folder of a Git repo causes a ton of worrisome messages about changing the contents of binary files as soon as .gitattributes is added:
Example B:
Yikes!
I think it might be wise to get this into the change record, so that it doesn't trip people up. For me, moving .gitattributes into the top-level folder of the repo caused the complaining to stop; but I'm not certain that is the best practice.
Comment #60
JohnAlbin@Jonathon Now that #2166013: Remove macros from .gitattributes to avoid Git errors. has removed the macros, do you still get those errors? If so, open a follow-up issue to discuss.
Doesn't this need to go to 7.x for David to decide if it should be backported?
Comment #61
scor CreditAttribution: scor commentedFollow up issue for D8: #2333243: Relax .gitattributes global rule
Comment #67
NicholasSI can't seem to get this file to not copy from the scaffolds
Does anyone know if this for some reason does not work?
https://www.drupal.org/docs/develop/using-composer/using-drupals-compose...
This is what I see from my CLI, its like it can't ignore the .gitattributes
Scaffolding files for drupal/core:
- Copy [project-root]/.gitattributes from assets/scaffold/files/gitattributes
- Skip [web-root]/.htaccess: overridden in drupal/recommended-project
* Homepage: https://www.drupal.org/project/drupal
* Support:
Comment #70
poker10 CreditAttribution: poker10 at ActivIT s.r.o. commented@NicholasS This issue is 10 years old. Please create a new issue with your request / problem.
Ad D7 backport: D7 planned EOL is on 5.1.2025. I do not think it would be good to introduce this in the current D7 phase, as it would have a minimal effect (and potentially can affect existing developers with different settings). Therefore closing this as fixed for D8 (and fixing credits). Thanks all!