diff options
Diffstat (limited to 'ref-filter.c')
-rw-r--r-- | ref-filter.c | 41 |
1 files changed, 39 insertions, 2 deletions
diff --git a/ref-filter.c b/ref-filter.c index 2840ca18e3..47e292bc46 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -33,8 +33,8 @@ struct if_then_else { }; struct refname_atom { - enum { R_NORMAL, R_SHORT, R_LSTRIP } option; - int lstrip; + enum { R_NORMAL, R_SHORT, R_LSTRIP, R_RSTRIP } option; + int lstrip, rstrip; }; /* @@ -95,6 +95,10 @@ static void refname_atom_parser_internal(struct refname_atom *atom, atom->option = R_LSTRIP; if (strtol_i(arg, 10, &atom->lstrip)) die(_("Integer value expected refname:lstrip=%s"), arg); + } else if (skip_prefix(arg, "rstrip=", &arg)) { + atom->option = R_RSTRIP; + if (strtol_i(arg, 10, &atom->rstrip)) + die(_("Integer value expected refname:rstrip=%s"), arg); } else die(_("unrecognized %%(%s) argument: %s"), name, arg); } @@ -1125,12 +1129,45 @@ static const char *lstrip_ref_components(const char *refname, int len) return start; } +static const char *rstrip_ref_components(const char *refname, int len) +{ + long remaining = len; + char *start = xstrdup(refname); + + if (len < 0) { + int i; + const char *p = refname; + + /* Find total no of '/' separated path-components */ + for (i = 0; p[i]; p[i] == '/' ? i++ : *p++) + ; + /* + * The number of components we need to strip is now + * the total minus the components to be left (Plus one + * because we count the number of '/', but the number + * of components is one more than the no of '/'). + */ + remaining = i + len + 1; + } + + while (remaining-- > 0) { + char *p = strrchr(start, '/'); + if (p == NULL) + return ""; + else + p[0] = '\0'; + } + return start; +} + static const char *show_ref(struct refname_atom *atom, const char *refname) { if (atom->option == R_SHORT) return shorten_unambiguous_ref(refname, warn_ambiguous_refs); else if (atom->option == R_LSTRIP) return lstrip_ref_components(refname, atom->lstrip); + else if (atom->option == R_RSTRIP) + return rstrip_ref_components(refname, atom->rstrip); else return refname; } |