struct atom_value *v)
{
if (!strcmp(name, "objectname")) {
- char *s = xmalloc(41);
- strcpy(s, sha1_to_hex(sha1));
- v->s = s;
+ v->s = xstrdup(sha1_to_hex(sha1));
return 1;
}
if (!strcmp(name, "objectname:short")) {
if (!strcmp(name, "objecttype"))
v->s = typename(obj->type);
else if (!strcmp(name, "objectsize")) {
- char *s = xmalloc(40);
- sprintf(s, "%lu", sz);
v->ul = sz;
- v->s = s;
+ v->s = xstrfmt("%lu", sz);
}
else if (deref)
grab_objectname(name, obj->sha1, v);
v->s = tag->tag;
else if (!strcmp(name, "type") && tag->tagged)
v->s = typename(tag->tagged->type);
- else if (!strcmp(name, "object") && tag->tagged) {
- char *s = xmalloc(41);
- strcpy(s, sha1_to_hex(tag->tagged->sha1));
- v->s = s;
- }
+ else if (!strcmp(name, "object") && tag->tagged)
+ v->s = xstrdup(sha1_to_hex(tag->tagged->sha1));
}
}
if (deref)
name++;
if (!strcmp(name, "tree")) {
- char *s = xmalloc(41);
- strcpy(s, sha1_to_hex(commit->tree->object.sha1));
- v->s = s;
+ v->s = xstrdup(sha1_to_hex(commit->tree->object.sha1));
}
- if (!strcmp(name, "numparent")) {
- char *s = xmalloc(40);
+ else if (!strcmp(name, "numparent")) {
v->ul = commit_list_count(commit->parents);
- sprintf(s, "%lu", v->ul);
- v->s = s;
+ v->s = xstrfmt("%lu", v->ul);
}
else if (!strcmp(name, "parent")) {
- int num = commit_list_count(commit->parents);
- int i;
struct commit_list *parents;
- char *s = xmalloc(41 * num + 1);
- v->s = s;
- for (i = 0, parents = commit->parents;
- parents;
- parents = parents->next, i = i + 41) {
+ struct strbuf s = STRBUF_INIT;
+ for (parents = commit->parents; parents; parents = parents->next) {
struct commit *parent = parents->item;
- strcpy(s+i, sha1_to_hex(parent->object.sha1));
- if (parents->next)
- s[i+40] = ' ';
+ if (parents != commit->parents)
+ strbuf_addch(&s, ' ');
+ strbuf_addstr(&s, sha1_to_hex(parent->object.sha1));
}
- if (!i)
- *s = '\0';
+ v->s = strbuf_detach(&s, NULL);
}
}
}
else if (!strcmp(formatp, "track") &&
(starts_with(name, "upstream") ||
starts_with(name, "push"))) {
- char buf[40];
if (stat_tracking_info(branch, &num_ours,
&num_theirs, NULL))
if (!num_ours && !num_theirs)
v->s = "";
- else if (!num_ours) {
- sprintf(buf, "[behind %d]", num_theirs);
- v->s = xstrdup(buf);
- } else if (!num_theirs) {
- sprintf(buf, "[ahead %d]", num_ours);
- v->s = xstrdup(buf);
- } else {
- sprintf(buf, "[ahead %d, behind %d]",
- num_ours, num_theirs);
- v->s = xstrdup(buf);
- }
+ else if (!num_ours)
+ v->s = xstrfmt("[behind %d]", num_theirs);
+ else if (!num_theirs)
+ v->s = xstrfmt("[ahead %d]", num_ours);
+ else
+ v->s = xstrfmt("[ahead %d, behind %d]",
+ num_ours, num_theirs);
continue;
} else if (!strcmp(formatp, "trackshort") &&
(starts_with(name, "upstream") ||
if (!deref)
v->s = refname;
- else {
- int len = strlen(refname);
- char *s = xmalloc(len + 4);
- sprintf(s, "%s^{}", refname);
- v->s = s;
- }
+ else
+ v->s = xstrfmt("%s^{}", refname);
}
for (i = 0; i < used_atom_cnt; i++) {
return is_descendant_of(commit, filter->with_commit);
}
+/*
+ * Return 1 if the refname matches one of the patterns, otherwise 0.
+ * A pattern can be a literal prefix (e.g. a refname "refs/heads/master"
+ * matches a pattern "refs/heads/mas") or a wildcard (e.g. the same ref
+ * matches "refs/heads/mas*", too).
+ */
+static int match_pattern(const char **patterns, const char *refname)
+{
+ /*
+ * When no '--format' option is given we need to skip the prefix
+ * for matching refs of tags and branches.
+ */
+ (void)(skip_prefix(refname, "refs/tags/", &refname) ||
+ skip_prefix(refname, "refs/heads/", &refname) ||
+ skip_prefix(refname, "refs/remotes/", &refname) ||
+ skip_prefix(refname, "refs/", &refname));
+
+ for (; *patterns; patterns++) {
+ if (!wildmatch(*patterns, refname, 0, NULL))
+ return 1;
+ }
+ return 0;
+}
+
/*
* Return 1 if the refname matches one of the patterns, otherwise 0.
* A pattern can be path prefix (e.g. a refname "refs/heads/master"
- * matches a pattern "refs/heads/") or a wildcard (e.g. the same ref
- * matches "refs/heads/m*",too).
+ * matches a pattern "refs/heads/" but not "refs/heads/m") or a
+ * wildcard (e.g. the same ref matches "refs/heads/m*", too).
*/
static int match_name_as_path(const char **pattern, const char *refname)
{
return 0;
}
+/* Return 1 if the refname matches one of the patterns, otherwise 0. */
+static int filter_pattern_match(struct ref_filter *filter, const char *refname)
+{
+ if (!*filter->name_patterns)
+ return 1; /* No pattern always matches */
+ if (filter->match_as_path)
+ return match_name_as_path(filter->name_patterns, refname);
+ return match_pattern(filter->name_patterns, refname);
+}
+
/*
* Given a ref (sha1, refname), check if the ref belongs to the array
* of sha1s. If the given ref is a tag, check if the given tag points
if (!(kind & filter->kind))
return 0;
- if (*filter->name_patterns && !match_name_as_path(filter->name_patterns, refname))
+ if (!filter_pattern_match(filter, refname))
return 0;
if (filter->points_at.nr && !match_points_at(&filter->points_at, oid->hash, refname))
* obtain the commit using the 'oid' available and discard all
* non-commits early. The actual filtering is done later.
*/
- if (filter->merge_commit || filter->with_commit) {
+ if (filter->merge_commit || filter->with_commit || filter->verbose) {
commit = lookup_commit_reference_gently(oid->hash, 1);
if (!commit)
return 0;
if (va->ul < vb->ul)
cmp = -1;
else if (va->ul == vb->ul)
- cmp = 0;
+ cmp = strcmp(a->refname, b->refname);
else
cmp = 1;
}