Fossil Forum

Feature request: TREE command
Login

Feature request: TREE command

Feature request: TREE command

(1) By anonymous on 2021-06-10 12:08:56 [link] [source]

I'd like to propose the addition of tree structure display similar to how the TREE command under Windows (and possibly Linux, don't remember) work. Best if relative to the current or provided branch in case the whole tree is too big to clearly see the branch of interest.

Example: fossil tree while inside trunk branch:

trunk
├───branch1
├───branch2
│   ├───android
│   └───linux
└───branch3
    └───android

and while inside branch2:

branch2
├───android
└───linux

(2) By Stephan Beal (stephan) on 2021-06-10 12:12:39 in reply to 1 [link] [source]

Best if relative to the current or provided branch

What happens when multiple independent branches have the same name? That's perfectly legal (though not necessarily recommended) in fossil.

(3) By anonymous on 2021-06-10 12:16:49 in reply to 2 [link] [source]

If no explicit branch is given, use the current branch.

If explicit branch is given, use the same resolution that TIMELINE and other commands would use.

Or did I miss your point?

(4) By Stephan Beal (stephan) on 2021-06-10 12:34:44 in reply to 3 [link] [source]

Or did I miss your point?

A branch is just a name, so "use the current branch" is not necessarily unambiguous for purposes of a tree view. It us unambiguous for purposes of an update because that name maps directly to a version number in that context. However:

fossil tree my-branch

Might result in any number of independent branches called my-branch, just like:

fossil tree # use current branch

might resolve to any number of unrelated branches with the same name.

How should a hypothetical tree command behave when given a name which has multiple unrelated branches with the same name?

There's also the question of the point in time the tree is rendered from: doing a tree view of the tip of the trunk of a moderately active project is going to create a useless amount of output - a whole jungle of lines (all of which have to be mapped to console output, which is a separate problem altogether). A branch can be closed at any time, meaning that the tree will look different depending on the point in time the tree view is calculated from (assuming closed branches should not be rendered). Branches from trunk come and go, so how should closed branches play into the view?

My point is simply that doing a tree view of a filesystem or process list is only superficially related to doing one for SCM state, the latter having whole barrels of worms to deal with which the former don't. Fossil's ability to reuse branch names makes this even trickier than it would be in, e.g., subversion.

(5) By anonymous on 2021-06-10 13:52:14 in reply to 4 [link] [source]

When you specify a branch name in most commands, you really mean (or that's what you get, anyway) the most recent [1] check-in of that branch.

A branch could also be given by hash (or date and so on as is done with TIMELINE) [2], not necessarily by name. That would also take care of the point-in-time issue in cases of ambiguity.

Multiple same branch names is a non-issue in the same sense that you can point to a specific one (e.g., by hash) the way you would do with other commands. How does one disambiguate with TIMELINE? Same way here.

Unlike [1], starting from the tip of a branch would be practically pointless for a TREE command as chances are that there are no branches off it (yet), and that's not really what you'd be interested, anyway.

So, what I had in my mind is the branch identified by [1] or [2] above would refer to the beginning of that branch. Something like TIMELINE ROOT:BRANCH does. Only that we'd want to start from the first commit of the actual branch and not the commit from which that branch 'escaped' (which is what root: does, I believe).

Closed branches could be viewed with an -a or --all option like it's done with the BRANCH LS command.

As for the width of the tree becoming bigger than the screen's, how would the Windows TREE command deal with that? No idea, I'll have to check and report back.

Most likely I would expect to keep printing to the right and let the terminal wrap around. That way, I could pipe the output to an editor that doesn't wrap it for further examination.

The hardest part for me would be how to represent forks. Perhaps with dotted lines instead of solid ones only for the segment that shows where the fork occurred.

(6) By Stephan Beal (stephan) on 2021-06-10 14:57:47 in reply to 5 [source]

How does one disambiguate with TIMELINE? Same way here.

The timeline doesn't work with branches, it works with versions (hashes) and then calculates the branch name for the version (any given version can have only one branch tag). If you tell the timeline to show you a branch, it resolves (as you point out) to the latest version with that branch. From there, it works with the versions. Branch names are recorded durably but can be renamed at any time, so any tree view based on a branch is equally transient, whereas the version lineage is immutable (with one specific and rare corner case). All lineage calculations work with versions, not branches, though a branch name is frequently used as a shorthand for specifying a version.

We have lots of code and options for following a trail from one version to another, but none (AFAIR) for following from one branch to another.

The hardest part for me would be how to represent forks.

A branch and a fork are the same thing in fossil. We typically use the term "fork" to mean "unintended branch," but that's a human-level distinction. Internally, in fossil's data model, forks and branches are the exact same things.

Most likely I would expect to keep printing to the right and let the terminal wrap around. That way, I could pipe the output to an editor that doesn't wrap it for further examination.

That would seem to be the only really sensible way to handle wide trees.

Warren or Richard may have some ideas about how a tree view could be implemented.

(7) By Warren Young (wyetr) on 2021-06-10 15:43:39 in reply to 6 [link] [source]

We typically use the term "fork" to mean "unintended branch,"

Not just unintended, but also unlabeled. We call a fork in the DAG a "branch" when it has a sym-NAME tag but a "fork" otherwise.

Quoting the "key distinction" from that same linked doc: "A branch is a named, intentional fork."

I don't think much of these worries over the difficulties of finding suitable lookup data in the existing repo metadata to compute the tree view. We can see from the timeline that the info is present. It may take a clever bit of hand-crafted SQL to pull it together efficiently, but it has to be present. The sticky question is, who's bothered enough by the lack of this feature to take the time to implement this SQL and the corresponding Unicode box art rendering code?

Since I've been solicited for ideas for implementing this, I'll point out that Linux also has a tree command, but its source code is GPL'd. I stopped looking at that point, knowing that this made it a hard incompatibility with the Fossil source.

Nevertheless, I expect its externally-visible behavior can be mined for sane solutions to problems like horizontal scrolling beyond the terminal's $COLUMNS value.

(8) By Stephan Beal (stephan) on 2021-06-10 15:52:34 in reply to 7 [link] [source]

We call a fork in the DAG a "branch" when it has a sym-NAME tag but a "fork" otherwise.

That distinction has thus far escaped me but it is a nice, concrete one.

(9) By Andy Bradford (andybradford) on 2021-06-10 19:54:27 in reply to 6 [link] [source]

We typically use the term "fork" to mean "unintended branch," but that's a human-level distinction.

The word "unintended" often connotates something bad or wrong has happened. I have never understood "fork" in Fossil to be a bad or wrong thing---it just is Fossil's way of dealing with conflict---in this sense, the "fork" is 100% always intentional because Fossil did so intentionally to permit the commit (or sync) to succeed. It's like a knife can have good uses and bad uses, but simply stating "knife" one should not immediately assume "murder".

Maybe splitting hairs here, but since I started using Fossil many years ago, one thing I thought was intelligent was the "fork". Better than the way Git handles things.

Andy

(10) By Stephan Beal (stephan) on 2021-06-11 00:26:28 in reply to 9 [link] [source]

The word "unintended" often connotates something bad or wrong has happened.

Fair point. By "unintended" i meant along the lines of "accidental, often caused by a race condition related to syncing with the remote." Not bad, per se, but often not what was intended.

Warren's definition is an excellent improvement over mine, in any case.