mirror of
https://git.proxmox.com/git/libgit2
synced 2025-12-29 22:08:45 +00:00
Checkout: crlf filter.
This commit is contained in:
parent
8e4aae1ae5
commit
e4bac3c469
88
src/crlf.c
88
src/crlf.c
@ -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)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user