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
Rebase: improve perfs when displaying list of commits #11197
Conversation
@dosercz You could try the portable version here: https://ci.appveyor.com/project/gitextensions/gitextensions/build/artifacts |
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.
+1
Has not run
acee834
to
0c40e6d
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.
Approving, assuming the question is fixed
GitCommands/Git/GitModule.cs
Outdated
{ | ||
Author = data?.Author, | ||
ObjectId = data?.ObjectId, | ||
Subject = data?.Body, |
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.
Is body or Subject needed?
RevisionReader will not save Body (just subject) if the commit is older than 6 months.
(rename the _sixMonths variable to _oldestBody?)
public RevisionReader(GitModule module, bool hasReflogSelector, bool allBodies = false)
: this(module, hasReflogSelector, module.LogOutputEncoding, allBodies ? 0 : new DateTimeOffset(DateTime.Now.ToUniversalTime() - TimeSpan.FromDays(30 * 6)).ToUnixTimeSeconds())
{
}
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.
Subject = data?.Body, | |
Subject = error ?? data?.Subject, |
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.
If the Body is not needed, then those changes in RevisionReader is not required, just enough to clarify with this line.
(I do not mind keep them, should be used later).
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.
Few nits and suggestions
@pmiossec I have tested portable version builded for this PR and it's fine, good job. It'll safe a lot of my time! |
@gerhardol Could you give your point of view at least on the 2nd commit that get the bodies for older commits as I did some refactoring/renaming? |
GitCommands/Git/GitModule.cs
Outdated
var isApplying = currentCommitShortHash is not null && commitHash.StartsWith(currentCommitShortHash); | ||
isCurrentFound |= isApplying; | ||
RevisionReader reader = new(this, hasReflogSelector: false, allBodies: true); | ||
CancellationTokenSource cts = new(2 * 60_000); |
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.
A comment here would be great as well. This is two minutes? Why so long?
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.
CancellationTokenSource cts = new(2 * 60_000); | |
CancellationTokenSource cts = new(TimeSpan.FromMinutes(2)); |
or whatever value how long we would block the UI if there are extremely many commits.
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.
Hopefully two minutes will no longer be needed, but if there is a scenario where the new handling is not effective, keep it.
👍 |
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.
just tuning
GitCommands/Git/GitModule.cs
Outdated
|
||
string[] parts = todoCommit.Split(Delimiters.Space); | ||
// Filter comment lines and keep only lines containing at least 3 columns | ||
// (action, commit hash and commit subject -- that could contains space and be cut in more --) |
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.
nit:
// (action, commit hash and commit subject -- that could contains space and be cut in more --) | |
// (action, commit hash and commit subject -- that could contain spaces and be cut in more --) |
GitCommands/Git/GitModule.cs
Outdated
var isApplying = currentCommitShortHash is not null && commitHash.StartsWith(currentCommitShortHash); | ||
isCurrentFound |= isApplying; | ||
RevisionReader reader = new(this, hasReflogSelector: false, allBodies: true); | ||
CancellationTokenSource cts = new(2 * 60_000); |
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.
CancellationTokenSource cts = new(2 * 60_000); | |
CancellationTokenSource cts = new(TimeSpan.FromMinutes(2)); |
or whatever value how long we would block the UI if there are extremely many commits.
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.
agree with most other comments, assume they will be resolved
GitCommands/Git/GitModule.cs
Outdated
{ | ||
Author = data?.Author, | ||
ObjectId = data?.ObjectId, | ||
Subject = data?.Body, |
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.
If the Body is not needed, then those changes in RevisionReader is not required, just enough to clarify with this line.
(I do not mind keep them, should be used later).
GitCommands/Git/GitModule.cs
Outdated
var isApplying = currentCommitShortHash is not null && commitHash.StartsWith(currentCommitShortHash); | ||
isCurrentFound |= isApplying; | ||
RevisionReader reader = new(this, hasReflogSelector: false, allBodies: true); | ||
CancellationTokenSource cts = new(2 * 60_000); |
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.
Hopefully two minutes will no longer be needed, but if there is a scenario where the new handling is not effective, keep it.
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.
👍
GitCommands/Git/GitModule.cs
Outdated
@@ -2151,7 +2151,7 @@ public IReadOnlyList<PatchFile> GetInteractiveRebasePatchFiles() | |||
string commentChar = EffectiveConfigFile.GetString("core.commentChar", "#"); | |||
|
|||
// Filter comment lines and keep only lines containing at least 3 columns | |||
// (action, commit hash and commit subject -- that could contains space and be cut in more --) | |||
// (action, commit hash and commit subject -- that could contains spaces and be cut in more --) |
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.
// (action, commit hash and commit subject -- that could contains spaces and be cut in more --) | |
// (action, commit hash and commit subject -- that could contain spaces and be cut in more --) |
GitCommands/Git/GitModule.cs
Outdated
isCurrentFound |= isApplying; | ||
// retrieve commits bodies to display them in the grid or as tooltips | ||
RevisionReader reader = new(this, hasReflogSelector: false, allBodies: true); | ||
CancellationTokenSource cts = new(TimeSpan.FromSeconds(15)); |
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 might be too short. It can take a few seconds for a few commits on a workstation.
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.
Is it something you saw?
Because, in GE repo, I made a rebase of 12k commits and it took only 250ms that's why I concluded that in this case 15s was enough. But I have no problem to increase it. 30s?
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.
git-log+parsing requires about 2 s for 100K commits so rebasing all commits in the linux repo would require 20s or so on my machine. 30s is safe
The git-rebase operation can require some time though
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 cancelation token is only for the 'git log & parsing' so I'm happy you confirm that 15s is enough (to rebase 700k commits!) 🤣
But secured 30s is OK for me as we are talking about a worst case scenario that will nearly never happen...
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.
Is it something you saw?
Yes, perhaps caused by hyperactive enterprise AV and / or Windows Update.
(Also git itself became quirky later yesterday. It reproducibly returned exit code 128 without error output when resetting single files using git checkout
- vanished after reboot.)
GitCommands/Git/GitModule.cs
Outdated
isCurrentFound |= isApplying; | ||
// retrieve commits bodies to display them in the grid or as tooltips | ||
RevisionReader reader = new(this, hasReflogSelector: false, allBodies: true); | ||
CancellationTokenSource cts = new(TimeSpan.FromSeconds(15)); |
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.
Is it something you saw?
Yes, perhaps caused by hyperactive enterprise AV and / or Windows Update.
(Also git itself became quirky later yesterday. It reproducibly returned exit code 128 without error output when resetting single files using git checkout
- vanished after reboot.)
Do you still want to review something or I could squash and rebase everything? |
9983162
to
edf2cc2
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.
👍
by retrieving all the commits data with only one `git log` call instead of one by commit. It is possible as when rebasing, all the commits belong to the same branch. Kept a fall back to previous way to retrieve commit data for 1 commit if commit is not in the one loaded. and read bodies of all rebased commits (even the ones older than 6 monthes like it was the case before. RevisionReader had to be adapted to do that.) Results with 7448 commits rebased: 2s instead of 4m50 previously Fixes gitextensions#10698 and gitextensions#11196
edf2cc2
to
eb9df4b
Compare
Squashed and rebased. Ready to be merged... |
GitArgumentBuilder arguments = new("log") | ||
{ | ||
"-z", | ||
$"--pretty=format:\"{FullFormat}\"", |
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 should have been LogFormat
, will change at another update
by retrieving all the commits data with only one
git log
call instead of one by commit.It is possible as when rebasing, all the commits belong to the same branch.
Kept a fall back to previous way to retrieve commit data for 1 commit if commit is not in the one loaded.
Results to show the rebase popup with 7448 commits rebased: 2s instead of 4m50 previously
Fixes #10698 and fixes #11196
Test methodology
Test environment(s)
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.