Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gix worktree list first row appears similar to others but differs in meaning #1649

Open
EliahKagan opened this issue Oct 29, 2024 · 1 comment
Labels
acknowledged an issue is accepted as shortcoming to be fixed help wanted Extra attention is needed

Comments

@EliahKagan
Copy link
Member

EliahKagan commented Oct 29, 2024

Current behavior 😯

The output of gix worktree list (introduced in c7213bc in #1465) is a table of paths and names, but one of the names is usually a branch name, while others are usually directory names. Even if intended, the names are presented in a way that inadvertently obscures this distinction, so the output is easy to misread. Specifically, in the absence of errors, the output consists of:

  • First, a row showing the path of a detected current working tree, typically based on the current directory, and a branch name. This first row may be omitted if no such working tree is found, such as in a bare repository to which no separate (i.e. linked) worktrees have been added.

    if let Some(worktree) = repo.worktree() {
    writeln!(
    out,
    "{base} [{branch}]",
    base = gix::path::realpath(worktree.base())?.display(),
    branch = repo
    .head_name()?
    .map_or("<detached>".into(), |name| name.shorten().to_owned()),
    )?;
    }

  • Then, zero or more rows, one for each detected separate (i.e. linked) worktree, each showing the path of the worktree, and the worktree name. This worktree name is related to the location of the worktree, but not (except by coincidence) related to the name of a branch checked out in the worktree.

    for proxy in repo.worktrees()? {
    writeln!(
    out,
    "{base} [{name}]",
    base = proxy.base()?.display(),
    name = proxy.id()
    )?;
    }

But the rows are formatted similarly, so they intuitively seem to be expressing the same kind of information when they are not. There are two kinds of misleading similarity:

  • The lines are formatted similarly to each other, for example by enclosing all second-column items in square brackets, even though they represent different kinds of things.
  • The lines are formatted similarly to output of git worktree list, in which a square-bracketed name in the final column is always a branch name and never (except by coincidence) a name derived from a location.

Another difference is that the paths shown in the first column are normalized slightly differently in the first row than in others, such that, on Windows, backslashes appear as directory separators in the first row, while (forward) slashes appear as directory separators in subsequent rows. Although this is a separate issue, it is fairy minor and also seems to serve, on Windows, as a mitigation, since it makes it easier to notice that the rows are different, though it does not point to the extent of the difference.

Here's an example in a non-bare repository where git worktree list and gix worktree list are run in the main worktree, where the directory name is gitoxide and the main branch is checked out, as well as in a linked worktree in which the directory name is gitoxide-wt and a wt branch is checked out.

(This example is on Windows so that it also shows the different path styles, but this issue is otherwise not specific to Windows. This is in PowerShell with posh-git. The lines that contain a > are lines in which commands are entered on a prompt, such that all the text of the line up to and including > is the prompt rather than a command or its output. I considered resetting the prompt to be very simple for this demonstration, but I think it is actually clearer with the information shown in these prompts.)

C:\Users\ek\source\repos\gitoxide [main ≡]> git worktree add -b wt ../gitoxide-wt
Preparing worktree (new branch 'wt')
Updating files: 100% (2282/2282), done.
HEAD is now at 417bf95fd Merge pull request #1648 from EliahKagan/run-ci/touch-next
C:\Users\ek\source\repos\gitoxide [main ≡]> git worktree list
C:/Users/ek/source/repos/gitoxide     417bf95fd [main]
C:/Users/ek/source/repos/gitoxide-wt  417bf95fd [wt]
C:\Users\ek\source\repos\gitoxide [main ≡]> gix worktree list
C:\Users\ek\source\repos\gitoxide [main]
C:/Users/ek/source/repos/gitoxide-wt [gitoxide-wt]

This is with the same setup but when gix is run from the linked worktree directory (this was done immediately after the above, with no intervening changes):

C:\Users\ek\source\repos\gitoxide [main ≡]> pushd ../gitoxide-wt
C:\Users\ek\source\repos\gitoxide-wt [wt]> git worktree list
C:/Users/ek/source/repos/gitoxide     417bf95fd [main]
C:/Users/ek/source/repos/gitoxide-wt  417bf95fd [wt]
C:\Users\ek\source\repos\gitoxide-wt [wt]> gix worktree list
C:\Users\ek\source\repos\gitoxide-wt [wt]
C:/Users/ek/source/repos/gitoxide-wt [gitoxide-wt]

Notice how, when run in a linked worktree directory:

  • git worktree list gives the same information as when run in the main worktree.
  • gix worktree list is outputting two lines about the linked worktree, where the first line shows [wt] where wt is a branch name, and the second line shows [gitoxide-wt] where gitoxide-wt is the worktree name associated with its location.

This particular scenario, which will happen anytime gix worktree list is run from a linked worktree, is especially unexpected because it shows two lines for the same worktree and no lines for the main worktree.

Expected behavior 🤔

I think the output of gix worktree list should:

  1. Either show the same kind of information in each row, or present the rows differently (at least with some kind of different notation) so that the kind of information they provide is not likely to be confused.
  2. Either provide the same kind of information as git worktree list, or avoid creating the appearance that it does. Avoiding this without changing the information shown, if that is to be done, could be achieved by using a different notation when information differs--which may also address (1). It may also help to document the format in the output of gix worktree list --help, which currently does not say anything about what information is shown or how it is presented.
  3. In the path column, show paths with the same style (and amount) of normalization in each row, except where there is a reason to do otherwise. But this is the least important aspect. If the different rows intentionally have a different interpretation for the second column (and it is distinguished notationally), then presenting the first-column paths differently may be okay.

Because a worktree name is usually the same as the last component of its directory, it may be less important to show that separately from the path, and I think this is also a further factor that creates the impression that the second column of each row--rather than just the first--would show a branch name.

It's useful to know what branch, if any, one has checked out in each worktree. So this is another possible reason to make the output more similar to that of git.

Git behavior

The most important differences between gix worktree list and git worktree list are shown above in the example under "Current behavior". The other aspect of the difference not discussed is that the output of git worktree list has three columns, with two columns that usually contain refs: it includes a column that shows a (truncated) hash for the commit checked out in the worktree.

Steps to reproduce 🕹

On a machine with gitoxide installed and gix in the $PATH, from the main working tree of a non-bare repository with a least one commit whose HEAD is not currently detached--I used my local gitoxide clone, which is why I named a worktree with a gitoxide- prefix--run:

git worktree add -b wt ../gitoxide-wt
git worktree list
pushd ../gitoxide-wt
git worktree list
gix worktree list

This should work in most Unix-style shells including Bash, as well as in PowerShell on Windows. To observe the / vs. \ distinction, this should be done on Windows; for everything else, any platform should work.

Those commands are presented in the "Current behavior" section above with relevant context.

@Byron Byron added help wanted Extra attention is needed acknowledged an issue is accepted as shortcoming to be fixed labels Oct 30, 2024
@Byron
Copy link
Member

Byron commented Oct 30, 2024

Thanks a lot for bringing this up and for the proposition of viable avenues for improvement.

I think this case perfectly describes the underlying of a misleading API too, where worktree() suggests it's the main worktree even though it is not. After checking the documentation of Repository::worktree() I found it to be correct, and it seems instead of this it should rather use Repository::main_repo() to get the main worktree no matter where it was started from.

Lastly, like already stated here, the output should be adjusted to not be misleading anymore, probably to be much more like Git.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
acknowledged an issue is accepted as shortcoming to be fixed help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants