Repository: iterative/dvc

Issue:
`exp show`: branch name containing path separator not returned for HEAD
# Bug Report

> From https://github.com/iterative/vscode-dvc/issues/1946

## Description

<!--
A clear and concise description of what the bug is.
-->

`exp show` will not return the full name of a branch for the HEAD revision if it contains a path separator. 

This causes two issues in the extension: 
1. The wrong name is shown in our experiments table.
2. We call `plots diff` with the incomplete branch name and it fails (we use the name to fetch the HEAD revision).

e.g when the branch name is `readme/known-limitations` the output is as follows:

```bash
/vscode-dvc/demo readme/known-limitations *1 !2 ❯ dvc exp show --show-json
{
  "workspace": {
  ...
  },
  "4d78b9e7158ee1d6504028f79f65daf48d2d9af3": {
    "baseline": {
      "data": {
       ...
        "name": "known-limitations"
      }
    }
  }
}
```

### Reproduce

<!--
Step list of how to reproduce the bug
-->

<!--
Example:

1. dvc init
2. Copy dataset.zip to the directory
3. dvc add dataset.zip
4. dvc run -d dataset.zip -o model ./train.sh
5. modify dataset.zip
6. dvc repro
-->

1. checkout a branch with a name which includes a file path separator (e.g `readme/known-limitations`)
2. run `exp show`
3. the last part of the branch name will be returned as the name for the HEAD commit (e.g `known-limitations`).

### Expected

<!--
A clear and concise description of what you expect to happen.
-->

`exp show` returns the full branch name including file separators.

### Environment information

<!--
This is required to ensure that we can reproduce the bug.
-->

**Output of `dvc doctor`:**

```console
$ dvc doctor
DVC version: 2.11.0 (brew)
---------------------------------
Platform: Python 3.9.13 on macOS-12.4-x86_64-i386-64bit
Supports:
        azure (adlfs = 2022.4.0, knack = 0.9.0, azure-identity = 1.10.0),
        gdrive (pydrive2 = 1.10.1),
        gs (gcsfs = 2022.5.0),
        webhdfs (fsspec = 2022.5.0),
        http (aiohttp = 3.8.1, aiohttp-retry = 2.4.6),
        https (aiohttp = 3.8.1, aiohttp-retry = 2.4.6),
        s3 (s3fs = 2022.5.0, boto3 = 1.21.21),
        ssh (sshfs = 2022.6.0),
        oss (ossfs = 2021.8.0),
        webdav (webdav4 = 0.9.7),
        webdavs (webdav4 = 0.9.7)
Cache types: reflink, hardlink, symlink
Cache directory: apfs on /dev/disk1s5s1
Caches: local
Remotes: s3
Workspace directory: apfs on /dev/disk1s5s1
Repo: dvc (subdir), git
```

**Additional Information (if any):**

<!--
Please check https://github.com/iterative/dvc/wiki/Debugging-DVC on ways to gather more information regarding the issue.

If applicable, please also provide a `--verbose` output of the command, eg: `dvc add --verbose`.
If the issue is regarding the performance, please attach the profiling information and the benchmark comparisons.
-->

Please LMK if this behaviour is by design. Thank you.

Original issue: https://github.com/iterative/vscode-dvc/issues/1946

I have tested to see if calling `dvc plots diff nested/branch` works and it fails if there are any static plots involved. I will raise a separate issue for this.



Discussion:
For experiments this is expected and intentional, exp names are not allowed to contain slashes (even though they are valid in git refs)

see: https://github.com/iterative/dvc/pull/6848#issuecomment-950487613

e: reopened since for branches/tags we should still display them with the slash
@mattseddon can we do a workaround for now ... pass hash id instead into `dvc plots diff`? 
I have been looking at how to make that hack. I would need to create a mapping between the name and the sha but the fix is not as simple as you would initially think. The returned plots data will have the hash id all through it as the rev field. We will have to replace all instances of that hash id in the data in order to show the semi-correct name in the UI/show the correct plots data.
> The returned plots data will have the hash id all through it as the rev field

Yes, and it might be fine for now as a workaround for names that we know are problematic, wdyt? Image plots will be fine, trends also (?), only plots like confusion matrixes will have these hash ids?

> e: reopened since for branches/tags we should still display them with the slash

What's the level of effort to support it?

> For experiments this is expected and intentional, exp names are not allowed to contain slashes (even though they are valid in git refs)
> 
> see: [#6848 (comment)](https://github.com/iterative/dvc/pull/6848#issuecomment-950487613)

The comment suggests hesitance to support slashes because the exp refs conventions aren't stable enough. Do you still have those concerns @pmrowla?
This is just a UI issue, it is separate from the "should exp names be allowed to contain slashes" question. The problem here is that if you have a git branch named `foo/bar`, we display it as `bar` due to something parsing git branches by splitting at the last path separator.

Exp names should still be prohibited from having slashes. But git branches and tags are allowed to have slashes, and we need to display them properly in DVC commands
If it's a small effort, could we please address this? 
> If it's a small effort, could we please address this?

I will open P.R. later

Resolving patch:
diff --git a/dvc/repo/experiments/show.py b/dvc/repo/experiments/show.py
--- a/dvc/repo/experiments/show.py
+++ b/dvc/repo/experiments/show.py
@@ -100,11 +100,10 @@ def _collect_experiment_commit(
                 for refspec in ["refs/tags", "refs/heads"]:
                     name = repo.scm.describe(rev, base=refspec)
                     if name:
+                        name = name.replace(f"{refspec}/", "")
                         break
-            if not name:
-                name = repo.experiments.get_exact_name(rev)
+            name = name or repo.experiments.get_exact_name(rev)
             if name:
-                name = name.rsplit("/")[-1]
                 res["name"] = name
 
     return res
@@ -117,7 +116,7 @@ def _collect_experiment_branch(
     baseline,
     onerror: Optional[Callable] = None,
     running=None,
-    **kwargs
+    **kwargs,
 ):
     from dvc.scm import resolve_rev
 
@@ -132,7 +131,7 @@ def _collect_experiment_branch(
             onerror=onerror,
             status=status,
             running=running,
-            **kwargs
+            **kwargs,
         )
         if len(revs) > 1:
             exp = {"checkpoint_tip": exp_rev}


Test patch:
diff --git a/tests/func/experiments/test_show.py b/tests/func/experiments/test_show.py
--- a/tests/func/experiments/test_show.py
+++ b/tests/func/experiments/test_show.py
@@ -48,6 +48,21 @@ def test_show_no_commits(tmp_dir):
     assert Repo.init().experiments.show() == {}
 
 
+@pytest.mark.vscode
+def test_show_branch_and_tag_name(tmp_dir, scm, dvc, exp_stage):
+    with tmp_dir.branch("new/branch", new=True):
+        tmp_dir.scm_gen("branch", "branch", "commit")
+        branch_rev = scm.get_rev()
+
+    result = dvc.experiments.show(all_branches=True)
+    assert result[branch_rev]["baseline"]["data"]["name"] == "new/branch"
+
+    scm.tag("new/tag")
+    tag_rev = scm.get_rev()
+    result = dvc.experiments.show(all_tags=True)
+    assert result[tag_rev]["baseline"]["data"]["name"] == "new/tag"
+
+
 @pytest.mark.vscode
 def test_show_simple(tmp_dir, scm, dvc, exp_stage):
     assert dvc.experiments.show()["workspace"] == {