All of lore.kernel.org
 help / color / mirror / Atom feed
From: Phillip Wood <phillip.wood123@gmail.com>
To: Taylor Blau <me@ttaylorr.com>, Cameron Steffen <cam.steffen94@gmail.com>
Cc: git@vger.kernel.org
Subject: Re: git revert --continue --no-verify
Date: Wed, 4 Aug 2021 19:14:34 +0100	[thread overview]
Message-ID: <74443c64-efe9-ea47-e918-d62b8c976abc@gmail.com> (raw)
In-Reply-To: <YQm+PWAtc3rixqsw@nand.local>

Hi Cameron and Taylor

On 03/08/2021 23:07, Taylor Blau wrote:
> On Tue, Aug 03, 2021 at 04:33:09PM -0500, Cameron Steffen wrote:
>> Perhaps the issue then is that the pre-commit hook should not run for
>> `git revert --continue`? It does not run for `git revert`.

The general rule for cherry-pick, revert and rebase is that if the 
commit message is edited then the commit is made with --verify and if 
the commit message is not being edited then the commit is made with 
--no-verify. I think the reasoning for this is that if the user has 
altered the commit message or contents and they have a pre-commit hook 
set then it is reasonable to check the new commit is acceptable to the 
hook. There are some exceptions to this which are oversights (for 
example I think we always pass --no-verify when committing a conflict 
resolution with 'git rebase --continue' even though the editor opens 
when committing in that case - I should try and fix that)

For 'git revert --continue' the commit is made when sequencer_continue() 
calls continue_single_pick() which looks like

static int continue_single_pick(struct repository *r, struct replay_opts 
*opts)
{
	struct strvec argv = STRVEC_INIT;
	int ret;

	if (!refs_ref_exists(get_main_ref_store(r), "CHERRY_PICK_HEAD") &&
	    !refs_ref_exists(get_main_ref_store(r), "REVERT_HEAD"))
		return error(_("no cherry-pick or revert in progress"));

	strvec_push(&argv, "commit");

	/*
	 * continue_single_pick() handles the case of recovering from a
	 * conflict.  should_edit() doesn't handle that case; for a conflict,
	 * we want to edit if the user asked for it, or if they didn't specify
	 * and stdin is a tty.
	 */
	if (!opts->edit || (opts->edit < 0 && !isatty(0)))
		/*
		 * Include --cleanup=strip as well because we don't want the
		 * "# Conflicts:" messages.
		 */
		strvec_pushl(&argv, "--no-edit", "--cleanup=strip", NULL);

	ret = run_command_v_opt(argv.v, RUN_GIT_CMD);
	strvec_clear(&argv);
	return ret;
}

It runs git commit directly and never passes --no-verify. I wouldn't be 
opposed to someone adding support for --no-verify (and --no-edit) to 
"cherry-pick/revert/rebase --continue" on the understanding that it only 
applied when committing the conflict resolution. There is a possible 
confusion for users though who might expect that the options passed with 
'--continue' applied to all the commits made by the command.

> This does look like an oversight to me, but you'll have to bear with me
> since I am relatively unfamiliar with the sequencer code.
> 
> Ultimately `git revert` calls do_pick_commit()

This is what happens when we are picking commits, the commit made with 
'--continue' uses a different code path

> which either calls
> do_commit() or run_git_commit(). A couple of curiosities there:
> 
>    - do_commit() does fall back to run_git_commit() if it has the
>      VERIFY_MSG bit set in `flags`.
>    - run_git_commit() passes `-n` only when VERIFY_MSG *isn't* set, so
>      the VERIFY_MSG bit does imply that the pre-commit hook would be run
>      there.
>    - when do_pick_commit() does have to fall back to run_git_commit(), it
>      sets the VERIFY_MSG bit in flags.

Calling run_git_commit() there is not a fallback it, that call is used 
to reword commits once they have been picked (see 450efe2d53 ("rebase 
-i: always update HEAD before rewording", 2019-08-19) for the reasoning 
behind this) . Because the message is being edited there is no point in 
going through do_commit().

> But we never end up calling run_git_commit() (except in the case of
> errors) because do_pick_commit() special-cases `command == TODO_REVERT`
> (which is the case for `git revert`) and calls `do_commit()`.
> 
> But it gets weirder: do_commit() calls run_git_commit() itself, but
> before the caller in do_pick_commit() has had a chance to add VERIFY_MSG
> to the flags.

do_commit() does not change the flags that it is called with - callers 
that want VERIFY_MSG will set that before they call do_commit(). 
do_commit() is there to commit simple picks without forking 'git commit'

> So I suspect that this is an oversight, but perhaps somebody more
> familiar with this code could confirm my thinking.

I hope the above helps - basically the idea is "if the commit has been 
edited use VERIFY_MSG" and --continue unhelpfully uses a completely 
different code-path to the main commit picking/reverting loop.

Best Wishes

Phillip

> Thanks,
> Taylor
> 


  parent reply	other threads:[~2021-08-04 18:14 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-03 19:17 git revert --continue --no-verify Cameron Steffen
2021-08-03 20:50 ` Taylor Blau
2021-08-03 20:56   ` Cameron Steffen
2021-08-03 20:59     ` Taylor Blau
2021-08-03 21:33       ` Cameron Steffen
2021-08-03 22:07         ` Taylor Blau
2021-08-04  0:38           ` Junio C Hamano
2021-08-04 18:14           ` Phillip Wood [this message]
2021-08-05  1:40             ` Taylor Blau
2021-08-05  1:56               ` Cameron Steffen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=74443c64-efe9-ea47-e918-d62b8c976abc@gmail.com \
    --to=phillip.wood123@gmail.com \
    --cc=cam.steffen94@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=me@ttaylorr.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.