};
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;
};
/*
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);
}
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;
}