Skip to content
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

RangeDiff: Commit count in name #8628

Merged

Conversation

gerhardol
Copy link
Member

@gerhardol gerhardol commented Nov 21, 2020

Proposed changes

#8516 etc added git-range-diff. After some usage, I would like to change the presentation a little.

Currently the first and second commits are presented. I have found that I often want to know the commit count for first/second to the merge-base, similar to ahead/behind info. The first/second is (normally, see below) listed anyway in other groups and the second commit is not often seen as as the group name is too long.

If one of the first/second selected is artificial, the range diff uses HEAD. This is not listed in the other group names, but should be obvious.
To avoid a second call to git-rev-list (adding about 40 ms on my PC), a modified git-rev-list call was added.

Screenshots

Before

FileStatusList must be wide to see the second revision

image

image

After

image

image

Test methodology

Manual


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

@ghost ghost assigned gerhardol Nov 21, 2020
@codecov
Copy link

codecov bot commented Nov 21, 2020

Codecov Report

Merging #8628 (9bdef2b) into master (e0d47d8) will decrease coverage by 0.01%.
The diff coverage is 0.00%.

@@            Coverage Diff             @@
##           master    #8628      +/-   ##
==========================================
- Coverage   55.11%   55.10%   -0.02%     
==========================================
  Files         906      906              
  Lines       65550    65562      +12     
  Branches    11872    11874       +2     
==========================================
- Hits        36130    36129       -1     
- Misses      26589    26600      +11     
- Partials     2831     2833       +2     
Flag Coverage Δ
production 42.10% <0.00%> (-0.02%) ⬇️
tests 94.91% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Copy link
Member

@RussKie RussKie left a comment

Choose a reason for hiding this comment

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

The actual implementation LGTM with a comment

var first = firstRev.ObjectId == firstRevHead ? firstRev : new GitRevision(firstRevHead);
var selected = selectedRev.ObjectId == selectedRevHead ? selectedRev : new GitRevision(selectedRevHead);
var (baseToFirstCount, baseToSecondCount) = module.GetCommitRangeDiffCount(first.ObjectId, selected.ObjectId);
Copy link
Member

Choose a reason for hiding this comment

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

module should really be IGitModule, and thus the changes to the API should be exposed at the interface level.
This aligns with @ivangrek's work in #8574.

Copy link
Member Author

Choose a reason for hiding this comment

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

There are some more methods needed for that to happen.
Also, I would prefer to not share this with plugins. If so, the methods should change to strings instead of ObjectId (as there may be situations where treeish identifiers like HEAD could be used.)

Severity	Code	Description	Project	File	Line	Suppression State
Error	CS1061	'IGitModule' does not contain a definition for 'GetTreeFiles' and no accessible extension method 'GetTreeFiles' accepting a first argument of type 'IGitModule' could be found (are you missing a using directive or an assembly reference?)	GitUI	F:\dev\gc\gitextensions\GitUI\UserControls\FileStatusDiffCalculator.cs	40	Active
Error	CS1061	'IGitModule' does not contain a definition for 'GetCombinedDiffFileList' and no accessible extension method 'GetCombinedDiffFileList' accepting a first argument of type 'IGitModule' could be found (are you missing a using directive or an assembly reference?)	GitUI	F:\dev\gc\gitextensions\GitUI\UserControls\FileStatusDiffCalculator.cs	61	Active
Error	CS1061	'IGitModule' does not contain a definition for 'GetCommitDiffCount' and no accessible extension method 'GetCommitDiffCount' accepting a first argument of type 'IGitModule' could be found (are you missing a using directive or an assembly reference?)	GitUI	F:\dev\gc\gitextensions\GitUI\UserControls\FileStatusDiffCalculator.cs	191	Active
Error	CS1061	'IGitModule' does not contain a definition for 'GetCommitDiffCount' and no accessible extension method 'GetCommitDiffCount' accepting a first argument of type 'IGitModule' could be found (are you missing a using directive or an assembly reference?)	GitUI	F:\dev\gc\gitextensions\GitUI\UserControls\FileStatusDiffCalculator.cs	192	Active
Error	CS1061	'IGitModule' does not contain a definition for 'GetCommitRangeDiffCount' and no accessible extension method 'GetCommitRangeDiffCount' accepting a first argument of type 'IGitModule' could be found (are you missing a using directive or an assembly reference?)	GitUI	F:\dev\gc\gitextensions\GitUI\UserControls\FileStatusDiffCalculator.cs	173	Active
Error	CS1061	'IGitModule' does not contain a definition for 'GetDiffFilesWithSubmodulesStatus' and no accessible extension method 'GetDiffFilesWithSubmodulesStatus' accepting a first argument of type 'IGitModule' could be found (are you missing a using directive or an assembly reference?)	GitUI	F:\dev\gc\gitextensions\GitUI\UserControls\FileStatusDiffCalculator.cs	54	Active
Error	CS1061	'IGitModule' does not contain a definition for 'GetDiffFilesWithSubmodulesStatus' and no accessible extension method 'GetDiffFilesWithSubmodulesStatus' accepting a first argument of type 'IGitModule' could be found (are you missing a using directive or an assembly reference?)	GitUI	F:\dev\gc\gitextensions\GitUI\UserControls\FileStatusDiffCalculator.cs	87	Active
Error	CS1061	'IGitModule' does not contain a definition for 'GetDiffFilesWithSubmodulesStatus' and no accessible extension method 'GetDiffFilesWithSubmodulesStatus' accepting a first argument of type 'IGitModule' could be found (are you missing a using directive or an assembly reference?)	GitUI	F:\dev\gc\gitextensions\GitUI\UserControls\FileStatusDiffCalculator.cs	138	Active
Error	CS1061	'IGitModule' does not contain a definition for 'GetDiffFilesWithSubmodulesStatus' and no accessible extension method 'GetDiffFilesWithSubmodulesStatus' accepting a first argument of type 'IGitModule' could be found (are you missing a using directive or an assembly reference?)	GitUI	F:\dev\gc\gitextensions\GitUI\UserControls\FileStatusDiffCalculator.cs	147	Active
Error	CS1061	'IGitModule' does not contain a definition for 'GetDiffFilesWithSubmodulesStatus' and no accessible extension method 'GetDiffFilesWithSubmodulesStatus' accepting a first argument of type 'IGitModule' could be found (are you missing a using directive or an assembly reference?)	GitUI	F:\dev\gc\gitextensions\GitUI\UserControls\FileStatusDiffCalculator.cs	148	Active
Error	CS1061	'IGitModule' does not contain a definition for 'GetMergeBase' and no accessible extension method 'GetMergeBase' accepting a first argument of type 'IGitModule' could be found (are you missing a using directive or an assembly reference?)	GitUI	F:\dev\gc\gitextensions\GitUI\UserControls\FileStatusDiffCalculator.cs	103	Active
Error	CS1061	'IGitModule' does not contain a definition for 'GetMergeBase' and no accessible extension method 'GetMergeBase' accepting a first argument of type 'IGitModule' could be found (are you missing a using directive or an assembly reference?)	GitUI	F:\dev\gc\gitextensions\GitUI\UserControls\FileStatusDiffCalculator.cs	108	Active
Error	CS1061	'IGitModule' does not contain a definition for 'GetMergeBase' and no accessible extension method 'GetMergeBase' accepting a first argument of type 'IGitModule' could be found (are you missing a using directive or an assembly reference?)	GitUI	F:\dev\gc\gitextensions\GitUI\UserControls\FileStatusDiffCalculator.cs	111	Active

Copy link
Member

Choose a reason for hiding this comment

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

This is something we'll need to fix going forward.

@ghost ghost mentioned this pull request Nov 22, 2020
@gerhardol gerhardol requested a review from mstv November 22, 2020 15:58
@mstv
Copy link
Member

mstv commented Nov 24, 2020

I can follow the reasoning for this change.
Just curious: What is such interesting in how many commits a branch is ahead & behind? I just want to know whether it is ahead & behind. BTW: "(gone)" as text is distracting.
range-diff is a little special because of its limitations (max. distance in commits; commits must match, i.e. not usable for squashed branches -- or have I missed it?)
So finally, I don't have objections.

Comment on lines +846 to +849
var output = _gitExecutable.GetOutput(args);

var counts = output.Split('\t');
if (counts.Length == 2 && int.TryParse(counts[0], out var first) && int.TryParse(counts[1], out var second))
Copy link
Member

Choose a reason for hiding this comment

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

This is another reason for adding a generic detection of git error and warning messages to GetOutput etc.

Copy link
Member

Choose a reason for hiding this comment

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

How would it help?

var first = firstRev.ObjectId == firstRevHead ? firstRev : new GitRevision(firstRevHead);
var selected = selectedRev.ObjectId == selectedRevHead ? selectedRev : new GitRevision(selectedRevHead);
var (baseToFirstCount, baseToSecondCount) = module.GetCommitRangeDiffCount(first.ObjectId, selected.ObjectId);
const int maxRangeDiffCommits = 100;
var desc = $"{Strings.DiffRange} {baseToFirstCount ?? maxRangeDiffCommits + 1}↓ {baseToSecondCount ?? maxRangeDiffCommits + 1}↑";
Copy link
Member

Choose a reason for hiding this comment

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

"100+" or ">100" instead of "101"?

Copy link
Member Author

Choose a reason for hiding this comment

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

changed to angeDiffCommitLimit

@RussKie
Copy link
Member

RussKie commented Nov 25, 2020 via email

@gerhardol
Copy link
Member Author

Just curious: What is such interesting in how many commits a branch is ahead & behind? I just want to know whether it is ahead & behind.

To some extent, this change was initiated by that First->Second is too long and therefore not really useful.
The exact number is not so interesting, but to see where the branches are attached. Like if my local branch is about 4 commits and I compare to another branch with about 4 commits and the count is 8-9, there are other commits involved to, if it is 4-4 there are likely no other commits involved.

BTW: "(gone)" as text is distracting.

I agree but this is Git name. May be changed to "-".

range-diff is a little special because of its limitations (max. distance in commits; commits must match, i.e. not usable for squashed branches -- or have I missed it?)

Correct, the actual diff is hard to pretend (and even not always correct).
But for rebased branches it is very useful: Has someone else changed anything when rebasing, was the rebase correct?
I often have branches with 30 commits for review that I rearrange before creating a PR, with range-diff I get a better overview.

Comment on lines +840 to +845
var args = new GitArgumentBuilder("rev-list")
{
$"{firstId}...{secondId}",
"--count",
"--left-right"
};
Copy link

Choose a reason for hiding this comment

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

Could we use constants for these commands?

public static class GitCommands
{
    public static class RevList
    {
        public const string Command = "rev-list";
        public const string CountParameter = "--count";
        public const string LeftRightParameter = "--left-right";
    }
}

or

public static class GitCommands
{
    public const string RevList = "rev-list";

    public static class RevListParameters
    {
        public const string Count = "--count";
        public const string LeftRight = "--left-right";
    }
}

Most likely there will be many common parameters.

Copy link
Member Author

Choose a reason for hiding this comment

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

If this is changed, it should be a generic change for all commands, not in this PR.

Personally I see just one reason to make constants for commands: It is possible to search where they are used.
"rev-list" is unique though, but "log" is not.

Other than that, for Git commands you get down to a text string anyway. Using constants will just add another layer when viewing the code.

Other than that, I would like to merge this.
Changes to IGitModule will affect more commands than GetCommitRangeDiffCount, like GetDiffFilesWithSubmodulesStatus.

Copy link

Choose a reason for hiding this comment

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

Personally I see just one reason to make constants for commands: It is possible to search where they are used.
"rev-list" is unique though, but "log" is not.

The search itself is important.

I use the rule: "Everything that can be calculated at the stage of creating a program must be calculated."
Example:

image

image

Other than that, for Git commands you get down to a text string anyway. Using constants will just add another layer when viewing the code.

And that's the key.
Why not use it like that?

var args = new GitArgumentBuilder($"rev-list {firstId}...{secondId} --count --left-right");

Or so?

var args = $"rev-list {firstId}...{secondId} --count --left-right";

I think we could find this door if we looked, the key is already in our hands. 😉

Other than that, I would like to merge this.

Well, Ok.

Copy link
Member Author

Choose a reason for hiding this comment

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

Why not use it like that?

The Git command (like "rev-list") is a hook for options etc so that must be separate.
The (generic) argument builder handles some types native and simplifies use of booleans etc.

Another layer will require me too look up the constant when browsing the code which is not an advantage to me.

Copy link

@ghost ghost Nov 27, 2020

Choose a reason for hiding this comment

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

var args = new GitArgumentBuilder("rev-list")
{
    "--count",
    "--left-right"
};

var args = new GitArgumentBuilder(GitCommands.RevList)
{
    GitCommands.RevListParameters.Count,
    GitCommands.RevListParameters.LeftRight
};

I understand correctly, do you think that the second method may require additional actions?

Copy link
Member Author

Choose a reason for hiding this comment

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

I understand correctly, do you think that the second method may require additional actions?

No additional actions, but I do not see the actual commands at a glance.

@RussKie
Copy link
Member

RussKie commented Nov 28, 2020

@gerhardol squash and merge

@RussKie RussKie added the 📭 needs: author feedback More info/confirmation awaited from OP; issues typically get closed after 30 days of inactivity label Nov 28, 2020
Commit hash and branch names are too long to read
@ghost ghost removed the 📭 needs: author feedback More info/confirmation awaited from OP; issues typically get closed after 30 days of inactivity label Nov 28, 2020
@gerhardol gerhardol merged commit 5996dc9 into gitextensions:master Nov 28, 2020
@ghost ghost added this to the 4.0 milestone Nov 28, 2020
@gerhardol gerhardol deleted the feature/rangediff-commitcount branch November 28, 2020 10:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants