@@ -442,7 +442,7 @@ static int filter_buffer_or_fd(int in, int out, void *data)
442442 return (write_err || status );
443443}
444444
445- static int apply_filter (const char * path , const char * src , size_t len , int fd ,
445+ static int apply_single_file_filter (const char * path , const char * src , size_t len , int fd ,
446446 struct strbuf * dst , const char * cmd )
447447{
448448 /*
@@ -456,12 +456,6 @@ static int apply_filter(const char *path, const char *src, size_t len, int fd,
456456 struct async async ;
457457 struct filter_params params ;
458458
459- if (!cmd || !* cmd )
460- return 0 ;
461-
462- if (!dst )
463- return 1 ;
464-
465459 memset (& async , 0 , sizeof (async ));
466460 async .proc = filter_buffer_or_fd ;
467461 async .data = & params ;
@@ -493,6 +487,9 @@ static int apply_filter(const char *path, const char *src, size_t len, int fd,
493487 return !err ;
494488}
495489
490+ #define CAP_CLEAN (1u<<0)
491+ #define CAP_SMUDGE (1u<<1)
492+
496493static struct convert_driver {
497494 const char * name ;
498495 struct convert_driver * next ;
@@ -501,6 +498,29 @@ static struct convert_driver {
501498 int required ;
502499} * user_convert , * * user_convert_tail ;
503500
501+ static int apply_filter (const char * path , const char * src , size_t len ,
502+ int fd , struct strbuf * dst , struct convert_driver * drv ,
503+ const unsigned int wanted_capability )
504+ {
505+ const char * cmd = NULL ;
506+
507+ if (!drv )
508+ return 0 ;
509+
510+ if (!dst )
511+ return 1 ;
512+
513+ if ((CAP_CLEAN & wanted_capability ) && drv -> clean )
514+ cmd = drv -> clean ;
515+ else if ((CAP_SMUDGE & wanted_capability ) && drv -> smudge )
516+ cmd = drv -> smudge ;
517+
518+ if (cmd && * cmd )
519+ return apply_single_file_filter (path , src , len , fd , dst , cmd );
520+
521+ return 0 ;
522+ }
523+
504524static int read_convert_config (const char * var , const char * value , void * cb )
505525{
506526 const char * key , * name ;
@@ -839,7 +859,7 @@ int would_convert_to_git_filter_fd(const char *path)
839859 if (!ca .drv -> required )
840860 return 0 ;
841861
842- return apply_filter (path , NULL , 0 , -1 , NULL , ca .drv -> clean );
862+ return apply_filter (path , NULL , 0 , -1 , NULL , ca .drv , CAP_CLEAN );
843863}
844864
845865const char * get_convert_attr_ascii (const char * path )
@@ -872,18 +892,12 @@ int convert_to_git(const char *path, const char *src, size_t len,
872892 struct strbuf * dst , enum safe_crlf checksafe )
873893{
874894 int ret = 0 ;
875- const char * filter = NULL ;
876- int required = 0 ;
877895 struct conv_attrs ca ;
878896
879897 convert_attrs (& ca , path );
880- if (ca .drv ) {
881- filter = ca .drv -> clean ;
882- required = ca .drv -> required ;
883- }
884898
885- ret |= apply_filter (path , src , len , -1 , dst , filter );
886- if (!ret && required )
899+ ret |= apply_filter (path , src , len , -1 , dst , ca . drv , CAP_CLEAN );
900+ if (!ret && ca . drv && ca . drv -> required )
887901 die ("%s: clean filter '%s' failed" , path , ca .drv -> name );
888902
889903 if (ret && dst ) {
@@ -907,7 +921,7 @@ void convert_to_git_filter_fd(const char *path, int fd, struct strbuf *dst,
907921 assert (ca .drv );
908922 assert (ca .drv -> clean );
909923
910- if (!apply_filter (path , NULL , 0 , fd , dst , ca .drv -> clean ))
924+ if (!apply_filter (path , NULL , 0 , fd , dst , ca .drv , CAP_CLEAN ))
911925 die ("%s: clean filter '%s' failed" , path , ca .drv -> name );
912926
913927 crlf_to_git (path , dst -> buf , dst -> len , dst , ca .crlf_action , checksafe );
@@ -919,15 +933,9 @@ static int convert_to_working_tree_internal(const char *path, const char *src,
919933 int normalizing )
920934{
921935 int ret = 0 , ret_filter = 0 ;
922- const char * filter = NULL ;
923- int required = 0 ;
924936 struct conv_attrs ca ;
925937
926938 convert_attrs (& ca , path );
927- if (ca .drv ) {
928- filter = ca .drv -> smudge ;
929- required = ca .drv -> required ;
930- }
931939
932940 ret |= ident_to_worktree (path , src , len , dst , ca .ident );
933941 if (ret ) {
@@ -938,16 +946,16 @@ static int convert_to_working_tree_internal(const char *path, const char *src,
938946 * CRLF conversion can be skipped if normalizing, unless there
939947 * is a smudge filter. The filter might expect CRLFs.
940948 */
941- if (filter || !normalizing ) {
949+ if (( ca . drv && ca . drv -> smudge ) || !normalizing ) {
942950 ret |= crlf_to_worktree (path , src , len , dst , ca .crlf_action );
943951 if (ret ) {
944952 src = dst -> buf ;
945953 len = dst -> len ;
946954 }
947955 }
948956
949- ret_filter = apply_filter (path , src , len , -1 , dst , filter );
950- if (!ret_filter && required )
957+ ret_filter = apply_filter (path , src , len , -1 , dst , ca . drv , CAP_SMUDGE );
958+ if (!ret_filter && ca . drv && ca . drv -> required )
951959 die ("%s: smudge filter %s failed" , path , ca .drv -> name );
952960
953961 return ret | ret_filter ;
0 commit comments