Skip to content

Commit bb7e150

Browse files
committed
Merge branch 'js/rebase-r-safer-label' into jch
A label used in the todo list that are generated by "git rebase --rebase-merges" is used as a part of a refname; the logic to come up with the label has been tightened to avoid names that cannot be used as such. * js/rebase-r-safer-label: rebase -r: let `label` generate safer labels rebase-merges: move labels' whitespace mangling into `label_oid()`
2 parents 2a38637 + cd55222 commit bb7e150

File tree

2 files changed

+51
-27
lines changed

2 files changed

+51
-27
lines changed

sequencer.c

Lines changed: 45 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4437,7 +4437,6 @@ static const char *label_oid(struct object_id *oid, const char *label,
44374437
struct labels_entry *labels_entry;
44384438
struct string_entry *string_entry;
44394439
struct object_id dummy;
4440-
size_t len;
44414440
int i;
44424441

44434442
string_entry = oidmap_get(&state->commit2label, oid);
@@ -4457,10 +4456,10 @@ static const char *label_oid(struct object_id *oid, const char *label,
44574456
* abbreviation for any uninteresting commit's names that does not
44584457
* clash with any other label.
44594458
*/
4459+
strbuf_reset(&state->buf);
44604460
if (!label) {
44614461
char *p;
44624462

4463-
strbuf_reset(&state->buf);
44644463
strbuf_grow(&state->buf, GIT_MAX_HEXSZ);
44654464
label = p = state->buf.buf;
44664465

@@ -4483,32 +4482,55 @@ static const char *label_oid(struct object_id *oid, const char *label,
44834482
p[i] = save;
44844483
}
44854484
}
4486-
} else if (((len = strlen(label)) == the_hash_algo->hexsz &&
4487-
!get_oid_hex(label, &dummy)) ||
4488-
(len == 1 && *label == '#') ||
4489-
hashmap_get_from_hash(&state->labels,
4490-
strihash(label), label)) {
4485+
} else {
4486+
struct strbuf *buf = &state->buf;
4487+
44914488
/*
4492-
* If the label already exists, or if the label is a valid full
4493-
* OID, or the label is a '#' (which we use as a separator
4494-
* between merge heads and oneline), we append a dash and a
4495-
* number to make it unique.
4489+
* Sanitize labels by replacing non-alpha-numeric characters
4490+
* (including white-space ones) by dashes, as they might be
4491+
* illegal in file names (and hence in ref names).
4492+
*
4493+
* Note that we retain non-ASCII UTF-8 characters (identified
4494+
* via the most significant bit). They should be all acceptable
4495+
* in file names. We do not validate the UTF-8 here, that's not
4496+
* the job of this function.
44964497
*/
4497-
struct strbuf *buf = &state->buf;
4498+
for (; *label; label++)
4499+
if ((*label & 0x80) || isalnum(*label))
4500+
strbuf_addch(buf, *label);
4501+
/* avoid leading dash and double-dashes */
4502+
else if (buf->len && buf->buf[buf->len - 1] != '-')
4503+
strbuf_addch(buf, '-');
4504+
if (!buf->len) {
4505+
strbuf_addstr(buf, "rev-");
4506+
strbuf_add_unique_abbrev(buf, oid, default_abbrev);
4507+
}
4508+
label = buf->buf;
44984509

4499-
strbuf_reset(buf);
4500-
strbuf_add(buf, label, len);
4510+
if ((buf->len == the_hash_algo->hexsz &&
4511+
!get_oid_hex(label, &dummy)) ||
4512+
(buf->len == 1 && *label == '#') ||
4513+
hashmap_get_from_hash(&state->labels,
4514+
strihash(label), label)) {
4515+
/*
4516+
* If the label already exists, or if the label is a
4517+
* valid full OID, or the label is a '#' (which we use
4518+
* as a separator between merge heads and oneline), we
4519+
* append a dash and a number to make it unique.
4520+
*/
4521+
size_t len = buf->len;
45014522

4502-
for (i = 2; ; i++) {
4503-
strbuf_setlen(buf, len);
4504-
strbuf_addf(buf, "-%d", i);
4505-
if (!hashmap_get_from_hash(&state->labels,
4506-
strihash(buf->buf),
4507-
buf->buf))
4508-
break;
4509-
}
4523+
for (i = 2; ; i++) {
4524+
strbuf_setlen(buf, len);
4525+
strbuf_addf(buf, "-%d", i);
4526+
if (!hashmap_get_from_hash(&state->labels,
4527+
strihash(buf->buf),
4528+
buf->buf))
4529+
break;
4530+
}
45104531

4511-
label = buf->buf;
4532+
label = buf->buf;
4533+
}
45124534
}
45134535

45144536
FLEX_ALLOC_STR(labels_entry, label, label);
@@ -4610,10 +4632,6 @@ static int make_script_with_merges(struct pretty_print_context *pp,
46104632
else
46114633
strbuf_addbuf(&label, &oneline);
46124634

4613-
for (p1 = label.buf; *p1; p1++)
4614-
if (isspace(*p1))
4615-
*(char *)p1 = '-';
4616-
46174635
strbuf_reset(&buf);
46184636
strbuf_addf(&buf, "%s -C %s",
46194637
cmd_merge, oid_to_hex(&commit->object.oid));

t/t3430-rebase-merges.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,4 +468,10 @@ test_expect_success '--rebase-merges with strategies' '
468468
test_cmp expect G.t
469469
'
470470

471+
test_expect_success '--rebase-merges with commit that can generate bad characters for filename' '
472+
git checkout -b colon-in-label E &&
473+
git merge -m "colon: this should work" G &&
474+
git rebase --rebase-merges --force-rebase E
475+
'
476+
471477
test_done

0 commit comments

Comments
 (0)