]> git.ipfire.org Git - thirdparty/git.git/commitdiff
checkout: omit "tracking" information on a detached HEAD
authorJunio C Hamano <gitster@pobox.com>
Sat, 30 Mar 2024 21:37:14 +0000 (14:37 -0700)
committerJunio C Hamano <gitster@pobox.com>
Sun, 31 Mar 2024 00:53:25 +0000 (17:53 -0700)
By definition, a detached HEAD state is tentative and there is no
configured "upstream" that it always wants to integrate with.  But
if you detach from a branch that is behind its upstream, e.g.,

    $ git checkout -t -b main origin/main
    $ git checkout main
    $ git reset --hard HEAD^
    $ git checkout --detach main

you'd see "you are behind your upstream origin/main".  This does not
happen when you replace the last step in the above with any of these

    $ git checkout HEAD^0
    $ git checkout --detach HEAD
    $ git checkout --detach origin/main

Before 32669671 (checkout: introduce --detach synonym for "git
checkout foo^{commit}", 2011-02-08) introduced the "--detach"
option, the rule to decide if we show the tracking information
used to be:

    If --quiet is not given, and if the given branch name is a real
    local branch (i.e. the one we can compute the file path under
    .git/, like 'refs/heads/master' or "HEAD" which stand for the
    name of the current branch", then give the tracking information.

to exclude things like "git checkout master^0" (which was the
official way to detach HEAD at the commit before that commit) and
"git checkout origin/master^0" from showing tracking information,
but still do show the tracking information for the current branch
for "git checkout HEAD".  The introduction of an explicit option
"--detach" broke this subtley.  The new rule should have been

    If --quiet is given, do not bother with tracking info.
    If --detach is given, do not bother with tracking info.

    Otherwise, if we know that the branch name given is a real local
    branch, or if we were given "HEAD" and "HEAD" is not detached,
    then attempt to show the tracking info.

but it allowed "git checkout --detach master" to also show the
tracking info by mistake.  Let's tighten the rule to fix this.

Reported-by: mirth hickford <mirth.hickford@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/checkout.c
t/t2020-checkout-detach.sh

index 2e8b0d18f445b1307e264634f69c8ce0a3a5c68a..26e1a64569d4fb91b44cd4e8cac0951fb8f48b95 100644 (file)
@@ -1030,7 +1030,8 @@ static void update_refs_for_switch(const struct checkout_opts *opts,
        remove_branch_state(the_repository, !opts->quiet);
        strbuf_release(&msg);
        if (!opts->quiet &&
-           (new_branch_info->path || (!opts->force_detach && !strcmp(new_branch_info->name, "HEAD"))))
+           !opts->force_detach &&
+           (new_branch_info->path || !strcmp(new_branch_info->name, "HEAD")))
                report_tracking(new_branch_info);
 }
 
index bce284c2978848967ffe88764e396fad5059df54..8d90d0285045294b3f39233957ea4487bc7929e0 100755 (executable)
@@ -176,7 +176,10 @@ test_expect_success 'tracking count is accurate after orphan check' '
        git config branch.child.merge refs/heads/main &&
        git checkout child^ &&
        git checkout child >stdout &&
-       test_cmp expect stdout
+       test_cmp expect stdout &&
+
+       git checkout --detach child >stdout &&
+       test_grep ! "can be fast-forwarded\." stdout
 '
 
 test_expect_success 'no advice given for explicit detached head state' '