Add the options `:dir` and `:base` to the %(refname) atom. The `:dir` option gives the directory (the part after $GIT_DIR/) of the ref without the refname. The `:base` option gives the base directory of the given ref (i.e. the directory following $GIT_DIR/refs/). Add tests and documentation for the same. --- Documentation/git-for-each-ref.txt | 4 +++- ref-filter.c | 23 +++++++++++++++++++ t/t6302-for-each-ref-filter.sh | 47 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 1 deletion(-) diff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt index 206d646..b8d33a1 100644 --- a/Documentation/git-for-each-ref.txt +++ b/Documentation/git-for-each-ref.txt @@ -92,7 +92,9 @@ refname:: The name of the ref (the part after $GIT_DIR/). For a non-ambiguous short name of the ref append `:short`. The option core.warnAmbiguousRefs is used to select the strict - abbreviation mode. + abbreviation mode. For the base directory of the ref (i.e. foo + in refs/foo/bar/boz) append `:base`. For the entire directory + path append `:dir`. objecttype:: The type of the object (`blob`, `tree`, `commit`, `tag`). diff --git a/ref-filter.c b/ref-filter.c index 359c76d..94d8754 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -1105,6 +1105,29 @@ static void populate_value(struct ref_array_item *ref) else v->s = "<>"; continue; + } else if (!strcmp(formatp, "dir") && + (starts_with(name, "refname"))) { + const char *sp, *ep, *tmp; + + sp = tmp = ref->refname; + /* Obtain refs/foo/bar/ from refname refs/foo/bar/abc */ + do { + ep = tmp; + tmp = strchr(ep + 1, '/'); + } while (tmp); + v->s = xstrndup(sp, ep - sp); + continue; + } else if (!strcmp(formatp, "base") && + (starts_with(name, "refname"))) { + const char *sp, *ep; + + if (skip_prefix(ref->refname, "refs/", &sp)) { + ep = strchr(sp, '/'); + if (!ep) + continue; + v->s = xstrndup(sp, ep - sp); + } + continue; } else die("unknown %.*s format %s", (int)(formatp - name), name, formatp); diff --git a/t/t6302-for-each-ref-filter.sh b/t/t6302-for-each-ref-filter.sh index f45ac1f..19a5075 100755 --- a/t/t6302-for-each-ref-filter.sh +++ b/t/t6302-for-each-ref-filter.sh @@ -340,4 +340,51 @@ test_expect_success 'check %(if:notequals=<string>)' ' test_cmp expect actual ' +test_expect_success 'update refs for %(refname:dir) and %(refname:base)' ' + git update-ref refs/foo HEAD && + git update-ref refs/foodir/bar/boz HEAD +' + +test_expect_success 'check %(refname:dir)' ' + git for-each-ref --format="%(refname:dir)" >actual && + cat >expect <<-\EOF && + refs + refs/foodir/bar + refs/heads + refs/heads + refs/odd + refs/tags + refs/tags + refs/tags + refs/tags + refs/tags + refs/tags + refs/tags + refs/tags + refs/tags + EOF + test_cmp expect actual +' + +test_expect_success 'check %(refname:base)' ' + git for-each-ref --format="%(refname:base)" >actual && + cat >expect <<-\EOF && + + foodir + heads + heads + odd + tags + tags + tags + tags + tags + tags + tags + tags + tags + EOF + test_cmp expect actual +' + test_done -- 2.6.0 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html