Make git support core.gitattributesRevision for bare repo

At the moment some code depends on Rails calling ApplyGitattributes. This RPC copies HEAD:.gitattributes (being .gitattributes at the HEAD revision of the default branch) into repo-path.git/info/attributes. This makes sure some machinery in Git uses attributes like merge=union.

This isn't great for a few reasons:

  • It's racy. It's not guaranteed the content of info/attributes is up-to-date at all times.
  • It does not support .gitattributes subtrees. Technically a .gitattributes file in a subtree should override all settings in the root.

Example

This is relevant for the linguist attributes. Consider this repo:

$ tree -asI .git/
[        120]  .
├── [        100]  docu
│   ├── [         63]  generate.rb
│   ├── [         35]  .gitattributes
│   └── [         38]  install.md
├── [         29]  .gitattributes
└── [         61]  main.rb

1 directory, 5 files

$ cat .gitattributes
docu/* linguist-documentation

$ cat docu/.gitattributes
generate.rb -linguist-documentation

$ github-linguist
100.00% 124        Ruby

$ git check-attr -a docu/generate.rb
docu/generate.rb: diff: ruby
docu/generate.rb: linguist-documentation: unset

All this works as expected.

But when you clone this into a bare repo:

$ git clone --bare repo.git

$ github-linguist
100.00% 124        Ruby

$ git check-attr -a docu/generate.rb
docu/generate.rb: diff: ruby

$ git cat-file blob main:.gitattributes > info/attributes
docu/generate.rb: diff: ruby
docu/generate.rb: linguist-documentation: set

github-linguist works correctly, but git-check-attr(1) doesn't.

Proposal

We add a config option to Git, something like core.gitattributesRevision. This option we use in all relevant git calls and we pass the revision of the HEAD commit (default branch). Git inner machinery should then use this revision to read all the gitattributes for the whole tree of that revision.

After this we should retire the ApplyGitattributes RPC.

Edited by Toon Claes