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

Re: [PATCH V2] git-apply: add --allow-empty flag

From
Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Date
Apr 29, 2021, 00:32 UTC
Message-ID
<878s52ylko.fsf@evledraar.gmail.com>
In-Reply-To
<20210427194049.14399-1-jerry@skydio.com>
On Tue, Apr 27 2021, Jerry Zhang wrote:
Show 116 quoted lines
> Some users or scripts will pipe "git diff"
> output to "git apply" when replaying diffs
> or commits. In these cases, they will rely
> on the return value of "git apply" to know
> whether the diff was applied successfully.
>
> However, for empty commits, "git apply" will
> fail. This complicates scripts since they
> have to either buffer the diff and check
> its length, or run diff again with "exit-code",
> essentially doing the diff twice.
>
> Add the "--allow-empty" flag to "git apply"
> which allows it to handle both empty diffs
> and empty commits created by "git format-patch
> --always" by doing nothing and returning 0.
>
> Add tests for both with and without --allow-empty.
>
> Signed-off-by: Jerry Zhang <jerry@skydio.com>
> ---
> This patch applies on top of "git-apply: add --quiet flag".
> The conflict is in Documentation -> Synopsis and is
> trivial to solve.
>
> V1 -> V2:
> - Moved behavior under a flag
> - Added tests for both cases
>
>  Documentation/git-apply.txt |  6 +++++-
>  apply.c                     |  8 ++++++--
>  apply.h                     |  1 +
>  t/t4126-apply-empty.sh      | 16 ++++++++++++++++
>  4 files changed, 28 insertions(+), 3 deletions(-)
>
> diff --git a/Documentation/git-apply.txt b/Documentation/git-apply.txt
> index a32ad64718..b6d77f4206 100644
> --- a/Documentation/git-apply.txt
> +++ b/Documentation/git-apply.txt
> @@ -16,7 +16,7 @@ SYNOPSIS
>  	  [--ignore-space-change | --ignore-whitespace]
>  	  [--whitespace=(nowarn|warn|fix|error|error-all)]
>  	  [--exclude=<path>] [--include=<path>] [--directory=<root>]
> -	  [--verbose | --quiet] [--unsafe-paths] [<patch>...]
> +	  [--verbose | --quiet] [--unsafe-paths] [--allow-empty] [<patch>...]
>  
>  DESCRIPTION
>  -----------
> @@ -256,6 +256,10 @@ When `git apply` is used as a "better GNU patch", the user can pass
>  the `--unsafe-paths` option to override this safety check.  This option
>  has no effect when `--index` or `--cached` is in use.
>  
> +--allow-empty::
> +	Don't return error for patches containing no diff. This includes
> +	empty patches and patches with commit text only.
> +
>  CONFIGURATION
>  -------------
>  
> diff --git a/apply.c b/apply.c
> index 918e0988bb..0ddde5e8a8 100644
> --- a/apply.c
> +++ b/apply.c
> @@ -4732,8 +4732,10 @@ static int apply_patch(struct apply_state *state,
>  	}
>  
>  	if (!list && !skipped_patch) {
> -		error(_("unrecognized input"));
> -		res = -128;
> +		if (!state->allow_empty) {
> +			error(_("unrecognized input"));
> +			res = -128;
> +		}
>  		goto end;
>  	}
>  
> @@ -5061,6 +5063,8 @@ int apply_parse_options(int argc, const char **argv,
>  		OPT_CALLBACK(0, "directory", state, N_("root"),
>  			N_("prepend <root> to all filenames"),
>  			apply_option_parse_directory),
> +		OPT_BOOL(0, "allow-empty", &state->allow_empty,
> +			N_("don't return error for empty patches")),
>  		OPT_END()
>  	};
>  
> diff --git a/apply.h b/apply.h
> index da3d95fa50..16202da160 100644
> --- a/apply.h
> +++ b/apply.h
> @@ -66,6 +66,7 @@ struct apply_state {
>  	int threeway;
>  	int unidiff_zero;
>  	int unsafe_paths;
> +	int allow_empty;
>  
>  	/* Other non boolean parameters */
>  	struct repository *repo;
> diff --git a/t/t4126-apply-empty.sh b/t/t4126-apply-empty.sh
> index ceb6a79fe0..f89c53c5f6 100755
> --- a/t/t4126-apply-empty.sh
> +++ b/t/t4126-apply-empty.sh
> @@ -31,6 +31,22 @@ test_expect_success 'apply empty' '
>  	test_cmp expect empty
>  '
>  
> +test_expect_success 'apply empty patch fails' '
> +	git reset --hard &&
> +	git commit --allow-empty -m "empty commit" &&
> +	git format-patch --always HEAD~ >empty.patch &&
> +	test_must_fail git apply empty.patch &&
> +	test_must_fail git apply - </dev/null
> +'
> +
> +test_expect_success 'apply with --allow-empty succeeds' '
> +	git reset --hard &&
> +	git commit --allow-empty -m "empty commit" &&

Rather than making two --allow-empty commits, shouldn't this be added to the earlier "setup" routine, so both of these tests can use the same empty commit?

The setup routine sets up a patch0 and patch1, just add an empty-patch ?

And for the "git reset --hard" I see you're copy/pasting the existing convention in that file, but FWIW it's better to use 'test_when_finished "git reset --hard"' in the appropriate spot in the test (i.e. just before we'd need the reset if we fail), so a test cleans up after itself. As opposed to "I'm cleaning in case an earlier test didn't clean up".

Show 8 quoted lines
> +	git format-patch --always HEAD~ >empty.patch &&
> +	git apply --allow-empty empty.patch &&
> +	git apply --allow-empty - </dev/null
> +'
> +
>  test_expect_success 'apply --index empty' '
>  	git reset --hard &&
>  	rm -f missing &&
Previous: Jerry ZhangNext: Jerry Zhang
Message 7 of 13 in “git-apply: allow empty patch text”
  1. git-apply: allow empty patch textJerry Zhang, Apr 27, 2021
  2. Eric WongApr 27, 2021
  3. Junio C HamanoApr 27, 2021
  4. git-apply: add --allow-empty flagJerry Zhang, Apr 27, 2021
  5. Junio C HamanoApr 28, 2021
  6. Jerry ZhangApr 28, 2021
  7. Ævar Arnfjörð BjarmasonApr 29, 2021
  8. git-apply: add --allow-empty flagJerry Zhang, Dec 11, 2021
  9. Bagas SanjayaDec 11, 2021
  10. git-apply: add --allow-empty flagJerry Zhang, Dec 13, 2021
  11. Junio C HamanoDec 13, 2021
  12. Jerry ZhangDec 13, 2021
  13. Junio C HamanoDec 13, 2021

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.