diff options
author | Karthik Nayak <karthik.188@gmail.com> | 2023-01-14 08:30:38 (GMT) |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2023-01-14 16:49:55 (GMT) |
commit | 47cfc9bd7d0add617cf6d928e96b7d207be614f1 (patch) | |
tree | 72af9265a72d2b08913a8bb1eb252e80fd7ebe29 /builtin | |
parent | c847e8c228a7820f11ce66d82dc68cd2241af031 (diff) | |
download | git-47cfc9bd7d0add617cf6d928e96b7d207be614f1.zip git-47cfc9bd7d0add617cf6d928e96b7d207be614f1.tar.gz git-47cfc9bd7d0add617cf6d928e96b7d207be614f1.tar.bz2 |
attr: add flag `--source` to work with tree-ish
The contents of the .gitattributes files may evolve over time, but "git
check-attr" 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` 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.
Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
Signed-off-by: Toon Claes <toon@iotcl.com>
Co-authored-by: toon@iotcl.com
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin')
-rw-r--r-- | builtin/check-attr.c | 35 | ||||
-rw-r--r-- | builtin/pack-objects.c | 2 |
2 files changed, 23 insertions, 14 deletions
diff --git a/builtin/check-attr.c b/builtin/check-attr.c index 0fef10e..d7a40e6 100644 --- a/builtin/check-attr.c +++ b/builtin/check-attr.c @@ -9,9 +9,10 @@ static int all_attrs; static int cached_attrs; static int stdin_paths; +static char *source; static const char * const check_attr_usage[] = { -N_("git check-attr [-a | --all | <attr>...] [--] <pathname>..."), -N_("git check-attr --stdin [-z] [-a | --all | <attr>...]"), +N_("git check-attr [--source <tree-ish>] [-a | --all | <attr>...] [--] <pathname>..."), +N_("git check-attr --stdin [-z] [--source <tree-ish>] [-a | --all | <attr>...]"), NULL }; @@ -23,6 +24,7 @@ static const struct option check_attr_options[] = { OPT_BOOL(0 , "stdin", &stdin_paths, N_("read file names from stdin")), OPT_BOOL('z', NULL, &nul_term_line, N_("terminate input and output records by a NUL character")), + OPT_STRING(0, "source", &source, N_("<tree-ish>"), N_("which tree-ish to check attributes at")), OPT_END() }; @@ -55,27 +57,26 @@ static void output_attr(struct attr_check *check, const char *file) } } -static void check_attr(const char *prefix, - struct attr_check *check, - int collect_all, +static void check_attr(const char *prefix, struct attr_check *check, + const struct object_id *tree_oid, int collect_all, const char *file) + { char *full_path = prefix_path(prefix, prefix ? strlen(prefix) : 0, file); if (collect_all) { - git_all_attrs(&the_index, full_path, check); + git_all_attrs(&the_index, tree_oid, full_path, check); } else { - git_check_attr(&the_index, full_path, check); + git_check_attr(&the_index, tree_oid, full_path, check); } output_attr(check, file); free(full_path); } -static void check_attr_stdin_paths(const char *prefix, - struct attr_check *check, - int collect_all) +static void check_attr_stdin_paths(const char *prefix, struct attr_check *check, + const struct object_id *tree_oid, int collect_all) { struct strbuf buf = STRBUF_INIT; struct strbuf unquoted = STRBUF_INIT; @@ -89,7 +90,7 @@ static void check_attr_stdin_paths(const char *prefix, die("line is badly quoted"); strbuf_swap(&buf, &unquoted); } - check_attr(prefix, check, collect_all, buf.buf); + check_attr(prefix, check, tree_oid, collect_all, buf.buf); maybe_flush_or_die(stdout, "attribute to stdout"); } strbuf_release(&buf); @@ -105,6 +106,8 @@ static NORETURN void error_with_usage(const char *msg) int cmd_check_attr(int argc, const char **argv, const char *prefix) { struct attr_check *check; + struct object_id *tree_oid = NULL; + struct object_id initialized_oid; int cnt, i, doubledash, filei; if (!is_bare_repository()) @@ -176,11 +179,17 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix) } } + if (source) { + if (repo_get_oid_tree(the_repository, source, &initialized_oid)) + die("%s: not a valid tree-ish source", source); + tree_oid = &initialized_oid; + } + if (stdin_paths) - check_attr_stdin_paths(prefix, check, all_attrs); + check_attr_stdin_paths(prefix, check, tree_oid, all_attrs); else { for (i = filei; i < argc; i++) - check_attr(prefix, check, all_attrs, argv[i]); + check_attr(prefix, check, tree_oid, all_attrs, argv[i]); maybe_flush_or_die(stdout, "attribute to stdout"); } diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 2193f80..cabace4 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -1318,7 +1318,7 @@ static int no_try_delta(const char *path) if (!check) check = attr_check_initl("delta", NULL); - git_check_attr(the_repository->index, path, check); + git_check_attr(the_repository->index, NULL, path, check); if (ATTR_FALSE(check->items[0].value)) return 1; return 0; |