martinvonz / jj

A Git-compatible VCS that is both simple and powerful
https://martinvonz.github.io/jj/
Apache License 2.0
9.32k stars 321 forks source link

ShortestIdPrefix.rest() returning empty string #4932

Closed J-tt closed 20 hours ago

J-tt commented 1 day ago

Description

Not sure if this is user error, but been unable to get the shortestIdPrefix.rest() function to return the remainder of the prefix.

Steps to Reproduce the Problem

  1. run jj log --color never --no-graph -r @ --no-pager -T 'self.change_id().shortest().rest()'

Expected Behavior

Remainder of the change_id prefix is echoed into the terminal

Actual Behavior

No characters are output

Specifications

yuja commented 1 day ago

You'll need to specify the minimum length e.g. .shortest(10). The default is 0, so .rest() is always empty.

martinvonz commented 1 day ago

What were you hoping it would return?

J-tt commented 21 hours ago

@yuja even specifying the minimum length returns a blank string:

jj log --color never --no-graph -r @ --no-pager -T 'self.change_id().shortest(1).rest()'

@martinvonz ideally the remainder of the short change_id, for context I'm trying to replicate the highlighting of the change ids in a terminal prompt.

Here's what I've got so far, based on the sunakayu theme shared (and requiring the oh-my-zsh plugin): https://gist.github.com/J-tt/f33f2c6e16be1e8c2f3c6265d64f035a

martinvonz commented 20 hours ago

It's not very obvious but the ShortestIdPrefix contains both the unique prefix and the rest of the string up to the specified length (or more if it's not enough to make it unique). We use a minimum of 8 by default: https://github.com/martinvonz/jj/blob/e060ef20c132cae57fb5698d23ff071a0200bc10/cli/src/config/templates.toml#L163-L165

ilyagr commented 20 hours ago

@yuja even specifying the minimum length returns a blank string:

jj log --color never --no-graph -r @ --no-pager -T 'self.change_id().shortest(1).rest()'

This will work if you change the 1 to an 8, or 32 (which I think will give you the behavior you originally expected; it's the length of the change ids AFAIK), or 999 if you want to be safe for any ids of length < 999 (commit ids are slightly longer than change ids, at 40 bytes).

What shortest(8) does is compute the unique prefix and put it into the first half (whatever that's called), not matter how long that is. Now, if the prefix is shorter than 8, shortest(8).rest() will contain enough characters of the rest of the id to make the total length of .shortest(8) equal to 8.

shortest(999) will always include the entire id, as I think you expected.

J-tt commented 20 hours ago

Ooh right, okay I think I get how it works, just a bit counterintuitive but makes sense. I might throw up a PR for the documentation to make it a bit clearer if I get a chance!

Thanks everyone for your help!

J-tt commented 19 hours ago
image

Looks good! Thanks everyone again :)