From: Junio C Hamano <gitster@pobox.com>
To: Joanna Wang <jojwang@google.com>
Cc: git@vger.kernel.org
Subject: Re: [PATCH 1/1] attr: add native file mode values support
Date: Sat, 11 Nov 2023 13:48:43 +0900 [thread overview]
Message-ID: <xmqqpm0grj2s.fsf@gitster.g> (raw)
In-Reply-To: <20231111040309.2848560-1-jojwang@google.com> (Joanna Wang's message of "Sat, 11 Nov 2023 04:03:08 +0000")
Joanna Wang <jojwang@google.com> writes:
> +/*
> + * This implements native file mode attr support.
> + * We always return the current mode of the path, not the mode stored
> + * in the index, unless the path is a directory where we check the index
> + * to see if it is a GITLINK. It is ok to rely on the index for GITLINK
> + * modes because a path cannot become a GITLINK (which is a git concept only)
> + * without having it indexed with a GITLINK mode in git.
> + */
> +static unsigned int native_mode_attr(struct index_state *istate, const char *path)
> +{
> + struct stat st;
> + unsigned int mode;
Please have a blank line here between decls and the first statement.
> + if (lstat(path, &st))
> + die_errno(_("unable to stat '%s'"), path);
For checking in, this is probably OK, but don't we need to switch
between lstat() on the filesystem entity and inspecting ce_mode()
for the in-index cache_entry, depending on the git_attr_direction?
> + mode = canon_mode(st.st_mode);
> + if (S_ISDIR(mode)) {
> + int pos = index_name_pos(istate, path, strlen(path));
> + if (pos >= 0)
> + if (S_ISGITLINK(istate->cache[pos]->ce_mode))
> + return istate->cache[pos]->ce_mode;
Even if we assume that this code is currently meant to work only
with GIT_ATTR_CHECKIN, I do not think this is what you want. When
asked to perform "git add . ':(exclude,mode=160000)'", you not only
want to exclude the submodules that are already known to this
superproject, but also a repository that _can_ become a submodule of
this superproject when added, no? You are missing "if (pos < 0)"
case where you'd probably want to see if the directory at the path
looks like the top of a working tree with ".git" subdirectory that
is a valid repository, or something like that to detect such a case.
On the other hand, the GIT_ATTR_CHECKOUT direction is hopefully much
simpler. You'd see what the path in the index is, among a gitlink,
a regular non-executable file, an executable file, or a symlink.
> + }
> + return mode;
> +}
> +
> +
> void git_check_attr(struct index_state *istate,
> const char *path,
> struct attr_check *check)
> {
> int i;
> const struct object_id *tree_oid = default_attr_source();
> + struct strbuf sb = STRBUF_INIT;
>
> collect_some_attrs(istate, tree_oid, path, check);
>
> for (i = 0; i < check->nr; i++) {
> unsigned int n = check->items[i].attr->attr_nr;
> const char *value = check->all_attrs[n].value;
> - if (value == ATTR__UNKNOWN)
> - value = ATTR__UNSET;
> + if (value == ATTR__UNKNOWN){
Style. Missing SP between "){".
> + if (strcmp(check->all_attrs[n].attr->name, "mode") == 0) {
Style. We avoid comparison with 0; so say
if (!strcmp(check->all_attrs[n].attr->name, "mode") == 0) {
instead.
It is disturbing that we always need to perform a string comparison
in this loop (and the function is called repeatedly while traversing
the tree looking for paths that match pathspec). The attribute objects
are designed to be interned, so at least you should be able to do
mode_attr = git_attr("mode");
before the loop and then compare check->all_attrs[n].attr and
mode_attr as two addresses.
> + /*
> + * If value is ATTR_UNKNOWN then it has not been set
> + * anywhere with -mode (ATTR_FALSE), !mode (ATTR_UNSET),
> + * mode (ATTR_TRUE), or an explicit value. We fill
> + * value with the native mode value.
> + */
> + strbuf_addf(&sb, "%06o", native_mode_attr(istate, path));
> + value = sb.buf;
Or even better yet, as this is not a place to write too many lines
for a single oddball attribute, it might make even more sense to
introduce a helper function and make a call to it like so:
if (value == ATTR__UNKNOWN)
- value = ATTR__UNSET;
+ value = compute_attr_from_path(istate, path, check_items[i].attr);
with the new helper function do all the heavy lifting, e.g.,
static const char *compute_attr_from_path(struct index_state *istate,
const char *path,
const struct git_attr *attr) {
static struct git_attr mode_attr;
if (!mode_attr)
mode_attr = git_attr("mode");
if (attr == mode_attr) {
call native_mode_attr(), stringify, and
return it;
}
return ATTR__UNSET;
}
which will allow us to easily add in the future special attribute
similar to "mode" whose fallback value is computed.
Otherwise, looking pretty good. Thanks for working on this.
next prev parent reply other threads:[~2023-11-11 4:48 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-11-11 4:03 [PATCH 1/1] attr: add native file mode values support Joanna Wang
2023-11-11 4:48 ` Junio C Hamano [this message]
2023-11-13 16:50 ` Torsten Bögershausen
2023-11-13 22:22 ` Junio C Hamano
-- strict thread matches above, loose matches on Subject: below --
2023-11-14 2:28 Joanna Wang
2023-11-14 2:52 ` Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=xmqqpm0grj2s.fsf@gitster.g \
--to=gitster@pobox.com \
--cc=git@vger.kernel.org \
--cc=jojwang@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).