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

Re: [PATCH v3 2/2] push: fix --force-if-includes detached HEAD advice

From
Junio C Hamano <gitster@pobox.com>
Date
Sep 11, 2026, 15:40 UTC
Message-ID
<xmqqtsnvdcdz.fsf@gitster.g>
In-Reply-To
<20260910230506.1631656-3-tyler@tylercipriani.com>
Tyler Cipriani <tyler@tylercipriani.com> writes:
Show 19 quoted lines
> When a --force-if-includes push is rejected due to a detached HEAD
> state where there is no per-branch reflog to consult, the advice is
> misleading:
>
>      ! [rejected] HEAD -> main (remote ref updated since checkout)
>     error: failed to push some refs to '<remote>'
>     hint: Updates were rejected because the tip of the remote-tracking
>     hint: branch has been updated since the last checkout. If you want
>     hint: to integrate the remote changes, use 'git pull' before
>     hint: pushing again. See the 'Note about fast-forwards' in 'git
>     hint: push --help' for details.
>
> But a `git pull` will not fix this rejection. What is required is either
>
> - Specify the expected remote tip with --force-with-lease=<ref>:<expect>
> - Ignore the error with --no-force-if-includes
>
> Add ref->unverifiable to differentiate between a detached HEAD rejection
> vs. a remote update rejection.
Makes sense.
Show 13 quoted lines
> diff --git a/builtin/push.c b/builtin/push.c
> index 6021b71d66..9676c6241f 100644
> --- a/builtin/push.c
> +++ b/builtin/push.c
> @@ -319,6 +319,12 @@ static const char message_advice_ref_needs_update[] =
>  	   "remote changes, use 'git pull' before pushing again.\n"
>  	   "See the 'Note about fast-forwards' in 'git push --help' for details.");
>  
> +static const char message_advice_ref_unverifiable[] =
> +	N_("Updates were rejected because the tip of the remote-tracking branch\n"
> +	   "cannot be checked against a detached HEAD. If you want to push anyway,\n"
> +	   "specify the expected value with '--force-with-lease=<ref>:<expect>'\n"
> +	   "or use '--no-force-if-includes' to skip this check.");
Good.
> +static void advise_ref_unverifiable(void)
> +{
> +	if (!advice_enabled(ADVICE_PUSH_REF_UNVERIFIABLE) || !advice_enabled(ADVICE_PUSH_UPDATE_REJECTED))
> +		return;
Line that is over +100 column wide?
> +	advise(_(message_advice_ref_unverifiable));
> +}

This is a tangent, but on a separate thread we were talking about consolidating a sequence

    if (advice_enabled(ADVICE_FOO))
	advise(_(message for FOO));
into
    advise_if_enabled(ADVICE_FOO, _(message for FOO));

This is an example of usage that falls outside of the pattern (not a bad thing; just what those who advocate more use of advise_if_enabled() need to be aware of).

Show 24 quoted lines
> diff --git a/t/t5533-push-cas.sh b/t/t5533-push-cas.sh
> index 0c02151747..fe6af3f41c 100755
> --- a/t/t5533-push-cas.sh
> +++ b/t/t5533-push-cas.sh
> @@ -311,7 +311,8 @@ test_expect_success 'background updates to remote can be mitigated with "--force
>  		git switch main &&
>  		test_commit J &&
>  		git fetch --all &&
> -		test_must_fail git push --force-with-lease --force-if-includes --all
> +		test_must_fail git push --force-with-lease --force-if-includes --all 2>err &&
> +		test_grep "remote ref updated since checkout" err
>  	) &&
>  	git ls-remote dst refs/heads/main >actual.main &&
>  	git ls-remote dst refs/heads/branch >actual.branch &&
> @@ -457,7 +458,9 @@ test_expect_success '"--force-if-includes" should reject forced update from deta
>  		git reset --hard origin/main &&
>  		git switch -c newbranch origin/main &&
>  		git checkout HEAD^ &&
> -		test_must_fail git push --force-if-includes --force-with-lease origin HEAD:main
> +		test_must_fail git push --force-if-includes --force-with-lease origin HEAD:main 2>err &&
> +		test_grep "remote ref unverifiable" err &&
> +		test_grep "no-force-if-includes" err
>  	)
>  '
Great.
Previous: Junio C HamanoNext: Junio C Hamano
Message 19 of 40 in “push: fix --force-if-includes consulting wrong ref”
  1. 0/2 push: fix --force-if-includes consulting wrong refTyler Cipriani, Sep 4, 2026
  2. 1/2 push: check pushed ref for --force-if-includesTyler Cipriani, Sep 4, 2026
  3. 2/2 push: fix --force-if-includes detached HEAD adviceTyler Cipriani, Sep 4, 2026
  4. Ben KnobleSep 5, 2026
  5. Ben KnobleSep 5, 2026
  6. Tyler CiprianiSep 6, 2026
  7. 0/2 push: fix --force-if-includes consulting wrong refTyler Cipriani, Sep 8, 2026
  8. 1/2 push: check pushed ref for --force-if-includesTyler Cipriani, Sep 8, 2026
  9. 2/2 push: fix --force-if-includes detached HEAD adviceTyler Cipriani, Sep 8, 2026
  10. D. Ben KnobleSep 9, 2026
  11. Junio C HamanoSep 10, 2026
  12. Tyler CiprianiSep 10, 2026
  13. 0/2 push: fix --force-if-includes consulting wrong refTyler Cipriani, Sep 10, 2026
  14. 1/2 push: check pushed ref for --force-if-includesTyler Cipriani, Sep 10, 2026
  15. 2/2 push: fix --force-if-includes detached HEAD adviceTyler Cipriani, Sep 10, 2026
  16. Patrick SteinhardtSep 11, 2026
  17. Patrick SteinhardtSep 11, 2026
  18. Junio C HamanoSep 11, 2026
  19. Junio C HamanoSep 11, 2026
  20. Junio C HamanoSep 11, 2026
  21. Tyler CiprianiSep 11, 2026
  22. Tyler CiprianiSep 11, 2026
  23. 0/2 push: check pushed ref for --force-if-includesTyler Cipriani, Sep 14, 2026
  24. 1/2 push: check pushed ref for --force-if-includesTyler Cipriani, Sep 14, 2026
  25. 2/2 push: fix --force-if-includes non-branch adviceTyler Cipriani, Sep 14, 2026
  26. D. Ben KnobleSep 14, 2026
  27. Tyler CiprianiSep 14, 2026
  28. D. Ben KnobleSep 14, 2026
  29. 0/3 push: check pushed ref for --force-if-includesTyler Cipriani, Sep 15, 2026
  30. 1/3 push: check pushed ref for --force-if-includesTyler Cipriani, Sep 15, 2026
  31. 2/3 push: fix --force-if-includes non-branch adviceTyler Cipriani, Sep 15, 2026
  32. 3/3 push: --force-if-includes should allow fast-forwardTyler Cipriani, Sep 15, 2026
  33. D. Ben KnobleSep 16, 2026
  34. Tyler CiprianiSep 16, 2026
  35. Ben KnobleSep 16, 2026
  36. 0/3 push: check pushed ref for --force-if-includesTyler Cipriani, Sep 17, 2026
  37. 1/3 push: check pushed ref for --force-if-includesTyler Cipriani, Sep 17, 2026
  38. 2/3 push: fix --force-if-includes non-branch adviceTyler Cipriani, Sep 17, 2026
  39. 3/3 push: --force-if-includes should allow fast-forwardTyler Cipriani, Sep 17, 2026
  40. Tyler CiprianiOct 5, 2026

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.