@@ -30,6 +30,7 @@ static int fake_missing_tagger;
3030static int use_done_feature ;
3131static int no_data ;
3232static int full_tree ;
33+ static struct string_list extra_refs = STRING_LIST_INIT_NODUP ;
3334
3435static int parse_opt_signed_tag_mode (const struct option * opt ,
3536 const char * arg , int unset )
@@ -484,10 +485,32 @@ static void handle_tag(const char *name, struct tag *tag)
484485 (int )message_size , (int )message_size , message ? message : "" );
485486}
486487
487- static void get_tags_and_duplicates (struct rev_cmdline_info * info ,
488- struct string_list * extra_refs )
488+ static struct commit * get_commit (struct rev_cmdline_entry * e , char * full_name )
489+ {
490+ switch (e -> item -> type ) {
491+ case OBJ_COMMIT :
492+ return (struct commit * )e -> item ;
493+ case OBJ_TAG : {
494+ struct tag * tag = (struct tag * )e -> item ;
495+
496+ /* handle nested tags */
497+ while (tag && tag -> object .type == OBJ_TAG ) {
498+ parse_object (tag -> object .sha1 );
499+ string_list_append (& extra_refs , full_name )-> util = tag ;
500+ tag = (struct tag * )tag -> tagged ;
501+ }
502+ if (!tag )
503+ die ("Tag %s points nowhere?" , e -> name );
504+ return (struct commit * )tag ;
505+ break ;
506+ }
507+ default :
508+ return NULL ;
509+ }
510+ }
511+
512+ static void get_tags_and_duplicates (struct rev_cmdline_info * info )
489513{
490- struct tag * tag ;
491514 int i ;
492515
493516 for (i = 0 ; i < info -> nr ; i ++ ) {
@@ -502,60 +525,45 @@ static void get_tags_and_duplicates(struct rev_cmdline_info *info,
502525 if (dwim_ref (e -> name , strlen (e -> name ), sha1 , & full_name ) != 1 )
503526 continue ;
504527
505- switch (e -> item -> type ) {
506- case OBJ_COMMIT :
507- commit = (struct commit * )e -> item ;
508- break ;
509- case OBJ_TAG :
510- tag = (struct tag * )e -> item ;
511-
512- /* handle nested tags */
513- while (tag && tag -> object .type == OBJ_TAG ) {
514- parse_object (tag -> object .sha1 );
515- string_list_append (extra_refs , full_name )-> util = tag ;
516- tag = (struct tag * )tag -> tagged ;
517- }
518- if (!tag )
519- die ("Tag %s points nowhere?" , e -> name );
520- switch (tag -> object .type ) {
521- case OBJ_COMMIT :
522- commit = (struct commit * )tag ;
523- break ;
524- case OBJ_BLOB :
525- export_blob (tag -> object .sha1 );
526- continue ;
527- default : /* OBJ_TAG (nested tags) is already handled */
528- warning ("Tag points to object of unexpected type %s, skipping." ,
529- typename (tag -> object .type ));
530- continue ;
531- }
532- break ;
533- default :
528+ commit = get_commit (e , full_name );
529+ if (!commit ) {
534530 warning ("%s: Unexpected object of type %s, skipping." ,
535531 e -> name ,
536532 typename (e -> item -> type ));
537533 continue ;
538534 }
539535
536+ switch (commit -> object .type ) {
537+ case OBJ_COMMIT :
538+ break ;
539+ case OBJ_BLOB :
540+ export_blob (commit -> object .sha1 );
541+ continue ;
542+ default : /* OBJ_TAG (nested tags) is already handled */
543+ warning ("Tag points to object of unexpected type %s, skipping." ,
544+ typename (commit -> object .type ));
545+ continue ;
546+ }
547+
540548 /*
541549 * This ref will not be updated through a commit, lets make
542550 * sure it gets properly updated eventually.
543551 */
544552 if (commit -> util || commit -> object .flags & SHOWN )
545- string_list_append (extra_refs , full_name )-> util = commit ;
553+ string_list_append (& extra_refs , full_name )-> util = commit ;
546554 if (!commit -> util )
547555 commit -> util = full_name ;
548556 }
549557}
550558
551- static void handle_tags_and_duplicates (struct string_list * extra_refs )
559+ static void handle_tags_and_duplicates (void )
552560{
553561 struct commit * commit ;
554562 int i ;
555563
556- for (i = extra_refs -> nr - 1 ; i >= 0 ; i -- ) {
557- const char * name = extra_refs -> items [i ].string ;
558- struct object * object = extra_refs -> items [i ].util ;
564+ for (i = extra_refs . nr - 1 ; i >= 0 ; i -- ) {
565+ const char * name = extra_refs . items [i ].string ;
566+ struct object * object = extra_refs . items [i ].util ;
559567 switch (object -> type ) {
560568 case OBJ_TAG :
561569 handle_tag (name , (struct tag * )object );
@@ -657,7 +665,6 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
657665{
658666 struct rev_info revs ;
659667 struct object_array commits = OBJECT_ARRAY_INIT ;
660- struct string_list extra_refs = STRING_LIST_INIT_NODUP ;
661668 struct commit * commit ;
662669 char * export_filename = NULL , * import_filename = NULL ;
663670 uint32_t lastimportid ;
@@ -709,7 +716,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
709716 if (import_filename && revs .prune_data .nr )
710717 full_tree = 1 ;
711718
712- get_tags_and_duplicates (& revs .cmdline , & extra_refs );
719+ get_tags_and_duplicates (& revs .cmdline );
713720
714721 if (prepare_revision_walk (& revs ))
715722 die ("revision walk setup failed" );
@@ -725,7 +732,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
725732 }
726733 }
727734
728- handle_tags_and_duplicates (& extra_refs );
735+ handle_tags_and_duplicates ();
729736
730737 if (export_filename && lastimportid != last_idnum )
731738 export_marks (export_filename );
0 commit comments