@@ -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_YES , REENCODE_NO } reencode_mode = REENCODE_ABORT ;
3637static int fake_missing_tagger ;
3738static int use_done_feature ;
3839static int no_data ;
@@ -77,6 +78,31 @@ 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 ) {
85+ reencode_mode = REENCODE_ABORT ;
86+ return 0 ;
87+ }
88+
89+ switch (git_parse_maybe_bool (arg )) {
90+ case 0 :
91+ reencode_mode = REENCODE_NO ;
92+ break ;
93+ case 1 :
94+ reencode_mode = REENCODE_YES ;
95+ break ;
96+ default :
97+ if (!strcasecmp (arg , "abort" ))
98+ reencode_mode = REENCODE_ABORT ;
99+ else
100+ return error ("Unknown reencoding mode: %s" , arg );
101+ }
102+
103+ return 0 ;
104+ }
105+
80106static struct decoration idnums ;
81107static uint32_t last_idnum ;
82108
@@ -453,7 +479,7 @@ static const char *find_encoding(const char *begin, const char *end)
453479 bol = memmem (begin , end ? end - begin : strlen (begin ),
454480 needle , strlen (needle ));
455481 if (!bol )
456- return git_commit_encoding ;
482+ return NULL ;
457483 bol += strlen (needle );
458484 eol = strchrnul (bol , '\n' );
459485 * eol = '\0' ;
@@ -633,18 +659,32 @@ static void handle_commit(struct commit *commit, struct rev_info *rev,
633659 }
634660
635661 mark_next_object (& commit -> object );
636- if (anonymize )
662+ if (anonymize ) {
637663 reencoded = anonymize_commit_message (message );
638- else if (!is_encoding_utf8 (encoding ))
639- reencoded = reencode_string (message , "UTF-8" , encoding );
664+ } else if (encoding ) {
665+ switch (reencode_mode ) {
666+ case REENCODE_YES :
667+ reencoded = reencode_string (message , "UTF-8" , encoding );
668+ break ;
669+ case REENCODE_NO :
670+ break ;
671+ case REENCODE_ABORT :
672+ die ("Encountered commit-specific encoding %s in commit "
673+ "%s; use --reencode=[yes|no] to handle it" ,
674+ encoding , oid_to_hex (& commit -> object .oid ));
675+ }
676+ }
640677 if (!commit -> parents )
641678 printf ("reset %s\n" , refname );
642679 printf ("commit %s\nmark :%" PRIu32 "\n" , refname , last_idnum );
643680 if (show_original_ids )
644681 printf ("original-oid %s\n" , oid_to_hex (& commit -> object .oid ));
645- printf ("%.*s\n%.*s\ndata %u\n%s " ,
682+ printf ("%.*s\n%.*s\n " ,
646683 (int )(author_end - author ), author ,
647- (int )(committer_end - committer ), committer ,
684+ (int )(committer_end - committer ), committer );
685+ if (!reencoded && encoding )
686+ printf ("encoding %s\n" , encoding );
687+ printf ("data %u\n%s" ,
648688 (unsigned )(reencoded
649689 ? strlen (reencoded ) : message
650690 ? strlen (message ) : 0 ),
@@ -1088,6 +1128,9 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
10881128 OPT_CALLBACK (0 , "tag-of-filtered-object" , & tag_of_filtered_mode , N_ ("mode" ),
10891129 N_ ("select handling of tags that tag filtered objects" ),
10901130 parse_opt_tag_of_filtered_mode ),
1131+ OPT_CALLBACK (0 , "reencode" , & reencode_mode , N_ ("mode" ),
1132+ N_ ("select handling of commit messages in an alternate encoding" ),
1133+ parse_opt_reencode_mode ),
10911134 OPT_STRING (0 , "export-marks" , & export_filename , N_ ("file" ),
10921135 N_ ("Dump marks to this file" )),
10931136 OPT_STRING (0 , "import-marks" , & import_filename , N_ ("file" ),
0 commit comments