@@ -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 ));
0 commit comments