-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
Browse Diff tab menu alternatives and presentation #4569
Browse Diff tab menu alternatives and presentation #4569
Conversation
Codecov Report
@@ Coverage Diff @@
## master #4569 +/- ##
==========================================
+ Coverage 26.68% 27.14% +0.46%
==========================================
Files 501 504 +3
Lines 40752 41009 +257
Branches 5961 5970 +9
==========================================
+ Hits 10873 11132 +259
+ Misses 29379 29367 -12
- Partials 500 510 +10
Continue to review full report at Codecov.
|
acfced4
to
f45512a
Compare
f45512a
to
48d37c0
Compare
48d37c0
to
f2d2424
Compare
fbc734d
to
c5e00e4
Compare
Fixes gitextensions#4564 Fixes gitextensions#4387 Fixes gitextensions#4396 Depends on gitextensions#4562 gitextensions#4663 gitextensions#4365 gitextensions#4366 gitextensions#4367 gitextensions#4368 Submitted to allow review of the outcome to gitextensions#4564 Note: Due to the structure of tests in a separate class, it is very difficult to split this issue in several commits Rewrote RevisionDiffController to make it possible to have some kind of tests. The tests are retrofitted to the current functionality as they are just testing the menu items and not the actions themselves. (The tests adds may more maintenance than they give benefits but the formal test coverage increases.) Browse Diff: Submodules actions available for multi select (gitextensions#4568) Presents the Reset options for the correct parent in multi select situations No longer differ between parent-child and first-second for Reset Difftool: Describes A and B revisions in the menu Difftool arguments depends on parent availability Better detection of parents to A/B for diffs Commit: Limit DiffTool and FileHistory to tracked FormDiff: Limit FileHistory to Tracked Use RevisionDiffController to align to Browse-Diff
…instead of A/Parent and B/Second)
c5e00e4
to
bf40505
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will pull the branch down for closer inspection
GitUI/CommandsDialogs/FormDiff.cs
Outdated
private ContextMenuDiffToolInfo GetContextMenuDiffToolInfo() | ||
{ | ||
bool firstIsParent = _revisionDiffController.IsFirstParent(DiffFiles.Revision.ParentGuids, DiffFiles.SelectedItemParents.Select(i => i.Guid)); | ||
bool localExists = _revisionDiffController.LocalExists(DiffFiles.SelectedItemsWithParent, _fullPathResolver); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this indicates an incorrect use of IFullPathResolver
- behaviors must be injected via constructors and not passed as parameters
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see two two solutions for the relative simple LocalExists() function:
- Add LocalExists() to IFullPathResolver instead
- Duplicate LocalExists() where it is used (two or three modules). A separate interface/class for this seem to be overkill.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add LocalExists() to IFullPathResolver instead
👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I duplicated LocalExists() as it deals with GitItemStatusWithParent.
Probably better to move other similar to a separate class (but FullPathResolver.Resolve() will be duplicated instead).
But I can change again.
b5281f4
to
036a195
Compare
This reverts commit 036a195.
TODO: review RevisionDiffController IsFirstParent and LocalExists as their logic looks odd
…textMenuController
I've have taken liberty and shuffled things around. Referencing I've extracted the common functionality:
Thought? Opinions? |
I am OK with the changes. Will suggest a few name changes, will readd description etc LocalRevisionExists -> AnyLocalFileExists() IsFirstParent()
That was done here
FileStatusListController or FileStatusListContextMenuController would be more logical. |
Disagree. We see a lot of changes coming at a high rate (no one is working here full time).
Speaking of which, to me the logic in both new methods looked very odd.
No probs, let's rename. I like
The reason I created the controller (and other <UI control>Controllers) is to abstract business logic from the UI layer. I have a dream that one day we may be able to use another UI framework, so the UI should do as little as possible. |
Renamed and updated. Did not move more around.
We have had this discussion before and try my best to comply to your vision. But in this situation the tests just takes time and decrease my motivation. These tests are just at the "looks" not at the actual contents. The functionality has to broken down considerably different to meaningful, but that is again a lot more effort. I will try to keep quiet. |
@RussKie |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. Great job with tests!
} | ||
|
||
return true; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to rename the method to AnyFirstAreParentsToSelected
to match the implementation and the doc "True if one of the first selected is parent".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Thinking of it, may be we can change the signature to something like the following?
+ /// <summary>
+ /// Indicates whether any of the provided <param ref="selectedRevision" />'s parents are selected.
+ /// </summary>
+ public bool AnyRevisionParentsSelected(GitRevision selectedRevision, IEnumerable<GitRevision> revisionsSelectedFirst)
I think API becomes slightly more readable:
bool firstIsParent = _revisionDiffController.AnyRevisionParentsSelected(DiffFiles.Revision, DiffFiles.SelectedItemParents);
A rough idea, open to discussion...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The method checks if "True if all of the first selected are parents" so this would be changed behavior
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My bad, misread the logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will be happy to take a discussion why I have done like I have done and to change it to something better. How should this work? Your comment is a good indication of that. I could give some more background tomorrow. The alternative is to take this in follow-up discussions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's be good. I'm finding the API somewhat confusing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR (including the related PRs) primarily improves the diff and presentation of versions. In this process, the menu logic has been updated, some alternatives were not relevant and other were missing. The logic was also changed so testing could be done (testing is for the display, not for the actions so I do not find the tests useful still but they suck less than they would in my first iterations).
For the alternatives, some kind of rules were used:
- With one item selected, the menu items must be relevant
- With multiple items selected, menu items are relevant if at least one item is relevant. For instance if submodules are available if at least one submodule is selected. (There are exceptions to this rule)
In general, the behavior should be the same if the parent-child is selected as if just the "child". It was not like this previously, selecting a parent-child was more limiting.
In some situations selecting the parent, then the selected will provide more information, like the actual parents to parents, that enables those menu items (in diff menu).
AllFirstAreParentsToSelected() is a helper for these situations, this is similar to just selecting one revision.
There are some special handling for merge commits, to show the combined diff like in e51741d. This selects all parents and adds the artificial DiffFiles.CombinedDiff to compare to the Selected revision. The combined diff is shown if only one of the parents to e517 is shown but would be confusing if a non parent was selected.
(So combined diff is shown if at least one parent shown, but no other revision than parents).
For staged/unstaged, the availability is available is based on the selected revision but the parent must be staged/Head to be sure a file can be staged/unstaged. This commands breaks the rule to "show if at least one is possible" as it is not possible to determine the availability in a good way for the command.
FirstIsParent is also used to confirm that a parent to parent exists for difftool exists and to prune when parent-to-selected(B) is is the same as first(A).
Pushing a few clarifications related to this.
Not sure if it got any clearer...
GitCommands/Git/GitRevisionTester.cs
Outdated
|
||
foreach (var item in items) | ||
{ | ||
string filePath = _fullPathResolver?.Resolve(item.Name); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_fullPathResolver
can't be null
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixing
GitUI/CommandsDialogs/FormDiff.cs
Outdated
@@ -65,6 +71,12 @@ public partial class FormDiff : GitModuleForm | |||
DiffText.ExtraDiffArgumentsChanged += DiffTextOnExtraDiffArgumentsChanged; | |||
} | |||
|
|||
protected override void OnRuntimeLoad(EventArgs e) | |||
{ | |||
_revisionDiffContextMenuController = new FileStatusListContextMenuController(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❓ Can this be moved into constructor? If so, this method an go....
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I just followed the pattern you had use in other modules.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would have used OnRuntimeLoad
instead of instantiating objects in constructor where would be a dependency on fully set GitModule
, which isn't available until the control is loaded.
In this case there is no dependency on GitModule
and I'm pretty sure it is safe to move the instantiation in to the constructor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will move
return DescribeRevision(sha1, 0); | ||
} | ||
|
||
private string DescribeRevision(string sha1, int maxLength) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can combine these two methods into one - private string DescribeRevision(string sha1, int maxLength = 0)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changing
Edit: Delegate, need the signature
{ | ||
var parents = DiffFiles.SelectedItemParents | ||
.Where(i => showUnstagedAndCombined || | ||
!(i.Guid.IsNullOrWhiteSpace() || i.Guid == GitRevision.UnstagedGuid || i.Guid == DiffFiles.CombinedDiff.Text)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what does i.Guid == DiffFiles.CombinedDiff.Text
mean?
CombinedDiff.Text
is a localised string "Combined Diff", why are we comparing it to a commit's SHA1?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DiffFiles.CombinedDiff.Text is used both for display and as an ID for a variant of an "artificial commit".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something doesn't feel right about it.... can't articulate what exactly, but it feels bad
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not nice, but I preferred to not spread the knowledge about the revision. The proper way would be to add it in GitRevision.cs like:
public const string IndexGuid = "1111111111111111111111111111111111111111";
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we already have it
public const string IndexGuid = "1111111111111111111111111111111111111111"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In a similar way:
public const string CombinedDiffGuid = "2222...";
DiffFiles.CombinedDiff.Text will be used in some situations still.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a CombinedDiffGuid for the artificial diff after all. For instance #4154 seem to enhance the comparison more, so it is better to set the pattern. Not sure if the TranslationApp handles this correctly.
[Test] | ||
public void LocalExists_should_return_false_if_none_of_locally_tracked_items_have_files() | ||
{ | ||
Assert.Inconclusive(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you've done a great job with tests 👍
these tests need finishing too 😉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will finish later, some done
I have not planned to change anything more |
ab9f736
to
3e97549
Compare
Fixes #4564
Fixes #4387
Fixes #4396
Note: Due to the structure of tests in a separate class, it is very difficult to split this issue in several commits. First commit was PR #4566, partly reviewed. (Depended on merged commits #4562 #4563 #4565 #4567 #4568)
Tests:
Rewrote RevisionDiffController to make it possible to have some kind of tests. The tests are retrofitted to the current functionality as they are just testing the menu items and not the actions themselves. (The tests adds may more maintenance than they give benefits but the formal test coverage increases.)
Browse Diff:
Submodules actions available for multi select (#4568)
Presents the Reset options for the correct parent in multi select situations
No longer differ between parent-child and first-second for Reset
Difftool: Describes A and B revisions in the menu
Difftool arguments depends on parent availability
Better detection of parents to A/B for diffs
Commit:
Limit DiffTool and FileHistory to tracked
FormDiff:
Limit FileHistory to Tracked
Use RevisionDiffController to align to Browse-Diff for difftool
Screenshots before and after (if PR changes UI):
What did I do to test the code and ensure quality:
Has been tested on (remove any that don't apply):