char color[COLOR_MAXLEN];
struct align align;
struct {
- enum { RR_REF, RR_TRACK, RR_TRACKSHORT } option;
+ enum {
+ RR_REF, RR_TRACK, RR_TRACKSHORT, RR_REMOTE_NAME, RR_REMOTE_REF
+ } option;
struct refname_atom refname;
- unsigned int nobracket : 1;
+ unsigned int nobracket : 1, push : 1, push_remote : 1;
} remote_ref;
struct {
enum { C_BARE, C_BODY, C_BODY_DEP, C_LINES, C_SIG, C_SUB, C_TRAILERS } option;
struct string_list params = STRING_LIST_INIT_DUP;
int i;
+ if (!strcmp(atom->name, "push") || starts_with(atom->name, "push:"))
+ atom->u.remote_ref.push = 1;
+
if (!arg) {
atom->u.remote_ref.option = RR_REF;
refname_atom_parser_internal(&atom->u.remote_ref.refname,
atom->u.remote_ref.option = RR_TRACKSHORT;
else if (!strcmp(s, "nobracket"))
atom->u.remote_ref.nobracket = 1;
- else {
+ else if (!strcmp(s, "remotename")) {
+ atom->u.remote_ref.option = RR_REMOTE_NAME;
+ atom->u.remote_ref.push_remote = 1;
+ } else if (!strcmp(s, "remoteref")) {
+ atom->u.remote_ref.option = RR_REMOTE_REF;
+ atom->u.remote_ref.push_remote = 1;
+ } else {
atom->u.remote_ref.option = RR_REF;
refname_atom_parser_internal(&atom->u.remote_ref.refname,
arg, atom->name);
static void head_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
{
- struct object_id unused;
-
- atom->u.head = resolve_refdup("HEAD", RESOLVE_REF_READING, unused.hash, NULL);
+ atom->u.head = resolve_refdup("HEAD", RESOLVE_REF_READING, NULL, NULL);
}
static struct {
REALLOC_ARRAY(used_atom, used_atom_cnt);
used_atom[at].name = xmemdupz(atom, ep - atom);
used_atom[at].type = valid_atom[i].cmp_type;
- if (arg)
+ if (arg) {
arg = used_atom[at].name + (arg - atom) + 1;
+ if (!*arg) {
+ /*
+ * Treat empty sub-arguments list as NULL (i.e.,
+ * "%(atom:)" is equivalent to "%(atom)").
+ */
+ arg = NULL;
+ }
+ }
memset(&used_atom[at].u, 0, sizeof(used_atom[at].u));
if (valid_atom[i].parser)
valid_atom[i].parser(format, &used_atom[at], arg);
*s = ">";
else
*s = "<>";
+ } else if (atom->u.remote_ref.option == RR_REMOTE_NAME) {
+ int explicit;
+ const char *remote = atom->u.remote_ref.push ?
+ pushremote_for_branch(branch, &explicit) :
+ remote_for_branch(branch, &explicit);
+ if (explicit)
+ *s = xstrdup(remote);
+ else
+ *s = "";
+ } else if (atom->u.remote_ref.option == RR_REMOTE_REF) {
+ int explicit;
+ const char *merge;
+
+ merge = remote_ref_for_branch(branch, atom->u.remote_ref.push,
+ &explicit);
+ if (explicit)
+ *s = xstrdup(merge);
+ else
+ *s = "";
} else
die("BUG: unhandled RR_* enum");
}
ref->value = xcalloc(used_atom_cnt, sizeof(struct atom_value));
if (need_symref && (ref->flag & REF_ISSYMREF) && !ref->symref) {
- struct object_id unused1;
ref->symref = resolve_refdup(ref->refname, RESOLVE_REF_READING,
- unused1.hash, NULL);
+ NULL, NULL);
if (!ref->symref)
ref->symref = "";
}
if (refname)
fill_remote_ref_details(atom, refname, branch, &v->s);
continue;
- } else if (starts_with(name, "push")) {
+ } else if (atom->u.remote_ref.push) {
const char *branch_name;
if (!skip_prefix(ref->refname, "refs/heads/",
&branch_name))
continue;
branch = branch_get(branch_name);
- refname = branch_get_push(branch, NULL);
- if (!refname)
- continue;
+ if (atom->u.remote_ref.push_remote)
+ refname = NULL;
+ else {
+ refname = branch_get_push(branch, NULL);
+ if (!refname)
+ continue;
+ }
fill_remote_ref_details(atom, refname, branch, &v->s);
continue;
} else if (starts_with(name, "color:")) {