@@ -33,6 +33,7 @@ static const char *fast_export_usage[] = {
3333static int progress ;
3434static enum { SIGNED_TAG_ABORT , VERBATIM , WARN , WARN_STRIP , STRIP } signed_tag_mode = SIGNED_TAG_ABORT ;
3535static enum { TAG_FILTERING_ABORT , DROP , REWRITE } tag_of_filtered_mode = TAG_FILTERING_ABORT ;
36+ static enum { REENCODE_ABORT , REENCODE_PLEASE , REENCODE_NEVER } reencode_mode = REENCODE_ABORT ;
3637static int fake_missing_tagger ;
3738static int use_done_feature ;
3839static int no_data ;
@@ -77,6 +78,20 @@ static int parse_opt_tag_of_filtered_mode(const struct option *opt,
7778 return 0 ;
7879}
7980
81+ static int parse_opt_reencode_mode (const struct option * opt ,
82+ const char * arg , int unset )
83+ {
84+ if (unset || !strcmp (arg , "abort" ))
85+ reencode_mode = REENCODE_ABORT ;
86+ else if (!strcmp (arg , "yes" ))
87+ reencode_mode = REENCODE_PLEASE ;
88+ else if (!strcmp (arg , "no" ))
89+ reencode_mode = REENCODE_NEVER ;
90+ else
91+ return error ("Unknown reencoding mode: %s" , arg );
92+ return 0 ;
93+ }
94+
8095static struct decoration idnums ;
8196static uint32_t last_idnum ;
8297
@@ -453,7 +468,7 @@ static const char *find_encoding(const char *begin, const char *end)
453468 bol = memmem (begin , end ? end - begin : strlen (begin ),
454469 needle , strlen (needle ));
455470 if (!bol )
456- return git_commit_encoding ;
471+ return NULL ;
457472 bol += strlen (needle );
458473 eol = strchrnul (bol , '\n' );
459474 * eol = '\0' ;
@@ -633,18 +648,32 @@ static void handle_commit(struct commit *commit, struct rev_info *rev,
633648 }
634649
635650 mark_next_object (& commit -> object );
636- if (anonymize )
651+ if (anonymize ) {
637652 reencoded = anonymize_commit_message (message );
638- else if (!is_encoding_utf8 (encoding ))
639- reencoded = reencode_string (message , "UTF-8" , encoding );
653+ } else if (encoding ) {
654+ switch (reencode_mode ) {
655+ case REENCODE_PLEASE :
656+ reencoded = reencode_string (message , "UTF-8" , encoding );
657+ break ;
658+ case REENCODE_NEVER :
659+ break ;
660+ case REENCODE_ABORT :
661+ die ("Encountered commit-specific encoding %s in commit "
662+ "%s; use --reencode=<mode> to handle it" ,
663+ encoding , oid_to_hex (& commit -> object .oid ));
664+ }
665+ }
640666 if (!commit -> parents )
641667 printf ("reset %s\n" , refname );
642668 printf ("commit %s\nmark :%" PRIu32 "\n" , refname , last_idnum );
643669 if (show_original_ids )
644670 printf ("original-oid %s\n" , oid_to_hex (& commit -> object .oid ));
645- printf ("%.*s\n%.*s\ndata %u\n%s " ,
671+ printf ("%.*s\n%.*s\n " ,
646672 (int )(author_end - author ), author ,
647- (int )(committer_end - committer ), committer ,
673+ (int )(committer_end - committer ), committer );
674+ if (!reencoded && encoding )
675+ printf ("encoding %s\n" , encoding );
676+ printf ("data %u\n%s" ,
648677 (unsigned )(reencoded
649678 ? strlen (reencoded ) : message
650679 ? strlen (message ) : 0 ),
@@ -1088,6 +1117,9 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
10881117 OPT_CALLBACK (0 , "tag-of-filtered-object" , & tag_of_filtered_mode , N_ ("mode" ),
10891118 N_ ("select handling of tags that tag filtered objects" ),
10901119 parse_opt_tag_of_filtered_mode ),
1120+ OPT_CALLBACK (0 , "reencode" , & reencode_mode , N_ ("mode" ),
1121+ N_ ("select handling of commit messages in an alternate encoding" ),
1122+ parse_opt_reencode_mode ),
10911123 OPT_STRING (0 , "export-marks" , & export_filename , N_ ("file" ),
10921124 N_ ("Dump marks to this file" )),
10931125 OPT_STRING (0 , "import-marks" , & import_filename , N_ ("file" ),
0 commit comments