Skip to content

Commit 34f843f

Browse files
committed
Merge branch 'kh/name-rev-custom-format' into seen
"git name-rev" learned to use custom format instead of the object name in an extended SHA-1 expression form. * kh/name-rev-custom-format: name-rev: learn --format=<pretty> name-rev: wrap both blocks in braces
2 parents 1c9e1a4 + 1c9573c commit 34f843f

3 files changed

Lines changed: 139 additions & 13 deletions

File tree

Documentation/git-name-rev.adoc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ git-name-rev - Find symbolic names for given revs
99
SYNOPSIS
1010
--------
1111
[verse]
12-
'git name-rev' [--tags] [--refs=<pattern>]
12+
'git name-rev' [--tags] [--refs=<pattern>] [--format=<pretty>]
1313
( --all | --annotate-stdin | <commit-ish>... )
1414

1515
DESCRIPTION
@@ -21,6 +21,13 @@ format parsable by 'git rev-parse'.
2121
OPTIONS
2222
-------
2323

24+
--format=<pretty>::
25+
--no-format::
26+
Format revisions instead of outputting symbolic names. The
27+
default is `--no-format`.
28+
+
29+
Implies `--name-only`.
30+
2431
--tags::
2532
Do not use branch names, but only tags to name the commits
2633

builtin/name-rev.c

Lines changed: 73 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
#include "commit-graph.h"
1919
#include "wildmatch.h"
2020
#include "mem-pool.h"
21+
#include "pretty.h"
22+
#include "revision.h"
23+
#include "notes.h"
2124

2225
/*
2326
* One day. See the 'name a rev shortly after epoch' test in t6120 when
@@ -33,6 +36,11 @@ struct rev_name {
3336
int from_tag;
3437
};
3538

39+
struct pretty_format {
40+
struct pretty_print_context ctx;
41+
struct userformat_want want;
42+
};
43+
3644
define_commit_slab(commit_rev_name, struct rev_name);
3745

3846
static timestamp_t generation_cutoff = GENERATION_NUMBER_INFINITY;
@@ -454,21 +462,42 @@ static const char *get_exact_ref_match(const struct object *o)
454462
}
455463

456464
/* may return a constant string or use "buf" as scratch space */
457-
static const char *get_rev_name(const struct object *o, struct strbuf *buf)
465+
static const char *get_rev_name(const struct object *o,
466+
struct pretty_format *format_ctx,
467+
struct strbuf *buf)
458468
{
459469
struct rev_name *n;
460470
const struct commit *c;
461471

462472
if (o->type != OBJ_COMMIT)
463473
return get_exact_ref_match(o);
464474
c = (const struct commit *) o;
475+
476+
if (format_ctx) {
477+
strbuf_reset(buf);
478+
479+
if (format_ctx->want.notes) {
480+
struct strbuf notebuf = STRBUF_INIT;
481+
482+
format_display_notes(&c->object.oid, &notebuf,
483+
get_log_output_encoding(),
484+
format_ctx->ctx.fmt == CMIT_FMT_USERFORMAT);
485+
format_ctx->ctx.notes_message = strbuf_detach(&notebuf, NULL);
486+
}
487+
488+
pretty_print_commit(&format_ctx->ctx, c, buf);
489+
free(format_ctx->ctx.notes_message);
490+
491+
return buf->buf;
492+
}
493+
465494
n = get_commit_rev_name(c);
466495
if (!n)
467496
return NULL;
468497

469-
if (!n->generation)
498+
if (!n->generation) {
470499
return n->tip_name;
471-
else {
500+
} else {
472501
strbuf_reset(buf);
473502
strbuf_addstr(buf, n->tip_name);
474503
strbuf_strip_suffix(buf, "^0");
@@ -479,6 +508,7 @@ static const char *get_rev_name(const struct object *o, struct strbuf *buf)
479508

480509
static void show_name(const struct object *obj,
481510
const char *caller_name,
511+
struct pretty_format *format_ctx,
482512
int always, int allow_undefined, int name_only)
483513
{
484514
const char *name;
@@ -487,7 +517,7 @@ static void show_name(const struct object *obj,
487517

488518
if (!name_only)
489519
printf("%s ", caller_name ? caller_name : oid_to_hex(oid));
490-
name = get_rev_name(obj, &buf);
520+
name = get_rev_name(obj, format_ctx, &buf);
491521
if (name)
492522
printf("%s\n", name);
493523
else if (allow_undefined)
@@ -507,7 +537,9 @@ static char const * const name_rev_usage[] = {
507537
NULL
508538
};
509539

510-
static void name_rev_line(char *p, struct name_ref_data *data)
540+
static void name_rev_line(char *p,
541+
struct name_ref_data *data,
542+
struct pretty_format *format_ctx)
511543
{
512544
struct strbuf buf = STRBUF_INIT;
513545
int counter = 0;
@@ -516,10 +548,10 @@ static void name_rev_line(char *p, struct name_ref_data *data)
516548

517549
for (p_start = p; *p; p++) {
518550
#define ishex(x) (isdigit((x)) || ((x) >= 'a' && (x) <= 'f'))
519-
if (!ishex(*p))
551+
if (!ishex(*p)) {
520552
counter = 0;
521-
else if (++counter == hexsz &&
522-
!ishex(*(p+1))) {
553+
} else if (++counter == hexsz &&
554+
!ishex(*(p + 1))) {
523555
struct object_id oid;
524556
const char *name = NULL;
525557
char c = *(p+1);
@@ -532,7 +564,7 @@ static void name_rev_line(char *p, struct name_ref_data *data)
532564
struct object *o =
533565
lookup_object(the_repository, &oid);
534566
if (o)
535-
name = get_rev_name(o, &buf);
567+
name = get_rev_name(o, format_ctx, &buf);
536568
}
537569
*(p+1) = c;
538570

@@ -567,6 +599,10 @@ int cmd_name_rev(int argc,
567599
#endif
568600
int all = 0, annotate_stdin = 0, allow_undefined = 1, always = 0, peel_tag = 0;
569601
struct name_ref_data data = { 0, 0, STRING_LIST_INIT_NODUP, STRING_LIST_INIT_NODUP };
602+
const char *format = NULL;
603+
struct rev_info format_rev = REV_INFO_INIT;
604+
struct pretty_format *format_ctx = NULL;
605+
struct pretty_format format_pp = {0};
570606
struct option opts[] = {
571607
OPT_BOOL(0, "name-only", &data.name_only, N_("print only ref-based names (no object names)")),
572608
OPT_BOOL(0, "tags", &data.tags_only, N_("only use tags to name the commits")),
@@ -584,6 +620,8 @@ int cmd_name_rev(int argc,
584620
PARSE_OPT_HIDDEN),
585621
#endif /* WITH_BREAKING_CHANGES */
586622
OPT_BOOL(0, "annotate-stdin", &annotate_stdin, N_("annotate text from stdin")),
623+
OPT_STRING(0, "format", &format, N_("format"),
624+
"pretty-print output instead"),
587625
OPT_BOOL(0, "undefined", &allow_undefined, N_("allow to print `undefined` names (default)")),
588626
OPT_BOOL(0, "always", &always,
589627
N_("show abbreviated commit object as fallback")),
@@ -606,6 +644,29 @@ int cmd_name_rev(int argc,
606644
}
607645
#endif
608646

647+
if (format) {
648+
struct pretty_print_context ctx = {0};
649+
struct userformat_want want = {0};
650+
651+
get_commit_format(format, &format_rev);
652+
ctx.rev = &format_rev;
653+
ctx.fmt = format_rev.commit_format;
654+
ctx.abbrev = format_rev.abbrev;
655+
ctx.date_mode_explicit = format_rev.date_mode_explicit;
656+
ctx.date_mode = format_rev.date_mode;
657+
ctx.color = GIT_COLOR_AUTO;
658+
format_pp.ctx = ctx;
659+
660+
userformat_find_requirements(format, &want);
661+
if (want.notes)
662+
load_display_notes(NULL);
663+
664+
format_pp.want = want;
665+
format_ctx = &format_pp;
666+
667+
data.name_only = true;
668+
}
669+
609670
if (all + annotate_stdin + !!argc > 1) {
610671
error("Specify either a list, or --all, not both!");
611672
usage_with_options(name_rev_usage, opts);
@@ -663,7 +724,7 @@ int cmd_name_rev(int argc,
663724

664725
while (strbuf_getline(&sb, stdin) != EOF) {
665726
strbuf_addch(&sb, '\n');
666-
name_rev_line(sb.buf, &data);
727+
name_rev_line(sb.buf, &data, format_ctx);
667728
}
668729
strbuf_release(&sb);
669730
} else if (all) {
@@ -674,13 +735,13 @@ int cmd_name_rev(int argc,
674735
struct object *obj = get_indexed_object(the_repository, i);
675736
if (!obj || obj->type != OBJ_COMMIT)
676737
continue;
677-
show_name(obj, NULL,
738+
show_name(obj, NULL, format_ctx,
678739
always, allow_undefined, data.name_only);
679740
}
680741
} else {
681742
int i;
682743
for (i = 0; i < revs.nr; i++)
683-
show_name(revs.objects[i].item, revs.objects[i].name,
744+
show_name(revs.objects[i].item, revs.objects[i].name, format_ctx,
684745
always, allow_undefined, data.name_only);
685746
}
686747

t/t6120-describe.sh

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,64 @@ test_expect_success 'name-rev --annotate-stdin works with commitGraph' '
658658
)
659659
'
660660

661+
test_expect_success 'name-rev --format setup' '
662+
mkdir repo-format &&
663+
git -C repo-format init &&
664+
test_commit -C repo-format first &&
665+
test_commit -C repo-format second &&
666+
test_commit -C repo-format third &&
667+
test_commit -C repo-format fourth &&
668+
test_commit -C repo-format fifth &&
669+
test_commit -C repo-format sixth &&
670+
test_commit -C repo-format seventh &&
671+
test_commit -C repo-format eighth
672+
'
673+
674+
test_expect_success 'name-rev --format=%s for argument revs' '
675+
cat >expect <<-\EOF &&
676+
eighth
677+
seventh
678+
fifth
679+
EOF
680+
git -C repo-format name-rev --format=%s \
681+
HEAD HEAD~ HEAD~3 >actual &&
682+
test_cmp expect actual
683+
'
684+
685+
test_expect_success '--name-rev --format=<pretty> --annotate-stdin from rev-list same as log' '
686+
git -C repo-format log --format=reference >expect &&
687+
test_file_not_empty expect &&
688+
git -C repo-format rev-list HEAD >list &&
689+
git -C repo-format name-rev --format=reference \
690+
--annotate-stdin <list >actual &&
691+
test_cmp expect actual
692+
'
693+
694+
test_expect_success '--name-rev --format=<pretty> --annotate-stdin with running text and tree oid' '
695+
cmit_oid=$(git -C repo-format rev-parse :/fifth) &&
696+
reference=$(git -C repo-format log -n1 --format=reference :/fifth) &&
697+
tree=$(git -C repo-format rev-parse HEAD^{tree}) &&
698+
cat >expect <<-EOF &&
699+
We thought we fixed this in ${reference}.
700+
But look at this tree: ${tree}.
701+
EOF
702+
git -C repo-format name-rev --format=reference --annotate-stdin \
703+
>actual <<-EOF &&
704+
We thought we fixed this in ${cmit_oid}.
705+
But look at this tree: ${tree}.
706+
EOF
707+
test_cmp expect actual
708+
'
709+
710+
test_expect_success '--name-rev --format=<pretty> with a note' '
711+
test_when_finished "git -C repo-format notes remove" &&
712+
git -C repo-format notes add -m"Make a note" &&
713+
printf "Make a note\n\n\n" >expect &&
714+
git -C repo-format name-rev --format="tformat:%N" \
715+
HEAD HEAD~ >actual &&
716+
test_cmp expect actual
717+
'
718+
661719
# B
662720
# o
663721
# H \

0 commit comments

Comments
 (0)