# [RFC PATCH 0/2] status: improve info for detached HEAD

3 messages from 2023-02-24 to 2023-02-24. Participants: Roy Eldar.
Thread: https://gitlist.dev/t/59305

## Roy Eldar, 2023-02-24 23:28

Subject: [RFC PATCH 0/2] status: improve info for detached HEAD
Message-ID: <20230224232841.21297-1-royeldar0@gmail.com>
URL: https://gitlist.dev/e/20230224232841.21297-1-royeldar0%40gmail.com

```
When a repository is cloned using "git clone -b" and a tag is specified,
HEAD is automatically detached. As a result, "git status" shows
"currently not on any branch", which is not very useful.

Teach "git status" to generate the "HEAD detached at" message in this
case as well, in a similar way to when a tag is checked out.

In the case of "git checkout", the name of the ref that was checked out
is retrieved from the reflog; for "git clone", the name of the ref isn't
present in the reflog entry, so we use the abbreviated hash instead.
This is also consistent with the "detached HEAD" advice.

Roy Eldar (2):
  t7508: test status output for detached HEAD after clone
  status: improve info for detached HEAD after clone

 t/t7508-status.sh | 12 ++++++++++++
 wt-status.c       |  7 +++++++
 2 files changed, 19 insertions(+)

-- 
2.30.2


```

## Roy Eldar, 2023-02-24 23:28

Subject: [RFC PATCH 1/2] t7508: test status output for detached HEAD after clone
Message-ID: <20230224232841.21297-2-royeldar0@gmail.com>
URL: https://gitlist.dev/e/20230224232841.21297-2-royeldar0%40gmail.com
In-Reply-To: <20230224232841.21297-1-royeldar0@gmail.com>

```
After cloning a repository, HEAD might be detached: for example, when
"--branch" specifies a non-branch (e.g. a tag). In this case, running
"git status" prints 'Not currently on any branch'.

Signed-off-by: Roy Eldar <royeldar0@gmail.com>
---
 t/t7508-status.sh | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/t/t7508-status.sh b/t/t7508-status.sh
index aed07c5b62..d279157d28 100755
--- a/t/t7508-status.sh
+++ b/t/t7508-status.sh
@@ -885,6 +885,18 @@ test_expect_success 'status shows detached HEAD properly after checking out non-
 	grep -E "HEAD detached at [0-9a-f]+" actual
 '
 
+test_expect_success 'status shows detached HEAD properly after cloning a repository' '
+	test_when_finished rm -rf upstream downstream actual &&
+
+	git init upstream &&
+	test_commit -C upstream foo &&
+	git -C upstream tag test_tag &&
+
+	git clone -b test_tag upstream downstream &&
+	git -C downstream status >actual &&
+	grep -E "Not currently on any branch." actual
+'
+
 test_expect_success 'setup status submodule summary' '
 	test_create_repo sm && (
 		cd sm &&
-- 
2.30.2


```

## Roy Eldar, 2023-02-24 23:28

Subject: [RFC PATCH 2/2] status: improve info for detached HEAD after clone
Message-ID: <20230224232841.21297-3-royeldar0@gmail.com>
URL: https://gitlist.dev/e/20230224232841.21297-3-royeldar0%40gmail.com
In-Reply-To: <20230224232841.21297-1-royeldar0@gmail.com>

```
When a remote ref or a tag is checked out, HEAD is automatically
detached, and "git status" says 'HEAD detached at ...', instead of
'Not currently on any branch.'; this is done by traversing the reflog
and parsing an entry like 'checkout: moving from ... to ...'.

In certain situations, HEAD can be detached after "git clone": for
example, when "--branch" specifies a non-branch (e.g. a tag). It is
preferable to avoid displaying 'Not currently on any branch.', so
'HEAD detached at $sha1' is shown instead.

Signed-off-by: Roy Eldar <royeldar0@gmail.com>
---
 t/t7508-status.sh | 2 +-
 wt-status.c       | 7 +++++++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/t/t7508-status.sh b/t/t7508-status.sh
index d279157d28..0ab5bdc1e0 100755
--- a/t/t7508-status.sh
+++ b/t/t7508-status.sh
@@ -894,7 +894,7 @@ test_expect_success 'status shows detached HEAD properly after cloning a reposit
 
 	git clone -b test_tag upstream downstream &&
 	git -C downstream status >actual &&
-	grep -E "Not currently on any branch." actual
+	grep -E "HEAD detached at [0-9a-f]+" actual
 '
 
 test_expect_success 'setup status submodule summary' '
diff --git a/wt-status.c b/wt-status.c
index 3162241a57..f0a5fb578a 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -1632,6 +1632,13 @@ static int grab_1st_switch(struct object_id *ooid UNUSED,
 	struct grab_1st_switch_cbdata *cb = cb_data;
 	const char *target = NULL, *end;
 
+	if (skip_prefix(message, "clone: from ", &message)) {
+		oidcpy(&cb->noid, noid);
+		strbuf_reset(&cb->buf);
+		strbuf_add_unique_abbrev(&cb->buf, noid, DEFAULT_ABBREV);
+		return 1;
+	}
+
 	if (!skip_prefix(message, "checkout: moving from ", &message))
 		return 0;
 	target = strstr(message, " to ");
-- 
2.30.2


```
