summaryrefslogtreecommitdiff
path: root/convert.c
diff options
context:
space:
mode:
authorLibravatar Jonathan Tan <jonathantanmy@google.com>2017-07-26 11:17:29 -0700
committerLibravatar Junio C Hamano <gitster@pobox.com>2017-07-26 13:00:40 -0700
commitfa64a2fdbeedd98c5f24d1662bcc470a8449abcf (patch)
tree7da566f387a1f3253d7ecc98a48495d311881988 /convert.c
parentDocumentation: migrate sub-process docs to header (diff)
downloadtgif-fa64a2fdbeedd98c5f24d1662bcc470a8449abcf.tar.xz
sub-process: refactor handshake to common function
Refactor, into a common function, the version and capability negotiation done when invoking a long-running process as a clean or smudge filter. This will be useful for other Git code that needs to interact similarly with a long-running process. As you can see in the change to t0021, this commit changes the error message reported when the long-running process does not introduce itself with the expected "server"-terminated line. Originally, the error message reports that the filter "does not support filter protocol version 2", differentiating between the old single-file filter protocol and the new multi-file filter protocol - I have updated it to something more generic and useful. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'convert.c')
-rw-r--r--convert.c75
1 files changed, 7 insertions, 68 deletions
diff --git a/convert.c b/convert.c
index 972bf8aec2..4936fcc26b 100644
--- a/convert.c
+++ b/convert.c
@@ -513,78 +513,17 @@ static struct hashmap subprocess_map;
static int start_multi_file_filter_fn(struct subprocess_entry *subprocess)
{
- int err, i;
- struct cmd2process *entry = (struct cmd2process *)subprocess;
- struct string_list cap_list = STRING_LIST_INIT_NODUP;
- char *cap_buf;
- const char *cap_name;
- struct child_process *process = &subprocess->process;
- const char *cmd = subprocess->cmd;
-
- static const struct {
- const char *name;
- unsigned int cap;
- } known_caps[] = {
+ static int versions[] = {2, 0};
+ static struct subprocess_capability capabilities[] = {
{ "clean", CAP_CLEAN },
{ "smudge", CAP_SMUDGE },
{ "delay", CAP_DELAY },
+ { NULL, 0 }
};
-
- sigchain_push(SIGPIPE, SIG_IGN);
-
- err = packet_writel(process->in, "git-filter-client", "version=2", NULL);
- if (err)
- goto done;
-
- err = strcmp(packet_read_line(process->out, NULL), "git-filter-server");
- if (err) {
- error("external filter '%s' does not support filter protocol version 2", cmd);
- goto done;
- }
- err = strcmp(packet_read_line(process->out, NULL), "version=2");
- if (err)
- goto done;
- err = packet_read_line(process->out, NULL) != NULL;
- if (err)
- goto done;
-
- 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 (;;) {
- cap_buf = packet_read_line(process->out, NULL);
- if (!cap_buf)
- break;
- string_list_split_in_place(&cap_list, cap_buf, '=', 1);
-
- if (cap_list.nr != 2 || strcmp(cap_list.items[0].string, "capability"))
- continue;
-
- cap_name = cap_list.items[1].string;
- i = ARRAY_SIZE(known_caps) - 1;
- while (i >= 0 && strcmp(cap_name, known_caps[i].name))
- i--;
-
- if (i >= 0)
- entry->supported_capabilities |= known_caps[i].cap;
- else
- warning("external filter '%s' requested unsupported filter capability '%s'",
- cmd, cap_name);
-
- string_list_clear(&cap_list, 0);
- }
-
-done:
- sigchain_pop(SIGPIPE);
-
- return err;
+ struct cmd2process *entry = (struct cmd2process *)subprocess;
+ return subprocess_handshake(subprocess, "git-filter", versions, NULL,
+ capabilities,
+ &entry->supported_capabilities);
}
static void handle_filter_error(const struct strbuf *filter_status,