git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [GSoC][PATCH v3 1/3] sequencer: add a new function to silence a command, except if it fails.

From
Junio C Hamano <gitster@pobox.com>
Date
Jun 21, 2018, 22:03 UTC
Message-ID
<xmqqk1qrre4w.fsf@gitster-ct.c.googlers.com>
In-Reply-To
<20180621141732.19952-2-alban.gruin@gmail.com>
Alban Gruin <alban.gruin@gmail.com> writes:
Show 7 quoted lines
> This adds a new function, run_command_silent_on_success(), to
> redirect the stdout and stderr of a command to a strbuf, and then to run
> that command. This strbuf is printed only if the command fails. It is
> functionnaly similar to output() from git-rebase.sh.
>
> run_git_commit() is then refactored to use of
> run_command_silent_on_success().

It might be just a difference in viewpoint, but I think it is more customary in this project (hence it will be easier to understand and accept by readers of the patch) if a change like this is explained NOT as "introducing a new function and then rewrite an existing code to use it", and instead as "extract a helper function from an existing code so that future callers can reuse it."

Show 9 quoted lines
> +static int run_command_silent_on_success(struct child_process *cmd)
> +{
> +	struct strbuf buf = STRBUF_INIT;
> +	int rc;
> +
> +	cmd->stdout_to_stderr = 1;
> +	rc = pipe_command(cmd,
> +			  NULL, 0,
> +			  /* stdout is already redirected */

I can see that this comment was inherited from the original place this code was lifted from (and that is why I say this is not "adding a new helper and rewriting an existing piece of code to use it" but is "extracting this function out of an existing code for future reuse"), but does it still make sense in the new context to keep the same comment?

The original in run_git_commit() made the .stdout_to_stderr=1 assignment many lines before it called pipe_command(), and it made sense to remind readers why we are passing NULL to the out buffer and only passing the err buffer here. But in the context of this new helper function, the redirection that may make such a reminder necessary sits immediately before the pipe_command() call for everybody to see.

Show 8 quoted lines
> +			  NULL, 0,
> +			  &buf, 0);
> +
> +	if (rc)
> +		fputs(buf.buf, stderr);
> +	strbuf_release(&buf);
> +	return rc;
> +}
Show 21 quoted lines
> @@ -820,18 +838,11 @@ static int run_git_commit(const char *defmsg, struct replay_opts *opts,
>  
>  	cmd.git_cmd = 1;
>  
> -	if (is_rebase_i(opts)) {
> -		if (!(flags & EDIT_MSG)) {
> -			cmd.stdout_to_stderr = 1;
> -			cmd.err = -1;
> -		}
> +	if (is_rebase_i(opts) && read_env_script(&cmd.env_array)) {
> +		const char *gpg_opt = gpg_sign_opt_quoted(opts);
>  
> -		if (read_env_script(&cmd.env_array)) {
> -			const char *gpg_opt = gpg_sign_opt_quoted(opts);
> -
> -			return error(_(staged_changes_advice),
> -				     gpg_opt, gpg_opt);
> -		}
> +		return error(_(staged_changes_advice),
> +			     gpg_opt, gpg_opt);
>  	}

The original in this hunk is criminally incomprehensible ;-) The assignment of .stdout_to_stderr=1 does not have to happen this early in the code, and also using .err being -1 to communicate that the "capture and show error only upon error" magic is going to be used to the later code is unnecessarily opaque. The new code gets rid of that ugliness from this earlier hunk and instead makes this part only about reading the various state files (and reporting failure to do so).

Show 22 quoted lines
> @@ -861,20 +872,8 @@ static int run_git_commit(const char *defmsg, struct replay_opts *opts,
>  	if (opts->allow_empty_message)
>  		argv_array_push(&cmd.args, "--allow-empty-message");
>  
> -	if (cmd.err == -1) {
> -		/* hide stderr on success */
> -		struct strbuf buf = STRBUF_INIT;
> -		int rc = pipe_command(&cmd,
> -				      NULL, 0,
> -				      /* stdout is already redirected */
> -				      NULL, 0,
> -				      &buf, 0);
> -		if (rc)
> -			fputs(buf.buf, stderr);
> -		strbuf_release(&buf);
> -		return rc;
> -	}
> -
> +	if (is_rebase_i(opts) && !(flags & EDIT_MSG))
> +		return run_command_silent_on_success(&cmd);
>  	return run_command(&cmd);
>  }

And then, the updated code in this hunk checks the EDIT_MSG bit instead. It probably is easier to understand the code if you added an "else" after, to highlight the fact that this is choosing one out of two possible ways to run "cmd", i.e.

	if (is_rebase_i(opts) && !(flags & EDIT_MSG))
		return run_command_silent_on_success(&cmd);
	else
		return run_command(&cmd);
Previous: Alban GruinNext: Alban Gruin
Message 27 of 51 in “rebase -i: rewrite reflog operations in C”
  1. Alban GruinJun 18, 2018
  2. [GSoC][PATCH 1/3] sequencer: add a new function to silence a command, except if it fails.Alban Gruin, Jun 18, 2018
  3. Phillip WoodJun 18, 2018
  4. Alban GruinJun 18, 2018
  5. Christian CouderJun 18, 2018
  6. Alban GruinJun 18, 2018
  7. [GSoC][PATCH 2/3] rebase -i: rewrite setup_reflog_action() in CAlban Gruin, Jun 18, 2018
  8. Phillip WoodJun 18, 2018
  9. Alban GruinJun 18, 2018
  10. Stefan BellerJun 18, 2018
  11. Johannes SchindelinJun 19, 2018
  12. [GSoC][PATCH 3/3] rebase -i: rewrite checkout_onto() in CAlban Gruin, Jun 18, 2018
  13. Phillip WoodJun 18, 2018
  14. Alban GruinJun 18, 2018
  15. [GSoC][PATCH v2 0/3] rebase -i: rewrite reflog operations in CAlban Gruin, Jun 19, 2018
  16. [GSoC][PATCH v2 1/3] sequencer: add a new function to silence a command, except if it fails.Alban Gruin, Jun 19, 2018
  17. Johannes SchindelinJun 21, 2018
  18. Alban GruinJun 21, 2018
  19. [GSoC][PATCH v2 2/3] rebase -i: rewrite setup_reflog_action() in CAlban Gruin, Jun 19, 2018
  20. Johannes SchindelinJun 21, 2018
  21. [GSoC][PATCH v2 3/3] rebase -i: rewrite checkout_onto() in CAlban Gruin, Jun 19, 2018
  22. Johannes SchindelinJun 21, 2018
  23. Stefan BellerJun 19, 2018
  24. Johannes SchindelinJun 21, 2018
  25. [GSoC][PATCH v3 0/3] rebase -i: rewrite reflog operations in CAlban Gruin, Jun 21, 2018
  26. [GSoC][PATCH v3 1/3] sequencer: add a new function to silence a command, except if it fails.Alban Gruin, Jun 21, 2018
  27. Junio C HamanoJun 21, 2018
  28. Alban GruinJun 22, 2018
  29. [GSoC][PATCH v3 2/3] rebase -i: rewrite setup_reflog_action() in CAlban Gruin, Jun 21, 2018
  30. Junio C HamanoJun 22, 2018
  31. Alban GruinJun 22, 2018
  32. Junio C HamanoJun 25, 2018
  33. Alban GruinJun 25, 2018
  34. Johannes SchindelinJun 25, 2018
  35. Pratik KarkiJun 26, 2018
  36. Junio C HamanoJun 26, 2018
  37. [GSoC][PATCH v3 3/3] rebase -i: rewrite checkout_onto() in CAlban Gruin, Jun 21, 2018
  38. [GSoC][PATCH v4 0/3] rebase -i: rewrite reflog operations in CAlban Gruin, Jun 25, 2018
  39. [GSoC][PATCH v4 1/3] sequencer: extract a function to silence a command, except if it failsAlban Gruin, Jun 25, 2018
  40. [GSoC][PATCH v4 2/3] rebase -i: rewrite checkout_onto() in CAlban Gruin, Jun 25, 2018
  41. Junio C HamanoJun 26, 2018
  42. [GSoC][PATCH v4 3/3] rebase -i: rewrite setup_reflog_action() in CAlban Gruin, Jun 25, 2018
  43. [GSoC][PATCH v5 0/3] rebase -i: rewrite reflog operations in CAlban Gruin, Jun 29, 2018
  44. [GSoC][PATCH v5 1/3] sequencer: add a new function to silence a command, except if it fails.Alban Gruin, Jun 29, 2018
  45. [GSoC][PATCH v5 2/3] rebase -i: rewrite setup_reflog_action() in CAlban Gruin, Jun 29, 2018
  46. Junio C HamanoJun 29, 2018
  47. [GSoC][PATCH v5 3/3] rebase -i: rewrite checkout_onto() in CAlban Gruin, Jun 29, 2018
  48. Junio C HamanoJun 29, 2018
  49. Junio C HamanoJun 29, 2018
  50. Alban GruinJul 2, 2018
  51. Junio C HamanoJul 3, 2018

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.