Skip to content

Commit 917d0d6

Browse files
committed
Merge branch 'js/rebase-r-safer-label'
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 56d3ce8 + cd55222 commit 917d0d6

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
@@ -4430,7 +4430,6 @@ static const char *label_oid(struct object_id *oid, const char *label,
44304430
struct labels_entry *labels_entry;
44314431
struct string_entry *string_entry;
44324432
struct object_id dummy;
4433-
size_t len;
44344433
int i;
44354434

44364435
string_entry = oidmap_get(&state->commit2label, oid);
@@ -4450,10 +4449,10 @@ static const char *label_oid(struct object_id *oid, const char *label,
44504449
* abbreviation for any uninteresting commit's names that does not
44514450
* clash with any other label.
44524451
*/
4452+
strbuf_reset(&state->buf);
44534453
if (!label) {
44544454
char *p;
44554455

4456-
strbuf_reset(&state->buf);
44574456
strbuf_grow(&state->buf, GIT_MAX_HEXSZ);
44584457
label = p = state->buf.buf;
44594458

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

4492-
strbuf_reset(buf);
4493-
strbuf_add(buf, label, len);
4503+
if ((buf->len == the_hash_algo->hexsz &&
4504+
!get_oid_hex(label, &dummy)) ||
4505+
(buf->len == 1 && *label == '#') ||
4506+
hashmap_get_from_hash(&state->labels,
4507+
strihash(label), label)) {
4508+
/*
4509+
* If the label already exists, or if the label is a
4510+
* valid full OID, or the label is a '#' (which we use
4511+
* as a separator between merge heads and oneline), we
4512+
* append a dash and a number to make it unique.
4513+
*/
4514+
size_t len = buf->len;
44944515

4495-
for (i = 2; ; i++) {
4496-
strbuf_setlen(buf, len);
4497-
strbuf_addf(buf, "-%d", i);
4498-
if (!hashmap_get_from_hash(&state->labels,
4499-
strihash(buf->buf),
4500-
buf->buf))
4501-
break;
4502-
}
4516+
for (i = 2; ; i++) {
4517+
strbuf_setlen(buf, len);
4518+
strbuf_addf(buf, "-%d", i);
4519+
if (!hashmap_get_from_hash(&state->labels,
4520+
strihash(buf->buf),
4521+
buf->buf))
4522+
break;
4523+
}
45034524

4504-
label = buf->buf;
4525+
label = buf->buf;
4526+
}
45054527
}
45064528

45074529
FLEX_ALLOC_STR(labels_entry, label, label);
@@ -4603,10 +4625,6 @@ static int make_script_with_merges(struct pretty_print_context *pp,
46034625
else
46044626
strbuf_addbuf(&label, &oneline);
46054627

4606-
for (p1 = label.buf; *p1; p1++)
4607-
if (isspace(*p1))
4608-
*(char *)p1 = '-';
4609-
46104628
strbuf_reset(&buf);
46114629
strbuf_addf(&buf, "%s -C %s",
46124630
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)