static int find_and_add_filter( git_vector *filters, git_repository *repo, const char *path, int (*apply)(struct git_filter *self, git_buf *dest, const git_buf *source)) { struct crlf_attrs ca; struct crlf_filter *filter; size_t pathlen; int error; /* Load gitattributes for the path */ if ((error = crlf_load_attributes(&ca, repo, path)) < 0) return error; /* * Use the core Git logic to see if we should perform CRLF for this file * based on its attributes & the value of `core.autocrlf` */ ca.crlf_action = crlf_input_action(&ca); if (ca.crlf_action == GIT_CRLF_BINARY) return 0; if (ca.crlf_action == GIT_CRLF_GUESS) { int auto_crlf; if ((error = git_repository__cvar(&auto_crlf, repo, GIT_CVAR_AUTO_CRLF)) < 0) return error; if (auto_crlf == GIT_AUTO_CRLF_FALSE) return 0; } /* If we're good, we create a new filter object and push it * into the filters array */ pathlen = strlen(path); filter = git__malloc(sizeof(struct crlf_filter) + pathlen + 1); GITERR_CHECK_ALLOC(filter); filter->f.apply = apply; filter->f.do_free = NULL; memcpy(&filter->attrs, &ca, sizeof(struct crlf_attrs)); filter->repo = repo; memcpy(filter->path, path, pathlen + 1); return git_vector_insert(filters, filter); }
static int crlf_check( git_filter *self, void **payload, /* points to NULL ptr on entry, may be set */ const git_filter_source *src, const char **attr_values) { int error; struct crlf_attrs ca; GIT_UNUSED(self); if (!attr_values) { ca.crlf_action = GIT_CRLF_GUESS; ca.eol = GIT_EOL_UNSET; } else { ca.crlf_action = check_crlf(attr_values[2]); /* text */ if (ca.crlf_action == GIT_CRLF_GUESS) ca.crlf_action = check_crlf(attr_values[0]); /* clrf */ ca.eol = check_eol(attr_values[1]); /* eol */ } ca.auto_crlf = GIT_AUTO_CRLF_DEFAULT; /* * Use the core Git logic to see if we should perform CRLF for this file * based on its attributes & the value of `core.autocrlf` */ ca.crlf_action = crlf_input_action(&ca); if (ca.crlf_action == GIT_CRLF_BINARY) return GIT_PASSTHROUGH; if (ca.crlf_action == GIT_CRLF_GUESS || (ca.crlf_action == GIT_CRLF_AUTO && git_filter_source_mode(src) == GIT_FILTER_SMUDGE)) { error = git_repository__cvar( &ca.auto_crlf, git_filter_source_repo(src), GIT_CVAR_AUTO_CRLF); if (error < 0) return error; if (ca.auto_crlf == GIT_AUTO_CRLF_FALSE) return GIT_PASSTHROUGH; if (ca.auto_crlf == GIT_AUTO_CRLF_INPUT && git_filter_source_mode(src) == GIT_FILTER_SMUDGE) return GIT_PASSTHROUGH; } if (git_filter_source_mode(src) == GIT_FILTER_CLEAN) { error = git_repository__cvar( &ca.safe_crlf, git_filter_source_repo(src), GIT_CVAR_SAFE_CRLF); if (error < 0) return error; /* downgrade FAIL to WARN if ALLOW_UNSAFE option is used */ if ((git_filter_source_options(src) & GIT_FILTER_OPT_ALLOW_UNSAFE) && ca.safe_crlf == GIT_SAFE_CRLF_FAIL) ca.safe_crlf = GIT_SAFE_CRLF_WARN; } *payload = git__malloc(sizeof(ca)); GITERR_CHECK_ALLOC(*payload); memcpy(*payload, &ca, sizeof(ca)); return 0; }