So how can I ask Git if it treats a file as text or binary?
Not only git check-attr --all
is a good option, but with Git 2.40 (Q1 2023), "git check-attr
"(man) learned to take an optional tree-ish to read the .gitattributes
file from.
That means you can Git if it treats a file as text or binary, for any commit, not just the current HEAD!
git check-attr --all --source=@~2 -- myFile
git check-attr --all --source=anotherBranch -- myFile
See commit 47cfc9b, commit c847e8c (14 Jan 2023) by Karthik Nayak (KarthikNayak
).
(Merged by Junio C Hamano -- gitster
-- in commit 577bff3, 23 Jan 2023)
attr
: add flag --source
to work with tree-ish
Signed-off-by: Karthik Nayak
Signed-off-by: Toon Claes
Co-authored-by: [email protected]
The contents of the .gitattributes
files may evolve over time, but "git check-attr
"(man) always checks attributes against them in the working tree and/or in the index.
It may be beneficial to optionally allow the users to check attributes taken from a commit other than HEAD against paths.
Add a new flag --source
which will allow users to check the attributes against a commit (actually any tree-ish would do).
When the user uses this flag, we go through the stack of .gitattributes
files but instead of checking the current working tree and/or in the index, we check the blobs from the provided tree-ish object.
This allows the command to also be used in bare repositories.
Since we use a tree-ish object, the user can pass "--source HEAD:subdirectory" and all the attributes will be looked up as if subdirectory was the root directory of the repository.
We cannot simply use the <rev>:<path>
syntax without the --source
flag, similar to how it is used in git show
(man) because any non-flag parameter before --
is treated as an attribute and any parameter after --
is treated as a pathname.
The change involves creating a new function read_attr_from_blob
, which given the path reads the blob for the path against the provided source and parses the attributes line by line.
This function is plugged into read_attr()
function wherein we go through the stack of attributes files.
git check-attr
now includes in its man page:
'git check-attr' [--source <tree-ish>] [-a | --all | <attr>...] [--] <pathname>...
'git check-attr' --stdin [-z] [--source <tree-ish>] [-a | --all | <attr>...]
git check-attr
now includes in its man page:
--source=<tree-ish>
Check attributes against the specified tree-ish.
It is common to
specify the source tree by naming a commit, branch or tag associated
with it.
If you are using a sparse checked out repository though, make sure to use Git 2.43 (Q4 2023), which teaches "git check-attr
"(man) work better with sparse-index.
See commit f981587, commit 4723ae1, commit fd4faf7 (11 Aug 2023) by Shuqi Liang (none
).
(Merged by Junio C Hamano -- gitster
-- in commit 354356f, 29 Aug 2023)
attr.c
: read attributes in a sparse directory
Helped-by: Victoria Dye
Signed-off-by: Shuqi Liang
Before this patch, git check-attr
(man) was unable to read the attributes from a .gitattributes
file within a sparse directory.
The original comment was operating under the assumption that users are only interested in files or directories inside the cones.
Therefore, in the original code, in the case of a cone-mode sparse-checkout, we didn't load the .gitattributes
file.
However, this behavior can lead to missing attributes for files inside sparse directories, causing inconsistencies in file handling.
To resolve this, revise 'git check-attr
' to allow attribute reading for files in sparse directories from the corresponding .gitattributes
files:
1.Utilize path_in_cone_mode_sparse_checkout()
and index_name_pos_sparse
to check if a path falls within a sparse directory.
2.If path is inside a sparse directory, employ the value of index_name_pos_sparse()
to find the sparse directory containing path and path relative to sparse directory.
Proceed to read attributes from the tree OID of the sparse directory using read_attr_from_blob()
.
3.If path is not inside a sparse directory,ensure that attributes are fetched from the index blob with read_blob_data_from_index()
.
Change the test 'check-attr with pathspec outside sparse definition' to 'test_expect_success
' to reflect that the attributes inside a sparse directory can now be read.
Ensure that the sparse index case works correctly for git check-attr
to illustrate the successful handling of attributes within sparse directories.
Another way, with Git 2.44 (Q1 2024), the builtin_objectmode
attribute is populated for each path without adding anything in .gitattributes
files, which would be useful in magic pathspec, e.g., ":(attr:builtin_objectmode=100755)"
to limit to executables.
See commit 2232a88 (16 Nov 2023) by Joanna Wang (joannajw
).
(Merged by Junio C Hamano -- gitster
-- in commit 3e85584, 12 Jan 2024)
attr
: add builtin objectmode values support
Signed-off-by: Joanna Wang
Gives all paths builtin objectmode values based on the paths' modes (one of 100644, 100755, 120000, 040000, 160000).
Users may use this feature to filter by file types.
For example a pathspec such as ':(attr:builtin_objectmode=160000)
' could filter for submodules without needing to have builtin_objectmode=160000
to be set in .gitattributes
for every submodule path.
These values are also reflected in git check-attr
(man) results.
If the git_attr_direction
is set to GIT_ATTR_INDEX
or GIT_ATTR_CHECKIN
and a path is not found in the index, the value will be unspecified.
This patch also reserves the builtin_*
attribute namespace for objectmode and any future builtin attributes.
Any user defined attributes using this reserved namespace will result in a warning.
This is a breaking change for any existing builtin_*
attributes.
Pathspecs with some builtin_*
attribute name (excluding builtin_objectmode)
will behave like any attribute where there are no user specified values.
gitattributes
now includes in its man page:
RESERVED BUILTIN_* ATTRIBUTES
builtin_*
is a reserved namespace for builtin attribute values. Any
user defined attributes under this namespace will be ignored and
trigger a warning.
builtin_objectmode
This attribute is for filtering files by their file bit modes (40000,
120000, 160000, 100755, 100644). e.g. ':(attr:builtin_objectmode=160000)'.
You may also check these values with git check-attr builtin_objectmode -- <file>
.
If the object is not in the index git check-attr --cached
will return unspecified.
So you can do a git check-attr $check_opts builtin_objectmode -- "$path"
git diff --numstat 4b825dc642cb6eb9a060e54bf8d69288fbee4904 HEAD -- "$1"
. – Rhonda