Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.kernel.org/pub/scm/git/git.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2022-06-14 01:53:41 +0300
committerJunio C Hamano <gitster@pobox.com>2022-06-14 01:53:41 +0300
commit1a7f6be5b17f572fc68ff2a2e0c079d50c671c74 (patch)
tree1968c2539b29085e584648a5b8079551ec61b752 /run-command.c
parent66c2948ffd6e376447252a3a72f7ce78eeef3e52 (diff)
parenta082345372e14ecd30a84a790eda0c38154e4602 (diff)
Merge branch 'ab/hooks-regression-fix'
In Git 2.36 we revamped the way how hooks are invoked. One change that is end-user visible is that the output of a hook is no longer directly connected to the standard output of "git" that spawns the hook, which was noticed post release. This is getting corrected. * ab/hooks-regression-fix: hook API: fix v2.36.0 regression: hooks should be connected to a TTY run-command: add an "ungroup" option to run_process_parallel()
Diffstat (limited to 'run-command.c')
-rw-r--r--run-command.c70
1 files changed, 51 insertions, 19 deletions
diff --git a/run-command.c b/run-command.c
index 789eaa5975..8e36b8ee74 100644
--- a/run-command.c
+++ b/run-command.c
@@ -1472,6 +1472,7 @@ enum child_state {
GIT_CP_WAIT_CLEANUP,
};
+int run_processes_parallel_ungroup;
struct parallel_processes {
void *data;
@@ -1495,6 +1496,7 @@ struct parallel_processes {
struct pollfd *pfd;
unsigned shutdown : 1;
+ unsigned ungroup : 1;
int output_owner;
struct strbuf buffered_output; /* of finished children */
@@ -1538,7 +1540,7 @@ static void pp_init(struct parallel_processes *pp,
get_next_task_fn get_next_task,
start_failure_fn start_failure,
task_finished_fn task_finished,
- void *data)
+ void *data, int ungroup)
{
int i;
@@ -1560,15 +1562,21 @@ static void pp_init(struct parallel_processes *pp,
pp->nr_processes = 0;
pp->output_owner = 0;
pp->shutdown = 0;
+ pp->ungroup = ungroup;
CALLOC_ARRAY(pp->children, n);
- CALLOC_ARRAY(pp->pfd, n);
+ if (pp->ungroup)
+ pp->pfd = NULL;
+ else
+ CALLOC_ARRAY(pp->pfd, n);
strbuf_init(&pp->buffered_output, 0);
for (i = 0; i < n; i++) {
strbuf_init(&pp->children[i].err, 0);
child_process_init(&pp->children[i].process);
- pp->pfd[i].events = POLLIN | POLLHUP;
- pp->pfd[i].fd = -1;
+ if (pp->pfd) {
+ pp->pfd[i].events = POLLIN | POLLHUP;
+ pp->pfd[i].fd = -1;
+ }
}
pp_for_signal = pp;
@@ -1616,24 +1624,31 @@ static int pp_start_one(struct parallel_processes *pp)
BUG("bookkeeping is hard");
code = pp->get_next_task(&pp->children[i].process,
- &pp->children[i].err,
+ pp->ungroup ? NULL : &pp->children[i].err,
pp->data,
&pp->children[i].data);
if (!code) {
- strbuf_addbuf(&pp->buffered_output, &pp->children[i].err);
- strbuf_reset(&pp->children[i].err);
+ if (!pp->ungroup) {
+ strbuf_addbuf(&pp->buffered_output, &pp->children[i].err);
+ strbuf_reset(&pp->children[i].err);
+ }
return 1;
}
- pp->children[i].process.err = -1;
- pp->children[i].process.stdout_to_stderr = 1;
+ if (!pp->ungroup) {
+ pp->children[i].process.err = -1;
+ pp->children[i].process.stdout_to_stderr = 1;
+ }
pp->children[i].process.no_stdin = 1;
if (start_command(&pp->children[i].process)) {
- code = pp->start_failure(&pp->children[i].err,
+ code = pp->start_failure(pp->ungroup ? NULL :
+ &pp->children[i].err,
pp->data,
pp->children[i].data);
- strbuf_addbuf(&pp->buffered_output, &pp->children[i].err);
- strbuf_reset(&pp->children[i].err);
+ if (!pp->ungroup) {
+ strbuf_addbuf(&pp->buffered_output, &pp->children[i].err);
+ strbuf_reset(&pp->children[i].err);
+ }
if (code)
pp->shutdown = 1;
return code;
@@ -1641,7 +1656,8 @@ static int pp_start_one(struct parallel_processes *pp)
pp->nr_processes++;
pp->children[i].state = GIT_CP_WORKING;
- pp->pfd[i].fd = pp->children[i].process.err;
+ if (pp->pfd)
+ pp->pfd[i].fd = pp->children[i].process.err;
return 0;
}
@@ -1675,6 +1691,7 @@ static void pp_buffer_stderr(struct parallel_processes *pp, int output_timeout)
static void pp_output(struct parallel_processes *pp)
{
int i = pp->output_owner;
+
if (pp->children[i].state == GIT_CP_WORKING &&
pp->children[i].err.len) {
strbuf_write(&pp->children[i].err, stderr);
@@ -1697,7 +1714,7 @@ static int pp_collect_finished(struct parallel_processes *pp)
code = finish_command(&pp->children[i].process);
- code = pp->task_finished(code,
+ code = pp->task_finished(code, pp->ungroup ? NULL :
&pp->children[i].err, pp->data,
pp->children[i].data);
@@ -1708,10 +1725,13 @@ static int pp_collect_finished(struct parallel_processes *pp)
pp->nr_processes--;
pp->children[i].state = GIT_CP_FREE;
- pp->pfd[i].fd = -1;
+ if (pp->pfd)
+ pp->pfd[i].fd = -1;
child_process_init(&pp->children[i].process);
- if (i != pp->output_owner) {
+ if (pp->ungroup) {
+ ; /* no strbuf_*() work to do here */
+ } else if (i != pp->output_owner) {
strbuf_addbuf(&pp->buffered_output, &pp->children[i].err);
strbuf_reset(&pp->children[i].err);
} else {
@@ -1748,9 +1768,14 @@ int run_processes_parallel(int n,
int i, code;
int output_timeout = 100;
int spawn_cap = 4;
+ int ungroup = run_processes_parallel_ungroup;
struct parallel_processes pp;
- pp_init(&pp, n, get_next_task, start_failure, task_finished, pp_cb);
+ /* unset for the next API user */
+ run_processes_parallel_ungroup = 0;
+
+ pp_init(&pp, n, get_next_task, start_failure, task_finished, pp_cb,
+ ungroup);
while (1) {
for (i = 0;
i < spawn_cap && !pp.shutdown &&
@@ -1767,8 +1792,15 @@ int run_processes_parallel(int n,
}
if (!pp.nr_processes)
break;
- pp_buffer_stderr(&pp, output_timeout);
- pp_output(&pp);
+ if (ungroup) {
+ int i;
+
+ for (i = 0; i < pp.max_processes; i++)
+ pp.children[i].state = GIT_CP_WAIT_CLEANUP;
+ } else {
+ pp_buffer_stderr(&pp, output_timeout);
+ pp_output(&pp);
+ }
code = pp_collect_finished(&pp);
if (code) {
pp.shutdown = 1;