Skip to content

Commit d1c5ae7

Browse files
bk2204gitster
authored andcommitted
rev-list: add option for --pretty=format without header
In general, we encourage users to use plumbing commands, like git rev-list, over porcelain commands, like git log, when scripting. However, git rev-list has one glaring problem that prevents it from being used in certain cases: when --pretty is used with a custom format, it always prints out a line containing "commit" and the object ID. This makes it unsuitable for many scripting needs, and forces users to use git log instead. While we can't change this behavior for backwards compatibility, we can add an option to suppress this behavior, so let's do so, and call it "--no-commit-header". Additionally, add the corresponding positive option to switch it back on. Note that this option doesn't affect the built-in formats, only custom formats. This is exactly the same behavior as users already have from git log and is what most users will be used to. Signed-off-by: brian m. carlson <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 670b81a commit d1c5ae7

File tree

4 files changed

+112
-12
lines changed

4 files changed

+112
-12
lines changed

Documentation/rev-list-options.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,6 +1064,14 @@ ifdef::git-rev-list[]
10641064
--header::
10651065
Print the contents of the commit in raw-format; each record is
10661066
separated with a NUL character.
1067+
1068+
--no-commit-header::
1069+
Suppress the header line containing "commit" and the object ID printed before
1070+
the specified format. This has no effect on the built-in formats; only custom
1071+
formats are affected.
1072+
1073+
--commit-header::
1074+
Overrides a previous `--no-commit-header`.
10671075
endif::git-rev-list[]
10681076

10691077
--parents::

builtin/rev-list.c

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -127,13 +127,15 @@ static void show_commit(struct commit *commit, void *data)
127127
if (info->header_prefix)
128128
fputs(info->header_prefix, stdout);
129129

130-
if (!revs->graph)
131-
fputs(get_revision_mark(revs, commit), stdout);
132-
if (revs->abbrev_commit && revs->abbrev)
133-
fputs(find_unique_abbrev(&commit->object.oid, revs->abbrev),
134-
stdout);
135-
else
136-
fputs(oid_to_hex(&commit->object.oid), stdout);
130+
if (revs->include_header) {
131+
if (!revs->graph)
132+
fputs(get_revision_mark(revs, commit), stdout);
133+
if (revs->abbrev_commit && revs->abbrev)
134+
fputs(find_unique_abbrev(&commit->object.oid, revs->abbrev),
135+
stdout);
136+
else
137+
fputs(oid_to_hex(&commit->object.oid), stdout);
138+
}
137139
if (revs->print_parents) {
138140
struct commit_list *parents = commit->parents;
139141
while (parents) {
@@ -153,7 +155,7 @@ static void show_commit(struct commit *commit, void *data)
153155
show_decorations(revs, commit);
154156
if (revs->commit_format == CMIT_FMT_ONELINE)
155157
putchar(' ');
156-
else
158+
else if (revs->include_header)
157159
putchar('\n');
158160

159161
if (revs->verbose_header) {
@@ -512,6 +514,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
512514
repo_init_revisions(the_repository, &revs, prefix);
513515
revs.abbrev = DEFAULT_ABBREV;
514516
revs.commit_format = CMIT_FMT_UNSPECIFIED;
517+
revs.include_header = 1;
515518

516519
/*
517520
* Scan the argument list before invoking setup_revisions(), so that we
@@ -627,6 +630,16 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
627630
continue;
628631
}
629632

633+
if (!strcmp(arg, ("--commit-header"))) {
634+
revs.include_header = 1;
635+
continue;
636+
}
637+
638+
if (!strcmp(arg, ("--no-commit-header"))) {
639+
revs.include_header = 0;
640+
continue;
641+
}
642+
630643
if (!strcmp(arg, "--disk-usage")) {
631644
show_disk_usage = 1;
632645
info.flags |= REV_LIST_QUIET;
@@ -636,10 +649,12 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
636649
usage(rev_list_usage);
637650

638651
}
652+
if (revs.commit_format != CMIT_FMT_USERFORMAT)
653+
revs.include_header = 1;
639654
if (revs.commit_format != CMIT_FMT_UNSPECIFIED) {
640655
/* The command line has a --pretty */
641656
info.hdr_termination = '\n';
642-
if (revs.commit_format == CMIT_FMT_ONELINE)
657+
if (revs.commit_format == CMIT_FMT_ONELINE || !revs.include_header)
643658
info.header_prefix = "";
644659
else
645660
info.header_prefix = "commit ";

revision.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,8 @@ struct rev_info {
215215
missing_newline:1,
216216
date_mode_explicit:1,
217217
preserve_subject:1,
218-
encode_email_headers:1;
218+
encode_email_headers:1,
219+
include_header:1;
219220
unsigned int disable_stdin:1;
220221
/* --show-linear-break */
221222
unsigned int track_linear:1,

t/t6006-rev-list-format.sh

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,22 +41,59 @@ test_expect_success 'setup' '
4141
echo "$added_iso88591" | git commit -F - &&
4242
head1=$(git rev-parse --verify HEAD) &&
4343
head1_short=$(git rev-parse --verify --short $head1) &&
44+
head1_short4=$(git rev-parse --verify --short=4 $head1) &&
4445
tree1=$(git rev-parse --verify HEAD:) &&
4546
tree1_short=$(git rev-parse --verify --short $tree1) &&
4647
echo "$changed" > foo &&
4748
echo "$changed_iso88591" | git commit -a -F - &&
4849
head2=$(git rev-parse --verify HEAD) &&
4950
head2_short=$(git rev-parse --verify --short $head2) &&
51+
head2_short4=$(git rev-parse --verify --short=4 $head2) &&
5052
tree2=$(git rev-parse --verify HEAD:) &&
5153
tree2_short=$(git rev-parse --verify --short $tree2) &&
5254
git config --unset i18n.commitEncoding
5355
'
5456

55-
# usage: test_format name format_string [failure] <expected_output
57+
# usage: test_format [argument...] name format_string [failure] <expected_output
5658
test_format () {
59+
local args=
60+
while true
61+
do
62+
case "$1" in
63+
--*)
64+
args="$args $1"
65+
shift;;
66+
*)
67+
break;;
68+
esac
69+
done
5770
cat >expect.$1
5871
test_expect_${3:-success} "format $1" "
59-
git rev-list --pretty=format:'$2' main >output.$1 &&
72+
git rev-list $args --pretty=format:'$2' main >output.$1 &&
73+
test_cmp expect.$1 output.$1
74+
"
75+
}
76+
77+
# usage: test_pretty [argument...] name format_name [failure] <expected_output
78+
test_pretty () {
79+
local args=
80+
while true
81+
do
82+
case "$1" in
83+
--*)
84+
args="$args $1"
85+
shift;;
86+
*)
87+
break;;
88+
esac
89+
done
90+
cat >expect.$1
91+
test_expect_${3:-success} "pretty $1 (without --no-commit-header)" "
92+
git rev-list $args --pretty='$2' main >output.$1 &&
93+
test_cmp expect.$1 output.$1
94+
"
95+
test_expect_${3:-success} "pretty $1 (with --no-commit-header)" "
96+
git rev-list $args --no-commit-header --pretty='$2' main >output.$1 &&
6097
test_cmp expect.$1 output.$1
6198
"
6299
}
@@ -93,6 +130,20 @@ $head1
93130
$head1_short
94131
EOF
95132

133+
test_format --no-commit-header hash-no-header %H%n%h <<EOF
134+
$head2
135+
$head2_short
136+
$head1
137+
$head1_short
138+
EOF
139+
140+
test_format --abbrev-commit --abbrev=0 --no-commit-header hash-no-header-abbrev %H%n%h <<EOF
141+
$head2
142+
$head2_short4
143+
$head1
144+
$head1_short4
145+
EOF
146+
96147
test_format tree %T%n%t <<EOF
97148
commit $head2
98149
$tree2
@@ -181,6 +232,31 @@ $added
181232
182233
EOF
183234

235+
test_format --no-commit-header raw-body-no-header %B <<EOF
236+
$changed
237+
238+
$added
239+
240+
EOF
241+
242+
test_pretty oneline oneline <<EOF
243+
$head2 $changed
244+
$head1 $added
245+
EOF
246+
247+
test_pretty short short <<EOF
248+
commit $head2
249+
Author: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
250+
251+
$changed
252+
253+
commit $head1
254+
Author: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
255+
256+
$added
257+
258+
EOF
259+
184260
test_expect_success 'basic colors' '
185261
cat >expect <<-EOF &&
186262
commit $head2

0 commit comments

Comments
 (0)