Fossil User Forum

fossil’s commit visualization is much better
Login

fossil’s commit visualization is much better

fossil's commit visualization is much better

(1) By seeg on 2024-11-12 09:19:10 [link] [source]

Hello,

I've recently started to use git squash in one project, so that the branch history remains "nice". Previously I used just git merge which has the drawback of producing a complex tree like this one:

https://codeberg.org/forgejo/forgejo/graph

However, it quickly turned out that whenever I want to merge in upstream changes, I have to resolve the same conflicts over and over. It seems a known issue with squash:

https://stackoverflow.com/questions/11797904/git-merge-squash-and-recurring-conflicts

This got me thinking that people want a nice visualization and instead of fixing the presentation layer, they go into the rebase/squash/amend land, overwriting their history just to have it nicely presented.

On the other hand, fossil's presentation layer is much better:

https://sqlite.org/src/timeline?udc=1&ss=m&n=100&y=ci&advm=0

There's lots of information and the graph isn't too heavy on my cognitive load.

I think this could be a strong point when having a fossil vs git discussion.

(2.1) By Konstantin Khomutov (kostix) on 2024-11-12 09:41:18 edited from 2.0 in reply to 1 [link] [source]

I've recently started to use git squash in one project, so that the branch history remains "nice".

That's obviously an anti-pattern (I admit you came to the same conclusion).

The use case for squashing is lumping multiple "clueless" commits into one (I mean, a series of "try this thing" / "now try that thing" commits).

Previously I used just git merge which has the drawback of producing a complex tree like this one:
[…]
fossil's presentation layer is much better:

Git does not have this presentation problem either. If you merge in a sensible way, avoiding "the diamond history" situation, (that is, you merge "side" branches into the branches they were forked off, and not vice-versa), the question of having simple history is to use the --first-parent command-line option to git log.

You can read more on this, say, here.

Various Git history visualisation tools, including its stock gitk, render something quite close to what you showed — albeit with more vertical lines, I admit ;-)


To automate resolution of recurring conflicts (usually with repeated git rebases on long-lived feature branches), Git has git rerere. Not that you'd need it for the case being discussed; just mentioned for completeness.

(3) By Richard Hipp (drh) on 2024-11-12 11:50:38 in reply to 2.1 [link] [source]

Git does not have this presentation problem

That has not been my experience. Yes, you can use things like gitk and even some other packages that work even better to see a graph of changes in Git. But there are limitations:

  1. All of these require that you have a local Git checkout for the repository of interest. None (that I have found) allow you to see a history graph in a web page. GitHub does not provide this capability, at least not in a usable way. Whenever I try to use GitHub, I always come away frustrated that I can only see a single branch at a time, not the whole tree.

  2. I'm not aware of any Git visualization tools that allow you to do things like click on a pair of check-ins to see a diff between them, or to get a tarball for a particular check-in, or to specify just two or three branches to view and ignore the rest, or to see the history of a single branch together with its merges into and out of other branches.

  3. Git does not do a good job of giving visualizations to ancient history for a project. The visualization tools all want to show you the recent changes. I often need to go back and review change history from years ago. As an extreme example, here is a graph of the first 10 check-ins to Fossil itself: https://fossil-scm.org/home/timeline?a=2007-01-01&n=10. How can you see the first 10 check-ins to Git?

If you merge in a sensible way, avoiding "the diamond history" situation

"Diamond history" (if I understand what you mean by that) can be quite useful. An example of this is the bv-corrections01 branch that is still underway in Fossil. There are frequent merges of trunk into bv-correcions01, and occasionally merges from bv-corrections01 back into trunk. The two branches are kind of running in parallel with periodic synchronization between them. Fossil has no issues with this and does not give any problems with merges in either direction. And the merge history is very clear in the graph.

(5) By seeg on 2024-11-12 12:51:26 in reply to 3 [link] [source]

GitHub does have graph visualizations but they're awful.

https://github.com/twentyhq/twenty/network

The codeberg link I mentioned above is much better: https://codeberg.org/forgejo/forgejo/graph. However, it seems I can't set the number of commits per page and, on my machine, it seems to load in about the same speed as fossil's timeline for 1000 commits of sqlite. It seems fossil is superior in showing larger history. Or maybe that's still on todo on forgejo. Anyways, having an input box to specify an arbitrary number of commits in history (like on fossil's timelime) is quite brave, as with inputting large numbers you could kill the server (that is, if fossil weren't performant in showing history).

(6) By seeg on 2024-11-12 12:54:54 in reply to 3 [link] [source]

"Diamond history" (if I understand what you mean by that) can be quite useful. An example of this is the bv-corrections01 branch that is still underway in Fossil. There are frequent merges of trunk into bv-correcions01, and occasionally merges from bv-corrections01 back into trunk. The two branches are kind of running in parallel with periodic synchronization between them. Fossil has no issues with this and does not give any problems with merges in either direction. And the merge history is very clear in the graph.

The link you provided is exactly the thing I'm talking about: a long-running branch with merges back and forth. With git, it would be an uncomprehensible mess of a growing tree of nodes.

(7) By brickviking on 2024-11-13 06:46:30 in reply to 6 [link] [source]

The nearest I can get to it is this link here. It looks a little messy and has to be panned to see the detail, but it's still (mostly) understandable. I'd hate to see the sqlite version in this.


RTDoc brickviking
(Post 54)

(8) By brickviking on 2024-11-13 06:52:55 in reply to 7 [link] [source]

Oooo, apologies - I'd forgotten to read the earlier post, where this was referenced. Sorry about the duplication folks folks.


RTDoc brickviking
(Post 55)

(9) By Richard Hipp (drh) on 2024-11-13 11:44:19 in reply to 6 [link] [source]

Git does not track branches. It only tracks leaves. The original branch for historical check-ins is not retained. If there are no merges in between a leaf and an historical check-in, then the branch of the historical check-in can be inferred. But if merges occur, the original branch of the historical check-in is lost.

For this reason, sensible display of a diamond history is not possible with Git. That is probably why diamond history is discouraged among Git users.

(10) By Konstantin Khomutov (kostix) on 2024-12-04 07:10:19 in reply to 9 [link] [source]

But if merges occur, the original branch of the historical check-in is lost.

For this reason, sensible display of a diamond history is not possible with Git. That is probably why diamond history is discouraged among Git users.

No, not really. This is indeed one reason, but the main one is based on the premise that if a series of commits "is not ready yet" and needs to be rebased on the updated state of the line of development it was originally based on, you actually rebase it — instead of merging that updated line of development into your side/feature branch.

(I'm well aware Fossil is based on a radically different approach to this, so I'm not advocating that of Git, merely explaining the reasoning.)

(11) By Richard Hipp (drh) on 2024-12-04 11:09:11 in reply to 10 [source]

A rebase in Git essentially the same thing as a merge; the only difference is that a rebase (intentionally) forgets the merge parent. See section 2.1 of https://fossil-scm.org/home/doc/trunk/www/rebaseharm.md.

The bv-corrections10 branch is a recent example of a diamond merge pattern in use. Are you saying that it would be preferable if the merge errors going from trunk over to bv-corrections01 were omitted, thus making those merges into rebases, and keeping only the merge arrows going from bv-corrections01 back to trunk? If you want to, we could start calling the arrows from trunk to bv-corrections01 "rebase arrows" rather than "merge arrows". We could paint such arrows in a different color perhaps. But is that helpful in some way? How does either omitting the rebase arrows entirely, or else showing them in a different style, improve situational awareness? How does that make the change history of the project clearer?

(4) By seeg on 2024-11-12 12:48:04 in reply to 2.1 [link] [source]

As I understand, "diamond history" affects long-running branches. Well, thing is I have to merge with upstream sometimes, resolving conflicts on the way. My preferred solution was to use "merge" all the time. It provided me with few conflicts and a good reflection of history. Drawback was the complex graph. With no upstream merges, whether it's squash or plain merge, the graph looks simpler.