ref-filter: add an 'rstrip=<N>' option to atoms which deal with refnames
Complimenting the existing 'lstrip=<N>' option, add an 'rstrip=<N>' option which strips `<N>` slash-separated path components from the end of the refname (e.g., `%(refname:rstrip=2)` turns `refs/tags/foo` into `refs`). Signed-off-by: Karthik Nayak <Karthik.188@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:

committed by
Junio C Hamano

parent
1a0ca5e358
commit
1a34728e6b
@ -95,13 +95,15 @@ refname::
|
|||||||
The name of the ref (the part after $GIT_DIR/).
|
The name of the ref (the part after $GIT_DIR/).
|
||||||
For a non-ambiguous short name of the ref append `:short`.
|
For a non-ambiguous short name of the ref append `:short`.
|
||||||
The option core.warnAmbiguousRefs is used to select the strict
|
The option core.warnAmbiguousRefs is used to select the strict
|
||||||
abbreviation mode. If `lstrip=<N>` is appended, strips `<N>`
|
abbreviation mode. If `lstrip=<N>` (`rstrip=<N>`) is appended, strips `<N>`
|
||||||
slash-separated path components from the front of the refname
|
slash-separated path components from the front (back) of the refname
|
||||||
(e.g. `%(refname:lstrip=2)` turns `refs/tags/foo` into `foo`.
|
(e.g. `%(refname:lstrip=2)` turns `refs/tags/foo` into `foo` and
|
||||||
|
`%(refname:rstrip=2)` turns `refs/tags/foo` into `refs`).
|
||||||
If `<N>` is a negative number, strip as many path components as
|
If `<N>` is a negative number, strip as many path components as
|
||||||
necessary from the left to leave `-<N>` path components
|
necessary from the specified end to leave `-<N>` path components
|
||||||
(e.g. `%(refname:lstrip=-2)` turns
|
(e.g. `%(refname:lstrip=-2)` turns
|
||||||
`refs/tags/foo` into `tags/foo`). When the ref does not have
|
`refs/tags/foo` into `tags/foo` and `%(refname:rstrip=-1)`
|
||||||
|
turns `refs/tags/foo` into `refs`). When the ref does not have
|
||||||
enough components, the result becomes an empty string if
|
enough components, the result becomes an empty string if
|
||||||
stripping with positive <N>, or it becomes the full refname if
|
stripping with positive <N>, or it becomes the full refname if
|
||||||
stripping with negative <N>. Neither is an error.
|
stripping with negative <N>. Neither is an error.
|
||||||
@ -121,22 +123,23 @@ objectname::
|
|||||||
|
|
||||||
upstream::
|
upstream::
|
||||||
The name of a local ref which can be considered ``upstream''
|
The name of a local ref which can be considered ``upstream''
|
||||||
from the displayed ref. Respects `:short` and `:lstrip` in the
|
from the displayed ref. Respects `:short`, `:lstrip` and
|
||||||
same way as `refname` above. Additionally respects `:track`
|
`:rstrip` in the same way as `refname` above. Additionally
|
||||||
to show "[ahead N, behind M]" and `:trackshort` to show the
|
respects `:track` to show "[ahead N, behind M]" and
|
||||||
terse version: ">" (ahead), "<" (behind), "<>" (ahead and
|
`:trackshort` to show the terse version: ">" (ahead), "<"
|
||||||
behind), or "=" (in sync). `:track` also prints "[gone]"
|
(behind), "<>" (ahead and behind), or "=" (in sync). `:track`
|
||||||
whenever unknown upstream ref is encountered. Append
|
also prints "[gone]" whenever unknown upstream ref is
|
||||||
`:track,nobracket` to show tracking information without
|
encountered. Append `:track,nobracket` to show tracking
|
||||||
brackets (i.e "ahead N, behind M"). Has no effect if the ref
|
information without brackets (i.e "ahead N, behind M"). Has
|
||||||
does not have tracking information associated with it. All
|
no effect if the ref does not have tracking information
|
||||||
the options apart from `nobracket` are mutually exclusive, but
|
associated with it. All the options apart from `nobracket`
|
||||||
if used together the last option is selected.
|
are mutually exclusive, but if used together the last option
|
||||||
|
is selected.
|
||||||
|
|
||||||
push::
|
push::
|
||||||
The name of a local ref which represents the `@{push}`
|
The name of a local ref which represents the `@{push}`
|
||||||
location for the displayed ref. Respects `:short`, `:lstrip`,
|
location for the displayed ref. Respects `:short`, `:lstrip`,
|
||||||
`:track`, and `:trackshort` options as `upstream`
|
`:rstrip`, `:track`, and `:trackshort` options as `upstream`
|
||||||
does. Produces an empty string if no `@{push}` ref is
|
does. Produces an empty string if no `@{push}` ref is
|
||||||
configured.
|
configured.
|
||||||
|
|
||||||
@ -178,8 +181,9 @@ if::
|
|||||||
|
|
||||||
symref::
|
symref::
|
||||||
The ref which the given symbolic ref refers to. If not a
|
The ref which the given symbolic ref refers to. If not a
|
||||||
symbolic ref, nothing is printed. Respects the `:short` and
|
symbolic ref, nothing is printed. Respects the `:short`,
|
||||||
`:lstrip` options in the same way as `refname` above.
|
`:lstrip` and `:rstrip` options in the same way as `refname`
|
||||||
|
above.
|
||||||
|
|
||||||
In addition to the above, for commit and tag objects, the header
|
In addition to the above, for commit and tag objects, the header
|
||||||
field names (`tree`, `parent`, `object`, `type`, and `tag`) can
|
field names (`tree`, `parent`, `object`, `type`, and `tag`) can
|
||||||
|
41
ref-filter.c
41
ref-filter.c
@ -33,8 +33,8 @@ struct if_then_else {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct refname_atom {
|
struct refname_atom {
|
||||||
enum { R_NORMAL, R_SHORT, R_LSTRIP } option;
|
enum { R_NORMAL, R_SHORT, R_LSTRIP, R_RSTRIP } option;
|
||||||
int lstrip;
|
int lstrip, rstrip;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -95,6 +95,10 @@ static void refname_atom_parser_internal(struct refname_atom *atom,
|
|||||||
atom->option = R_LSTRIP;
|
atom->option = R_LSTRIP;
|
||||||
if (strtol_i(arg, 10, &atom->lstrip))
|
if (strtol_i(arg, 10, &atom->lstrip))
|
||||||
die(_("Integer value expected refname:lstrip=%s"), arg);
|
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
|
} else
|
||||||
die(_("unrecognized %%(%s) argument: %s"), name, arg);
|
die(_("unrecognized %%(%s) argument: %s"), name, arg);
|
||||||
}
|
}
|
||||||
@ -1125,12 +1129,45 @@ static const char *lstrip_ref_components(const char *refname, int len)
|
|||||||
return start;
|
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)
|
static const char *show_ref(struct refname_atom *atom, const char *refname)
|
||||||
{
|
{
|
||||||
if (atom->option == R_SHORT)
|
if (atom->option == R_SHORT)
|
||||||
return shorten_unambiguous_ref(refname, warn_ambiguous_refs);
|
return shorten_unambiguous_ref(refname, warn_ambiguous_refs);
|
||||||
else if (atom->option == R_LSTRIP)
|
else if (atom->option == R_LSTRIP)
|
||||||
return lstrip_ref_components(refname, atom->lstrip);
|
return lstrip_ref_components(refname, atom->lstrip);
|
||||||
|
else if (atom->option == R_RSTRIP)
|
||||||
|
return rstrip_ref_components(refname, atom->rstrip);
|
||||||
else
|
else
|
||||||
return refname;
|
return refname;
|
||||||
}
|
}
|
||||||
|
@ -55,14 +55,22 @@ test_atom head refname:lstrip=1 heads/master
|
|||||||
test_atom head refname:lstrip=2 master
|
test_atom head refname:lstrip=2 master
|
||||||
test_atom head refname:lstrip=-1 master
|
test_atom head refname:lstrip=-1 master
|
||||||
test_atom head refname:lstrip=-2 heads/master
|
test_atom head refname:lstrip=-2 heads/master
|
||||||
|
test_atom head refname:rstrip=1 refs/heads
|
||||||
|
test_atom head refname:rstrip=2 refs
|
||||||
|
test_atom head refname:rstrip=-1 refs
|
||||||
|
test_atom head refname:rstrip=-2 refs/heads
|
||||||
test_atom head upstream refs/remotes/origin/master
|
test_atom head upstream refs/remotes/origin/master
|
||||||
test_atom head upstream:short origin/master
|
test_atom head upstream:short origin/master
|
||||||
test_atom head upstream:lstrip=2 origin/master
|
test_atom head upstream:lstrip=2 origin/master
|
||||||
test_atom head upstream:lstrip=-2 origin/master
|
test_atom head upstream:lstrip=-2 origin/master
|
||||||
|
test_atom head upstream:rstrip=2 refs/remotes
|
||||||
|
test_atom head upstream:rstrip=-2 refs/remotes
|
||||||
test_atom head push refs/remotes/myfork/master
|
test_atom head push refs/remotes/myfork/master
|
||||||
test_atom head push:short myfork/master
|
test_atom head push:short myfork/master
|
||||||
test_atom head push:lstrip=1 remotes/myfork/master
|
test_atom head push:lstrip=1 remotes/myfork/master
|
||||||
test_atom head push:lstrip=-1 master
|
test_atom head push:lstrip=-1 master
|
||||||
|
test_atom head push:rstrip=1 refs/remotes/myfork
|
||||||
|
test_atom head push:rstrip=-1 refs
|
||||||
test_atom head objecttype commit
|
test_atom head objecttype commit
|
||||||
test_atom head objectsize 171
|
test_atom head objectsize 171
|
||||||
test_atom head objectname $(git rev-parse refs/heads/master)
|
test_atom head objectname $(git rev-parse refs/heads/master)
|
||||||
@ -631,4 +639,15 @@ test_expect_success 'Verify usage of %(symref:lstrip) atom' '
|
|||||||
test_cmp expected actual
|
test_cmp expected actual
|
||||||
'
|
'
|
||||||
|
|
||||||
|
cat >expected <<EOF
|
||||||
|
refs
|
||||||
|
refs/heads
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_expect_success 'Verify usage of %(symref:rstrip) atom' '
|
||||||
|
git for-each-ref --format="%(symref:rstrip=2)" refs/heads/sym > actual &&
|
||||||
|
git for-each-ref --format="%(symref:rstrip=-2)" refs/heads/sym >> actual &&
|
||||||
|
test_cmp expected actual
|
||||||
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
Reference in New Issue
Block a user