Ability determine if gitattributes matches a file at a given ref/branch
We need to be able to look up values for a branch's
.gitattributes file. Currently we can only do this using
info/attributes from the default branch.
Ideally this behaviour would match git's normal behaviour, which might involve checking
.gitattributes files nested in subfolders and allowing filters to be overidden, cancelled out, etc. Some investigation might be required to see how rugged's approach (on bare repos) differs from using
When deciding what attributes are assigned to a path, Git consults $GIT_DIR/info/attributes file (which has the highest precedence), .gitattributes file in the same directory as the path in question, and its parent directories up to the toplevel of the work tree (the further the directory that contains .gitattributes is from the path in question, the lower its precedence). Finally global and system-wide files are considered (they have the lowest precedence).
This has been hardcoded to
info/attributes and can't handle
.gitattributes files individually, but can probably be reused either with a differnt path or by passing in the contents of
.gitattributes as a string.
Attributes class also overwrites rugged's methods in
What Rugged provides
For some reason this doesn't ask for a specific branch, even when using
[:file, :index] priority. Uses
rugged_copy_gitattributes for a given branch does make this work, but I'm not sure if it only ends up using
Rugged allows different search strategies such as
:skip_system, which change the flag passed in to
fetch_attributes(file_path, nil, 0).
check-attr with a temporary index
As suggested in #39785 (comment 52245379) it is possible to use
check-attr for this, using a temporary index file to workaround the limitations of bare repositories.
Using values set in the nested
.gitattributes file in https://gitlab.com/jamedjo/engine/blob/master/subdir/.gitattributes we get the following:
engine.git|master» GIT_INDEX_FILE=tmp-index git read-tree --reset -i master engine.git|master» GIT_INDEX_FILE=tmp-index git check-attr --cached --all subdir/pointer.sub subdir/pointer.sub: diff: lfs subdir/pointer.sub: merge: lfs subdir/pointer.sub: text: unset subdir/pointer.sub: filter: lfs
We switched to
Gitlab::Git::Attributes for performance reasons in gitlab_git@340e111e. We might want to re-examine this before starting to use rugged again for this new scenario.