Commit e4bac3c4 by Ben Straub

Checkout: crlf filter.

parent 8e4aae1a
......@@ -184,6 +184,85 @@ static int crlf_apply_to_odb(git_filter *self, git_buf *dest, const git_buf *sou
return drop_crlf(dest, source);
}
static int convert_line_endings(git_buf *dest, const git_buf *source, const char *ending)
{
const char *scan = git_buf_cstr(source),
*next,
*scan_end = git_buf_cstr(source) + git_buf_len(source);
while ((next = memchr(scan, '\n', scan_end - scan)) != NULL) {
if (next > scan)
git_buf_put(dest, scan, next-scan);
git_buf_puts(dest, ending);
scan = next + 1;
}
git_buf_put(dest, scan, scan_end - scan);
return 0;
}
static const char *line_ending(struct crlf_filter *filter)
{
switch (filter->attrs.crlf_action) {
case GIT_CRLF_BINARY:
case GIT_CRLF_INPUT:
return "\n";
case GIT_CRLF_CRLF:
return "\r\n";
case GIT_CRLF_AUTO:
case GIT_CRLF_TEXT:
case GIT_CRLF_GUESS:
break;
default:
goto line_ending_error;
}
switch (filter->attrs.eol) {
case GIT_EOL_UNSET:
return GIT_EOL_NATIVE == GIT_EOL_CRLF
? "\r\n"
: "\n";
case GIT_EOL_CRLF:
return "\r\n";
case GIT_EOL_LF:
return "\n";
default:
goto line_ending_error;
}
line_ending_error:
giterr_set(GITERR_INVALID, "Invalid input to line ending filter");
return NULL;
}
static int crlf_apply_to_workdir(git_filter *self, git_buf *dest, const git_buf *source)
{
struct crlf_filter *filter = (struct crlf_filter *)self;
const char *workdir_ending = NULL;
assert (self && dest && source);
/* Empty file? Nothing to do. */
if (git_buf_len(source) == 0)
return 0;
/* Determine proper line ending */
workdir_ending = line_ending(filter);
if (!workdir_ending) return -1;
/* If the line ending is '\n', just copy the input */
if (!strcmp(workdir_ending, "\n"))
return git_buf_puts(dest, git_buf_cstr(source));
return convert_line_endings(dest, source, workdir_ending);
}
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))
{
......@@ -207,8 +286,7 @@ static int find_and_add_filter(git_vector *filters, git_repository *repo, const
if (ca.crlf_action == GIT_CRLF_GUESS) {
int auto_crlf;
if ((error = git_repository__cvar(
&auto_crlf, repo, GIT_CVAR_AUTO_CRLF)) < 0)
if ((error = git_repository__cvar(&auto_crlf, repo, GIT_CVAR_AUTO_CRLF)) < 0)
return error;
if (auto_crlf == GIT_AUTO_CRLF_FALSE)
......@@ -227,12 +305,6 @@ static int find_and_add_filter(git_vector *filters, git_repository *repo, const
return git_vector_insert(filters, filter);
}
static int crlf_apply_to_workdir(git_filter *self, git_buf *dest, const git_buf *source)
{
/* TODO */
return -1;
}
int git_filter_add__crlf_to_odb(git_vector *filters, git_repository *repo, const char *path)
{
return find_and_add_filter(filters, repo, path, &crlf_apply_to_odb);
......
......@@ -58,15 +58,9 @@ void test_checkout_checkout__crlf(void)
"new.txt text eol=lf\n";
cl_git_mkfile("./testrepo/.gitattributes", attributes);
cl_git_pass(git_checkout_head(g_repo, NULL, NULL));
/* TODO: enable these when crlf is ready */
/* test_file_contents("./testrepo/README", "hey there\n"); */
/* test_file_contents("./testrepo/new.txt", "my new file\n"); */
/* test_file_contents("./testrepo/branch_file.txt", "hi\r\nbye!\r\n"); */
}
void test_checkout_checkout__stats(void)
{
/* TODO */
test_file_contents("./testrepo/README", "hey there\n");
test_file_contents("./testrepo/new.txt", "my new file\n");
test_file_contents("./testrepo/branch_file.txt", "hi\r\nbye!\r\n");
}
static void enable_symlinks(bool enable)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment