@matheusbsbs / matheus-bagliano / commits / cd5522271f
Fork 0

rebase -r: let `label` generate safer labels

The `label` todo command in interactive rebases creates temporary refs in the `refs/rewritten/` namespace. These refs are stored as loose refs, i.e. as files in `.git/refs/rewritten/`, therefore they have to conform with file name limitations on the current filesystem in addition to the accepted ref format. This poses a problem in particular on NTFS/FAT, where e.g. the colon, double-quote and pipe characters are disallowed as part of a file name. Let's safeguard against this by replacing not only white-space characters by dashes, but all non-alpha-numeric ones. However, we exempt non-ASCII UTF-8 characters from that, as it should be quite possible to reflect branch names such as `↯↯↯` in refs/file names. Signed-off-by: Matthew Rogers <mattr94@gmail.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Matthew Rogers committed Nov 17, 2019 at 23:16 UTC cd5522271f6b985114b33332e148bff2283b0440
2 files changed +25 -1
sequencer.c
+19 -1
@@ -4471,8 +4471,26 @@ static const char *label_oid(struct object_id *oid, const char *label,
4471 } else {
4472 struct strbuf *buf = &state->buf;
4473
4474 + /*
4475 + * Sanitize labels by replacing non-alpha-numeric characters
4476 + * (including white-space ones) by dashes, as they might be
4477 + * illegal in file names (and hence in ref names).
4478 + *
4479 + * Note that we retain non-ASCII UTF-8 characters (identified
4480 + * via the most significant bit). They should be all acceptable
4481 + * in file names. We do not validate the UTF-8 here, that's not
4482 + * the job of this function.
4483 + */
4484 for (; *label; label++)
4475 - strbuf_addch(buf, isspace(*label) ? '-' : *label);
4485 + if ((*label & 0x80) || isalnum(*label))
4486 + strbuf_addch(buf, *label);
4487 + /* avoid leading dash and double-dashes */
4488 + else if (buf->len && buf->buf[buf->len - 1] != '-')
4489 + strbuf_addch(buf, '-');
4490 + if (!buf->len) {
4491 + strbuf_addstr(buf, "rev-");
4492 + strbuf_add_unique_abbrev(buf, oid, default_abbrev);
4493 + }
4494 label = buf->buf;
4495
4496 if ((buf->len == the_hash_algo->hexsz &&
t/t3430-rebase-merges.sh
+6
@@ -468,4 +468,10 @@ test_expect_success '--rebase-merges with strategies' '
468 test_cmp expect G.t
469 '
470
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 +
477 test_done