зеркало из https://github.com/microsoft/git.git
convert: prepare filter.<driver>.process option
Refactor the existing 'single shot filter mechanism' and prepare the new 'long running filter mechanism'. Signed-off-by: Lars Schneider <larsxschneider@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Родитель
b84be55354
Коммит
234fa07e06
60
convert.c
60
convert.c
|
@ -442,7 +442,7 @@ static int filter_buffer_or_fd(int in, int out, void *data)
|
|||
return (write_err || status);
|
||||
}
|
||||
|
||||
static int apply_filter(const char *path, const char *src, size_t len, int fd,
|
||||
static int apply_single_file_filter(const char *path, const char *src, size_t len, int fd,
|
||||
struct strbuf *dst, const char *cmd)
|
||||
{
|
||||
/*
|
||||
|
@ -456,12 +456,6 @@ static int apply_filter(const char *path, const char *src, size_t len, int fd,
|
|||
struct async async;
|
||||
struct filter_params params;
|
||||
|
||||
if (!cmd || !*cmd)
|
||||
return 0;
|
||||
|
||||
if (!dst)
|
||||
return 1;
|
||||
|
||||
memset(&async, 0, sizeof(async));
|
||||
async.proc = filter_buffer_or_fd;
|
||||
async.data = ¶ms;
|
||||
|
@ -493,6 +487,9 @@ static int apply_filter(const char *path, const char *src, size_t len, int fd,
|
|||
return !err;
|
||||
}
|
||||
|
||||
#define CAP_CLEAN (1u<<0)
|
||||
#define CAP_SMUDGE (1u<<1)
|
||||
|
||||
static struct convert_driver {
|
||||
const char *name;
|
||||
struct convert_driver *next;
|
||||
|
@ -501,6 +498,29 @@ static struct convert_driver {
|
|||
int required;
|
||||
} *user_convert, **user_convert_tail;
|
||||
|
||||
static int apply_filter(const char *path, const char *src, size_t len,
|
||||
int fd, struct strbuf *dst, struct convert_driver *drv,
|
||||
const unsigned int wanted_capability)
|
||||
{
|
||||
const char *cmd = NULL;
|
||||
|
||||
if (!drv)
|
||||
return 0;
|
||||
|
||||
if (!dst)
|
||||
return 1;
|
||||
|
||||
if ((CAP_CLEAN & wanted_capability) && drv->clean)
|
||||
cmd = drv->clean;
|
||||
else if ((CAP_SMUDGE & wanted_capability) && drv->smudge)
|
||||
cmd = drv->smudge;
|
||||
|
||||
if (cmd && *cmd)
|
||||
return apply_single_file_filter(path, src, len, fd, dst, cmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_convert_config(const char *var, const char *value, void *cb)
|
||||
{
|
||||
const char *key, *name;
|
||||
|
@ -839,7 +859,7 @@ int would_convert_to_git_filter_fd(const char *path)
|
|||
if (!ca.drv->required)
|
||||
return 0;
|
||||
|
||||
return apply_filter(path, NULL, 0, -1, NULL, ca.drv->clean);
|
||||
return apply_filter(path, NULL, 0, -1, NULL, ca.drv, CAP_CLEAN);
|
||||
}
|
||||
|
||||
const char *get_convert_attr_ascii(const char *path)
|
||||
|
@ -872,18 +892,12 @@ int convert_to_git(const char *path, const char *src, size_t len,
|
|||
struct strbuf *dst, enum safe_crlf checksafe)
|
||||
{
|
||||
int ret = 0;
|
||||
const char *filter = NULL;
|
||||
int required = 0;
|
||||
struct conv_attrs ca;
|
||||
|
||||
convert_attrs(&ca, path);
|
||||
if (ca.drv) {
|
||||
filter = ca.drv->clean;
|
||||
required = ca.drv->required;
|
||||
}
|
||||
|
||||
ret |= apply_filter(path, src, len, -1, dst, filter);
|
||||
if (!ret && required)
|
||||
ret |= apply_filter(path, src, len, -1, dst, ca.drv, CAP_CLEAN);
|
||||
if (!ret && ca.drv && ca.drv->required)
|
||||
die("%s: clean filter '%s' failed", path, ca.drv->name);
|
||||
|
||||
if (ret && dst) {
|
||||
|
@ -907,7 +921,7 @@ void convert_to_git_filter_fd(const char *path, int fd, struct strbuf *dst,
|
|||
assert(ca.drv);
|
||||
assert(ca.drv->clean);
|
||||
|
||||
if (!apply_filter(path, NULL, 0, fd, dst, ca.drv->clean))
|
||||
if (!apply_filter(path, NULL, 0, fd, dst, ca.drv, CAP_CLEAN))
|
||||
die("%s: clean filter '%s' failed", path, ca.drv->name);
|
||||
|
||||
crlf_to_git(path, dst->buf, dst->len, dst, ca.crlf_action, checksafe);
|
||||
|
@ -919,15 +933,9 @@ static int convert_to_working_tree_internal(const char *path, const char *src,
|
|||
int normalizing)
|
||||
{
|
||||
int ret = 0, ret_filter = 0;
|
||||
const char *filter = NULL;
|
||||
int required = 0;
|
||||
struct conv_attrs ca;
|
||||
|
||||
convert_attrs(&ca, path);
|
||||
if (ca.drv) {
|
||||
filter = ca.drv->smudge;
|
||||
required = ca.drv->required;
|
||||
}
|
||||
|
||||
ret |= ident_to_worktree(path, src, len, dst, ca.ident);
|
||||
if (ret) {
|
||||
|
@ -938,7 +946,7 @@ static int convert_to_working_tree_internal(const char *path, const char *src,
|
|||
* CRLF conversion can be skipped if normalizing, unless there
|
||||
* is a smudge filter. The filter might expect CRLFs.
|
||||
*/
|
||||
if (filter || !normalizing) {
|
||||
if ((ca.drv && ca.drv->smudge) || !normalizing) {
|
||||
ret |= crlf_to_worktree(path, src, len, dst, ca.crlf_action);
|
||||
if (ret) {
|
||||
src = dst->buf;
|
||||
|
@ -946,8 +954,8 @@ static int convert_to_working_tree_internal(const char *path, const char *src,
|
|||
}
|
||||
}
|
||||
|
||||
ret_filter = apply_filter(path, src, len, -1, dst, filter);
|
||||
if (!ret_filter && required)
|
||||
ret_filter = apply_filter(path, src, len, -1, dst, ca.drv, CAP_SMUDGE);
|
||||
if (!ret_filter && ca.drv && ca.drv->required)
|
||||
die("%s: smudge filter %s failed", path, ca.drv->name);
|
||||
|
||||
return ret | ret_filter;
|
||||
|
|
Загрузка…
Ссылка в новой задаче