-
-
Notifications
You must be signed in to change notification settings - Fork 67
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
Fix status view for very out-of-sync repos #257
Conversation
Oh. |
OK yeah I tried out building the full So yeah I think we need one of:
|
Each getCommit call ends up as a `git show` subprocess: https://github.com/microsoft/vscode/blob/65a3d201e6a97b56ad0980bf2078cf6381ce3e52/extensions/git/src/git.ts#L2468 In my Linux kernel repo my `master` branch goes unused for months at a time so when I check it out it's normally tens of thousands of commits behind its upstream. Spinning up that many `git show` commands kills the extension! Not sure of the exact mechanics of why it gets killed, but even if it didn't get killed, it would be very slow and power-hungry. I initially tried to fix this by avoiding the `getCommit` calls, instead fetching partial commit data directly from the log. This turned out to be a bit of a pain, it required introducing an extra type to represent that incomplete commit data. Further testing then revealed this wasn't even very fast. So, the new solution is just to have the command code limit the number of commits that we fetch to 50 for each of the ahead/behind gap.
OK sorry for all the noise here... after further usage I discovered that my status view was nowhere near as fast as I first thought. I don't really understand how I came to believe it was rendering in under a second, that's no longer what I observed today. So I've ended up re-writing this according to approach number 3 in the comment above. I think this actually leads to fairly simple code anyway. |
Appreciate the work! I will look at this soon, when I have the time |
LGTM! |
This PR introduced a serious bug. The same commit appears in behind and ahead in the commit above. @bjackman , does this have a simple fix? |
Reverting for now |
Yep, thanks - suspect the fix will be simple but won't get a chance to take
a look for a few weeks so revert is the best option for now.
…On Tue, May 23, 2023, 8:25 PM Kristian Andersen Hole < ***@***.***> wrote:
Reverting for now
—
Reply to this email directly, view it on GitHub
<#257 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAWNWK2AZ7K5UT3ZSCBQMPLXHSNCNANCNFSM6AAAAAAYBK7SLE>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Hey @kahole I just got back to this but I couldn't reproduce it with a straightforward attempt (based on the current tip of this PR's branch i.e. e82a4c3): Initial repo state per git CLI:
And per edamagit: Creating a local commit ahead of upstream branch shows the expected unmerged status:
Reverse situation where the upstream branch is behind:
I also tried it at the commit before the revert i.e. 2bca719 but got the same results as above. So maybe this isn't such a trivial bug. Any chance you remember what state your repo was in when you took the screenshot in #257 (comment)? Would you be able to reproduce it? |
Might have something to do with it |
…c with upstream"" This reverts commit f7cdaee. As noted in kahole#257 (comment), that commit is broken when the current branch is out of sync with its upstream, and a push remote is configured for it. This will be fixed in the next commit.
The three-dot notation is a symmetric operation returning the difference between two commits, i.e. all that are reachable from one but not the other. This didn't turn out to matter for the usage directly in `internalMagitStatus` - we only call `getCommitRange` at most once there anyway because we first check the `.ahead`/`.behind` counters provided by the VSCode Git API. However in `pushRemoteStatus` we call it unconditionall for both "directions", which means the same set of commits show up in the returned `.head` and `.behind` fields. This leads to the bug described in kahole#257 (comment). The fix is just to use the asymmetric range operator: `..`.
The three-dot notation is a symmetric operation returning the difference between two commits, i.e. all that are reachable from one but not the other. This didn't turn out to matter for the usage directly in `internalMagitStatus` - we only call `getCommitRange` at most once there anyway because we first check the `.ahead`/`.behind` counters provided by the VSCode Git API. However in `pushRemoteStatus` we call it unconditionall for both "directions", which means the same set of commits show up in the returned `.head` and `.behind` fields. This leads to the bug described in kahole#257 (comment). The fix is just to use the asymmetric range operator: `..`.
Ah nice, thanks, you were right about that. Turns out |
…c with upstream"" This reverts commit f7cdaee. As noted in kahole#257 (comment), that commit is broken when the current branch is out of sync with its upstream, and a push remote is configured for it. This will be fixed in the next commit.
The three-dot notation is a symmetric operation returning the difference between two commits, i.e. all that are reachable from one but not the other. This didn't turn out to matter for the usage directly in `internalMagitStatus` - we only call `getCommitRange` at most once there anyway because we first check the `.ahead`/`.behind` counters provided by the VSCode Git API. However in `pushRemoteStatus` we call it unconditionall for both "directions", which means the same set of commits show up in the returned `.head` and `.behind` fields. This leads to the bug described in kahole#257 (comment). The fix is just to use the asymmetric range operator: `..`.
Fix for #255. See commit messages for some further details.
However:
It's a little annoying that this means we have to introduce the new
MagitCommitSummary
type. I would have liked to just create an objectthat satisfies the full Commit interface, but that interface has a
parents
field, which we can't easily collect without a more extensive operation 😕 .It seems like the log-parsing logic in getCommitsAheadBehind should
live in gitTextUtils.ts, but it's tightly coupled with the exact
git log
command.I'm new to TypeScript, please don't hesitate to let me know if I've
done anything stupid!
One alternative strategy that I haven't tried: Maybe instead of this
MagitCommitSummary
thing, we could just still usegetCommit
, but do it only for the commits we are actually going to display in the UI. Probably 256getCommit
calls is pretty OK, especially since it will be cached for later.The downside of that is that then we need a way to communicate from the model code to the view code that the commit list has been truncated, this seems kinda ugly in its own right. Maybe to fix that we could just pass through the
Branch
to the view code and then have it dogetCommit
according to its own knowledge of how many commits will actually get rendered? But then I guess we'd be mixing up model and view code in an awkward way.So yeah I dunno, let me know what you think.