static int crlf_apply_to_odb( git_filter *self, git_buf *dest, const git_buf *source) { struct crlf_filter *filter = (struct crlf_filter *)self; assert(self && dest && source); /* Empty file? Nothing to do */ if (git_buf_len(source) == 0) return 0; /* Heuristics to see if we can skip the conversion. * Straight from Core Git. */ if (filter->attrs.crlf_action == GIT_CRLF_AUTO || filter->attrs.crlf_action == GIT_CRLF_GUESS) { git_buf_text_stats stats; /* Check heuristics for binary vs text... */ if (git_buf_text_gather_stats(&stats, source, false)) return -1; /* * We're currently not going to even try to convert stuff * that has bare CR characters. Does anybody do that crazy * stuff? */ if (stats.cr != stats.crlf) return -1; if (filter->attrs.crlf_action == GIT_CRLF_GUESS) { /* * If the file in the index has any CR in it, do not convert. * This is the new safer autocrlf handling. */ if (has_cr_in_index(self)) return -1; } if (!stats.cr) return -1; } /* Actually drop the carriage returns */ return git_buf_text_crlf_to_lf(dest, source); }
static int crlf_apply_to_workdir( struct crlf_attrs *ca, git_buf *to, const git_buf *from) { git_buf_text_stats stats; const char *workdir_ending = NULL; bool is_binary; /* Empty file? Nothing to do. */ if (git_buf_len(from) == 0) return 0; /* Determine proper line ending */ workdir_ending = line_ending(ca); if (!workdir_ending) return -1; /* only LF->CRLF conversion is supported, do nothing on LF platforms */ if (strcmp(workdir_ending, "\r\n") != 0) return GIT_PASSTHROUGH; /* If there are no LFs, or all LFs are part of a CRLF, nothing to do */ is_binary = git_buf_text_gather_stats(&stats, from, false); if (stats.lf == 0 || stats.lf == stats.crlf) return GIT_PASSTHROUGH; if (ca->crlf_action == GIT_CRLF_AUTO || ca->crlf_action == GIT_CRLF_GUESS) { /* If we have any existing CR or CRLF line endings, do nothing */ if (ca->crlf_action == GIT_CRLF_GUESS && stats.cr > 0 && stats.crlf > 0) return GIT_PASSTHROUGH; /* If we have bare CR characters, do nothing */ if (stats.cr != stats.crlf) return GIT_PASSTHROUGH; /* Don't filter binary files */ if (is_binary) return GIT_PASSTHROUGH; } return git_buf_text_lf_to_crlf(to, from); }
void test_object_blob_filter__stats(void) { int i; git_blob *blob; git_buf buf = GIT_BUF_INIT; git_buf_text_stats stats; for (i = 0; i < CRLF_NUM_TEST_OBJECTS; i++) { cl_git_pass(git_blob_lookup(&blob, g_repo, &g_crlf_oids[i])); cl_git_pass(git_blob__getbuf(&buf, blob)); git_buf_text_gather_stats(&stats, &buf, false); cl_assert_equal_i( 0, memcmp(&g_crlf_filtered_stats[i], &stats, sizeof(stats))); git_blob_free(blob); } git_buf_free(&buf); }
static int crlf_apply_to_odb( struct crlf_attrs *ca, git_buf *to, const git_buf *from, const git_filter_source *src) { /* Empty file? Nothing to do */ if (!git_buf_len(from)) return 0; /* Heuristics to see if we can skip the conversion. * Straight from Core Git. */ if (ca->crlf_action == GIT_CRLF_AUTO || ca->crlf_action == GIT_CRLF_GUESS) { git_buf_text_stats stats; /* Check heuristics for binary vs text - returns true if binary */ if (git_buf_text_gather_stats(&stats, from, false)) return GIT_PASSTHROUGH; /* If there are no CR characters to filter out, then just pass */ if (!stats.cr) return GIT_PASSTHROUGH; /* If safecrlf is enabled, sanity-check the result. */ if (stats.cr != stats.crlf || stats.lf != stats.crlf) { switch (ca->safe_crlf) { case GIT_SAFE_CRLF_FAIL: giterr_set( GITERR_FILTER, "LF would be replaced by CRLF in '%s'", git_filter_source_path(src)); return -1; case GIT_SAFE_CRLF_WARN: /* TODO: issue warning when warning API is available */; break; default: break; } } /* * We're currently not going to even try to convert stuff * that has bare CR characters. Does anybody do that crazy * stuff? */ if (stats.cr != stats.crlf) return GIT_PASSTHROUGH; if (ca->crlf_action == GIT_CRLF_GUESS) { /* * If the file in the index has any CR in it, do not convert. * This is the new safer autocrlf handling. */ if (has_cr_in_index(src)) return GIT_PASSTHROUGH; } if (!stats.cr) return GIT_PASSTHROUGH; } /* Actually drop the carriage returns */ return git_buf_text_crlf_to_lf(to, from); }