Message ID | xmqqa5mfl7ud.fsf@gitster.g (mailing list archive) |
---|---|
State | Accepted |
Commit | b9f2e1a684e3729b0278950cd7e930441d84c9f1 |
Headers | show |
Series | checkout: do not bother "tracking" report on detached HEAD | expand |
On Sat, 30 Mar 2024 at 21:37, Junio C Hamano <gitster@pobox.com> wrote: > > 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> > --- > > mirth hickford <mirth.hickford@gmail.com> writes: > > >> git switch --detach main > > HEAD is now at 5a07c3bde Refactor... > > Your branch is behind 'origin/main' by 1 commit, and can be fast-forwarded. > > (use "git pull" to update your local branch) > > > >> git pull > > You are not currently on a branch. > > I think the instruction meant to say "use 'git pull' with > appropriate options to update" but had to ellide the details due > to limited screen real estate. And it is quite expected that a > "git pull" from a detached HEAD would not do anything. > > Because my local branches do not track any upstream branches, I > have little experience with the message in question. Given > that, I doubt that I am the best person to comment on this > issue, but having said that, I observe that this is shared > between "checkout" and "switch". > > Having said that, I think that the instruction is what is wrong. > What is wrong is the fact that the command assumed that you want > to keep up with the upstream of the branch you detached from. > > builtin/checkout.c | 3 ++- > t/t2020-checkout-detach.sh | 5 ++++- > 2 files changed, 6 insertions(+), 2 deletions(-) > > diff --git a/builtin/checkout.c b/builtin/checkout.c > index 2e8b0d18f4..26e1a64569 100644 > --- a/builtin/checkout.c > +++ b/builtin/checkout.c > @@ -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); > } > > diff --git a/t/t2020-checkout-detach.sh b/t/t2020-checkout-detach.sh > index bce284c297..8d90d02850 100755 > --- a/t/t2020-checkout-detach.sh > +++ b/t/t2020-checkout-detach.sh > @@ -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' ' > -- > 2.44.0-413-gd6fd04375f > > > Thanks Junio for the fix. It works for me. Tested-by: M Hickford <mirth.hickford@gmail.com>
M Hickford <mirth.hickford@gmail.com> writes: > Thanks Junio for the fix. It works for me. > > Tested-by: M Hickford <mirth.hickford@gmail.com> Thanks. It is already on 'next' and will be on 'master' sometime next week, hopefully.
diff --git a/builtin/checkout.c b/builtin/checkout.c index 2e8b0d18f4..26e1a64569 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -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); } diff --git a/t/t2020-checkout-detach.sh b/t/t2020-checkout-detach.sh index bce284c297..8d90d02850 100755 --- a/t/t2020-checkout-detach.sh +++ b/t/t2020-checkout-detach.sh @@ -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' '