Skip to content

Conversation

o-kloster
Copy link
Contributor

Fixes #5782
Improves on #9050

Proposed changes

  • As of now, segments in the revision graph are straightened only of they contain no intermediate commits (i.e. it's just one segment). This change allows straightening also when there are intermediate commits and/or merges.

Screenshots

Before

image

After

image

Test methodology

  • Manual with GE repo
  • Unit tests verify the graph layout

Test environment(s)

  • Git Extensions 33.33.33
  • Build 8d82309
  • Git 2.36.0.windows.1 (recommended: 2.38.1 or later)
  • Microsoft Windows NT 10.0.19044.0
  • .NET 6.0.14
  • DPI 96dpi (no scaling)

Merge strategy

I agree that the maintainer squash merge this PR (if the commit message is clear).


✒️ I contribute this code under The Developer Certificate of Origin.

@ghost ghost assigned o-kloster Feb 27, 2023
@o-kloster o-kloster changed the title O kloster/straighten segments O-kloster/straighten segments Feb 27, 2023
@o-kloster o-kloster changed the title O-kloster/straighten segments O kloster/straighten segments Feb 27, 2023
@o-kloster o-kloster changed the title O kloster/straighten segments Straighten revision graph in more cases Feb 27, 2023
@gerhardol
Copy link
Member

@o-kloster @mstv Merge this and #10637 ?

@mstv
Copy link
Member

mstv commented Feb 27, 2023

Merge this and #10637 ?

These two PRs are orthogonal and work well together.


These changes look promising. There are edge cases though - as most of the time...

The yellow area is unused space without benefit for the curves of the pink segments.
c20fe54803f3b6875f0b19302e85d5f2b415576c before / after:

image image

@o-kloster o-kloster marked this pull request as draft March 1, 2023 15:36
@o-kloster
Copy link
Contributor Author

I've found a few cases where the PR does not behave as desired. I'll be back with fixes.

@o-kloster
Copy link
Contributor Author

Ok, I've fixed the issues that I found:

  • Straightening could lead to increasing the width of the graph.
  • Straightening could lead to other segments becoming curved or shifting across more lanes than before.

The latter can also happen in the current version of GE, although more rarely. An example is at e75b40425321694fbf6f91f6898cdec18c4b739c:

Today With PR
image image

@o-kloster o-kloster marked this pull request as ready for review March 3, 2023 09:52
@mstv
Copy link
Member

mstv commented Mar 3, 2023

Apart from cases like the following, many parts of the graph clearly look better.

4.0.2 / This PR above 885eb0c59f0f4ae11b8b510fec962b17df27ff0f

image image

The violet segment should be kept straight. There are no nodes in it.

Straightening could lead to increasing the width of the graph.

This is not a strict rule IMO. I think a few additional lanes should be accepted.
In this example, the graph even has the same width.

@RussKie
Copy link
Member

RussKie commented Mar 4, 2023

Ok, I've fixed the issues that I found:

  • Straightening could lead to increasing the width of the graph.
  • Straightening could lead to other segments becoming curved or shifting across more lanes than before.

The latter can also happen in the current version of GE, although more rarely. An example is at e75b40425321694fbf6f91f6898cdec18c4b739c:

Today With PR
image image

Looking at this specific sample, I wonder if we could do this?
image

@RussKie
Copy link
Member

RussKie commented Mar 4, 2023

4.0.2 / This PR above 885eb0c59f0f4ae11b8b510fec962b17df27ff0f

image image

The violet segment should be kept straight. There are no nodes in it.

Straightening could lead to increasing the width of the graph.

This is not a strict rule IMO. I think a few additional lanes should be accepted. In this example, the graph even has the same width.

Is is possible to avoid the "bump" on the second lane? It'd allow avoiding all subsequent "bumps"...
image

@mstv
Copy link
Member

mstv commented Mar 4, 2023

Is is possible to avoid the "bump" on the second lane? It'd allow avoiding all subsequent "bumps"...
image

👍 Yes, this would be a valid graph. Though only, because the reason for the "bump" is the node in the left lane.
I.e. there is no risk that the crossing segments get in conflict with a node.
It is crucial that one can distinguish whether the segments just cross each other or whether there is a junction.

But image would turn into image. This might be confusing although still unambiguous.

The following (not occurring) graph would be definitely unclear:
image

Since crossings and junctions cannot clearly be distinguished, your first suggestion is problematic.
With the diagonals drawn by #10637, it might be doable - as long as there are no nodes or perpendicular segments in the way as in this:
image

Anyway, both proposals affect an even lower layer ("lane creation / selection") than this PR ("lane shifting") or #10637 ("segment drawing").
So they should be addressed in follow-up PRs.

@mstv
Copy link
Member

mstv commented Mar 4, 2023

Conflicting files: contributors.txt

Could you file your sign off in a separate PR, please, @o-kloster?

@mstv
Copy link
Member

mstv commented Mar 6, 2023

grafik

@o-kloster
Copy link
Contributor Author

4.0.2 / This PR above 885eb0c59f0f4ae11b8b510fec962b17df27ff0f

image image

The violet segment should be kept straight. There are no nodes in it.

Fixed in latest update. The rule against increasing the width has been relaxed somewhat.

Straightening could lead to increasing the width of the graph.

This is not a strict rule IMO. I think a few additional lanes should be accepted.

While I agree, I'm not sure how to formulate this precisely and fear the logic might become complex. It could quickly turn into an optimization problem of width against straightness.

As for the need to keep the width in check at all, you can see an example if you run the first version of this PR on 6d5defb20f78f52c21882c71fb68029ba1b642e5 and onward:

image

@o-kloster
Copy link
Contributor Author

Conflicting files: contributors.txt

Could you file your sign off in a separate PR, please, @o-kloster?

Done in #10791

@o-kloster
Copy link
Contributor Author

grafik

Which commit is this?

@mstv
Copy link
Member

mstv commented Mar 7, 2023

Which commit is this?

This example is from a private company repo.

@mstv
Copy link
Member

mstv commented Mar 7, 2023

There still is a too attracting condition:

3644218d8a7954db2b29e4b1af85b564a5edc28c

image

ca7e05c421c7c3b80eb97dd2a785be543ceb92bf

image

Copy link
Member

@mstv mstv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unfinished review

/// If this row is the parent row of <paramref name="segment"/>, returns the segment leading
/// to this row's first parent (if any). Otherwise, returns <paramref name="segment"/>.
/// </summary>
public RevisionGraphSegment FirstParentOrSelf(RevisionGraphSegment segment)
Copy link
Member

@mstv mstv Mar 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it should rather be SelfOrFirstParent in order to keep the segment straight as far as possible.
Only if it ends, take the first parent as continuation.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first parent should only be chosen for the first child. If coming from another child, the segment should not be continued.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it should rather be SelfOrFirstParent in order to keep the segment straight as far as possible. Only if it ends, take the first parent as continuation.

Are you arguing for just a name change, or for a functionality change? SelfOrFirstParent and FirstParentOrSelf are essentially the same, since the segment cannot both continue and have a parent in this row. But I opted for the latter since it returns self also in the case where the segment ends and has no parent segment.

The first parent should only be chosen for the first child.

I considered this. But how do you define the 'first' child segment? By order in the Segments list? By lane order in the row above (is this the same?)? By distance to the row of the child revision? In each case, I think I can find an example where this would lead to less straightening than desired.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SelfOrFirstParent and FirstParentOrSelf are essentially the same, since the segment cannot both continue and have a parent in this row. But I opted for the latter since it returns self also in the case where the segment ends and has no parent segment.

👍 Thank you for the explanation. I agree.
(From just reading if (segment.Parent != Revision), I do not get the meaning without looking into the docs of all these properties. Let's think about inversion and comments later when we have an agreed implementation.)

I was just dropping guesses how to avoid the yellow segment being bent one lane to the right unnecessarily early (resulting in the free lane under the mouse cursor).
The cyan branch is branched from and back to the yellow branch - at least as I read the graph.
The cyan branch should not "attract" the yellow branch (although it would save one bend for the cyan branch without adding one to the yellow branch).

I considered this. But how do you define the 'first' child segment? By order in the Segments list? By lane order in the row above?

👍
The yellow branch is the "first", the cyan one is the "second" and should not be continued with the ancestor.

(is this the same?)

I guess yes. Though this is not guaranteed. It depends on the sorting algorithm. I am experimenting with an (immature) alternative in my private build.
Using GetLaneIndexForSegment() will be safe and shouldn't be too expensive.

image image

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, the above seems to be not caused by this PR. The yellow and the cyan segments share the same lane since they have the same parent.
Since StraightenLanes operates on single segments, it cannot be detected / avoided not easily.
So I am dropping this part of the request.

@mstv

This comment was marked as outdated.

@o-kloster
Copy link
Contributor Author

This example is from a private company repo.

Could you show more of the graph? I don't see how to reproduce this. The two leftmost segments (yellow and blue) should have gotten the same lane, since neither connects to the revision of the first row, right?

@o-kloster

This comment was marked as resolved.

- if any affected row becomes wider than the row immediately before the affected rows
- if an already straight segment gets bent, or a segment shifting across lanes ends up
  shifting across more lanes than before
Before: Not more that the width of the row immediately above the changed rows
Now: Not more than the max existing width nearby (up to lookahead distance above or below)
@o-kloster o-kloster force-pushed the o-kloster/straightenSegments branch from 37ba8d8 to ba94923 Compare March 8, 2023 17:36
@mstv
Copy link
Member

mstv commented Mar 8, 2023

The two leftmost segments (yellow and blue) should have gotten the same lane, since neither connects to the revision of the first row, right?

In theory yes. But that's not the point. This is just caused by that I prefer a clearer graph where all branches fan out at their parent: 73e6a83

Could you show more of the graph? I don't see how to reproduce this.

I found it in the GE repo, too, at 083eef2e2c5030354bb33cefd14e233c58f72e41 "Merge pull request 5009":

Current | This PR

image image

@RussKie
Copy link
Member

RussKie commented Mar 11, 2023

💭 I wonder if we should consider allowing a branch to be on the left side as well if space allows it, e.g.:
image

@RussKie
Copy link
Member

RussKie commented Mar 11, 2023

Current | This PR

image image

I kind of like the left one better - it's "straighter", easier to follow.

@RussKie
Copy link
Member

RussKie commented Mar 29, 2023

So where are we with this?

@RussKie RussKie added the 📭 needs: author feedback More info/confirmation awaited from OP; issues typically get closed after 30 days of inactivity label Mar 29, 2023
@mstv
Copy link
Member

mstv commented Mar 29, 2023

So where are we with this?

Let's take #10842 first (perhaps after v4.1). Then StraightenLanes() is called more consistently.

Open:

  • only switch to ancestor from 'first' child segment
  • Bulges like the following need to be straightened again yet:

image

@mstv
Copy link
Member

mstv commented Apr 1, 2023

#10842 has been merged. It calls StraightenLanes() more consistently. There shouldn't be many conflicts when rebasing.

@ghost ghost added the 💤 status: no recent activity The issue is stale label Apr 22, 2023
@ghost
Copy link

ghost commented Apr 22, 2023

This pull request has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 14 days. It will be closed if no further activity occurs.

This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
📭 needs: author feedback More info/confirmation awaited from OP; issues typically get closed after 30 days of inactivity 🖊️ status: cla signed status: abandoned 💤 status: no recent activity The issue is stale
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Readability revision graph
4 participants