@ -507,7 +507,7 @@ static struct hashmap subprocess_map;
static int start_multi_file_filter_fn(struct subprocess_entry *subprocess)
static int start_multi_file_filter_fn(struct subprocess_entry *subprocess)
{
{
int err;
int err, i;
struct cmd2process *entry = (struct cmd2process *)subprocess;
struct cmd2process *entry = (struct cmd2process *)subprocess;
struct string_list cap_list = STRING_LIST_INIT_NODUP;
struct string_list cap_list = STRING_LIST_INIT_NODUP;
char *cap_buf;
char *cap_buf;
@ -515,6 +515,14 @@ static int start_multi_file_filter_fn(struct subprocess_entry *subprocess)
struct child_process *process = &subprocess->process;
struct child_process *process = &subprocess->process;
const char *cmd = subprocess->cmd;
const char *cmd = subprocess->cmd;
static const struct {
const char *name;
unsigned int cap;
} known_caps[] = {
{ "clean", CAP_CLEAN },
{ "smudge", CAP_SMUDGE },
};
sigchain_push(SIGPIPE, SIG_IGN);
sigchain_push(SIGPIPE, SIG_IGN);
err = packet_writel(process->in, "git-filter-client", "version=2", NULL);
err = packet_writel(process->in, "git-filter-client", "version=2", NULL);
@ -533,7 +541,15 @@ static int start_multi_file_filter_fn(struct subprocess_entry *subprocess)
if (err)
if (err)
goto done;
goto done;
err = packet_writel(process->in, "capability=clean", "capability=smudge", NULL);
for (i = 0; i < ARRAY_SIZE(known_caps); ++i) {
err = packet_write_fmt_gently(
process->in, "capability=%s\n", known_caps[i].name);
if (err)
goto done;
}
err = packet_flush_gently(process->in);
if (err)
goto done;
for (;;) {
for (;;) {
cap_buf = packet_read_line(process->out, NULL);
cap_buf = packet_read_line(process->out, NULL);
@ -545,16 +561,15 @@ static int start_multi_file_filter_fn(struct subprocess_entry *subprocess)
continue;
continue;
cap_name = cap_list.items[1].string;
cap_name = cap_list.items[1].string;
if (!strcmp(cap_name, "clean")) {
i = ARRAY_SIZE(known_caps) - 1;
entry->supported_capabilities |= CAP_CLEAN;
while (i >= 0 && strcmp(cap_name, known_caps[i].name))
} else if (!strcmp(cap_name, "smudge")) {
i--;
entry->supported_capabilities |= CAP_SMUDGE;
} else {
if (i >= 0)
warning(
entry->supported_capabilities |= known_caps[i].cap;
"external filter '%s' requested unsupported filter capability '%s'",
else
cmd, cap_name
warning("external filter '%s' requested unsupported filter capability '%s'",
);
cmd, cap_name);
}
string_list_clear(&cap_list, 0);
string_list_clear(&cap_list, 0);
}
}