Added function to retrieve the sha1 for a (re-)normalized cache_entry. It makes a reasonable effort at detecting conversion mode changes. Signed-off-by: Henrik Grubbström <grubba@xxxxxxxxxx> --- Note: This implementation will miss a changed custom filter. cache.h | 21 +++++++++++++++++++++ convert.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 0 deletions(-) diff --git a/cache.h b/cache.h index 1fe2d7d..536697d 100644 --- a/cache.h +++ b/cache.h @@ -151,10 +151,17 @@ struct cache_entry { unsigned int ce_size; unsigned int ce_flags; unsigned char sha1[20]; + unsigned int norm_flags; + unsigned char norm_sha1[20]; struct cache_entry *next; char name[FLEX_ARRAY]; /* more */ }; +#define NORM_CONV_CRLF 0x0001 +#define NORM_CONV_GUESS 0x0002 +#define NORM_CONV_IDENT 0x0004 +#define NORM_CONV_FILT 0x0008 + #define CE_NAMEMASK (0x0fff) #define CE_STAGEMASK (0x3000) #define CE_EXTENDED (0x4000) @@ -1014,6 +1021,7 @@ extern void trace_argv_printf(const char **argv, const char *format, ...); /* convert.c */ /* returns 1 if *dst was used */ +extern unsigned int git_norm_flags(const char *path); extern int convert_to_git(const char *path, const char *src, size_t len, struct strbuf *dst, enum safe_crlf checksafe); extern int convert_to_working_tree(const char *path, const char *src, size_t len, struct strbuf *dst); @@ -1062,4 +1070,17 @@ int split_cmdline(char *cmdline, const char ***argv); /* builtin/merge.c */ int checkout_fast_forward(const unsigned char *from, const unsigned char *to); +static inline unsigned char *ce_norm_sha1(struct cache_entry *ce) +{ + unsigned int norm_flags = git_norm_flags(ce->name); + + if (!norm_flags) + return ce->sha1; + if (norm_flags == ce->norm_flags) + return ce->norm_sha1; + index_blob(ce->norm_sha1, ce->sha1, 1, ce->name); + ce->norm_flags = norm_flags; + return ce->norm_sha1; +} + #endif /* CACHE_H */ diff --git a/convert.c b/convert.c index 4f8fcb7..6378ef5 100644 --- a/convert.c +++ b/convert.c @@ -568,6 +568,41 @@ static int git_path_check_ident(const char *path, struct git_attr_check *check) return !!ATTR_TRUE(value); } +unsigned int git_norm_flags(const char *path) +{ + struct git_attr_check check[3]; + int crlf = CRLF_GUESS; + int ident = 0; + unsigned ret = 0; + struct convert_driver *drv = NULL; + + setup_convert_check(check); + if (!git_checkattr(path, ARRAY_SIZE(check), check)) { + crlf = git_path_check_crlf(path, check + 0); + ident = git_path_check_ident(path, check + 1); + drv = git_path_check_convert(path, check + 2); + } + + switch(crlf) { + case CRLF_INPUT: + case CRLF_TEXT: + ret |= NORM_CONV_CRLF; + break; + case CRLF_GUESS: + ret |= NORM_CONV_GUESS; + break; + case CRLF_BINARY: + break; + } + if (ident) { + ret |= NORM_CONV_IDENT; + } + if (drv) { + ret |= NORM_CONV_FILT; + } + return ret; +} + int convert_to_git(const char *path, const char *src, size_t len, struct strbuf *dst, enum safe_crlf checksafe) { -- 1.7.0.4.369.g81e89 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html