aboutsummaryrefslogtreecommitdiffstats
path: root/pathspec.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2023-12-09 16:37:49 -0800
committerJunio C Hamano <gitster@pobox.com>2023-12-09 16:37:49 -0800
commitd8b0ec44b13f7ee4dd6c8c726b5c105f66a51329 (patch)
tree5e1b2162152023286664719ad30d834833fb9cd4 /pathspec.c
parentMerge branch 'jk/chunk-bounds-more' (diff)
parentattr: enable attr pathspec magic for git-add and git-stash (diff)
downloadgit-d8b0ec44b13f7ee4dd6c8c726b5c105f66a51329.tar.gz
git-d8b0ec44b13f7ee4dd6c8c726b5c105f66a51329.zip
Merge branch 'jw/git-add-attr-pathspec'
"git add" and "git stash" learned to support the ":(attr:...)" magic pathspec. * jw/git-add-attr-pathspec: attr: enable attr pathspec magic for git-add and git-stash
Diffstat (limited to 'pathspec.c')
-rw-r--r--pathspec.c39
1 files changed, 30 insertions, 9 deletions
diff --git a/pathspec.c b/pathspec.c
index bb1efe1f39..2133b9fe60 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -109,16 +109,37 @@ static struct pathspec_magic {
{ PATHSPEC_ATTR, '\0', "attr" },
};
-static void prefix_magic(struct strbuf *sb, int prefixlen, unsigned magic)
+static void prefix_magic(struct strbuf *sb, int prefixlen,
+ unsigned magic, const char *element)
{
- int i;
- strbuf_addstr(sb, ":(");
- for (i = 0; i < ARRAY_SIZE(pathspec_magic); i++)
- if (magic & pathspec_magic[i].bit) {
- if (sb->buf[sb->len - 1] != '(')
- strbuf_addch(sb, ',');
- strbuf_addstr(sb, pathspec_magic[i].name);
+ /* No magic was found in element, just add prefix magic */
+ if (!magic) {
+ strbuf_addf(sb, ":(prefix:%d)", prefixlen);
+ return;
+ }
+
+ /*
+ * At this point, we know that parse_element_magic() was able
+ * to extract some pathspec magic from element. So we know
+ * element is correctly formatted in either shorthand or
+ * longhand form
+ */
+ if (element[1] != '(') {
+ /* Process an element in shorthand form (e.g. ":!/<match>") */
+ strbuf_addstr(sb, ":(");
+ for (int i = 0; i < ARRAY_SIZE(pathspec_magic); i++) {
+ if ((magic & pathspec_magic[i].bit) &&
+ pathspec_magic[i].mnemonic) {
+ if (sb->buf[sb->len - 1] != '(')
+ strbuf_addch(sb, ',');
+ strbuf_addstr(sb, pathspec_magic[i].name);
+ }
}
+ } else {
+ /* For the longhand form, we copy everything up to the final ')' */
+ size_t len = strchr(element, ')') - element;
+ strbuf_add(sb, element, len);
+ }
strbuf_addf(sb, ",prefix:%d)", prefixlen);
}
@@ -493,7 +514,7 @@ static void init_pathspec_item(struct pathspec_item *item, unsigned flags,
struct strbuf sb = STRBUF_INIT;
/* Preserve the actual prefix length of each pattern */
- prefix_magic(&sb, prefixlen, element_magic);
+ prefix_magic(&sb, prefixlen, element_magic, elt);
strbuf_addstr(&sb, match);
item->original = strbuf_detach(&sb, NULL);