Skip to content

Commit b9f2e1a

Browse files
committed
checkout: omit "tracking" information on a detached HEAD
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 3266967 (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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent d6fd043 commit b9f2e1a

File tree

2 files changed

+6
-2
lines changed

2 files changed

+6
-2
lines changed

builtin/checkout.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1030,7 +1030,8 @@ static void update_refs_for_switch(const struct checkout_opts *opts,
10301030
remove_branch_state(the_repository, !opts->quiet);
10311031
strbuf_release(&msg);
10321032
if (!opts->quiet &&
1033-
(new_branch_info->path || (!opts->force_detach && !strcmp(new_branch_info->name, "HEAD"))))
1033+
!opts->force_detach &&
1034+
(new_branch_info->path || !strcmp(new_branch_info->name, "HEAD")))
10341035
report_tracking(new_branch_info);
10351036
}
10361037

t/t2020-checkout-detach.sh

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,10 @@ test_expect_success 'tracking count is accurate after orphan check' '
176176
git config branch.child.merge refs/heads/main &&
177177
git checkout child^ &&
178178
git checkout child >stdout &&
179-
test_cmp expect stdout
179+
test_cmp expect stdout &&
180+
181+
git checkout --detach child >stdout &&
182+
test_grep ! "can be fast-forwarded\." stdout
180183
'
181184

182185
test_expect_success 'no advice given for explicit detached head state' '

0 commit comments

Comments
 (0)