-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
Description
I love GitLens and get a lot of value out of it. The "GitLens Current Line Blame" is particularly valuable and something I use all the time. Multiple times a day, I've noticed VS Code get into a state where the line blame disappears.
Here's a screenshot of the feature I'm referring to:
Here's a screenshot of what it looks like when the feature mysteriously disappears. When this happens, it completely disappears and is not present as a status bar item when I right click on the bottom status bar.
I usually have to restart the VS Code extension server to get out of this state.
Investigating
I've had this problem for multiple years. It's been very difficult to replicate since it usually happens a few hours into my work day and hadn't appeared in the past when I cloned the GitLens repo and started an Extension Development Host window.
Today, I was feeling particularly motivated to debug and figured out how to attach an interactive debugger with source maps to an already running Extension Host process after it got into this bad state. 😎
I noticed that this.updateState is never called when I get into the bad state due to this.suspended always evaluating to true here.
Theory
I'm not exactly sure how this.suspended became true indefinitely in my editor today, but reading GitLens's source code, I see one reproducible way this could happen:
- A user edits a file causing the editor state to become "dirty" and
this.suspend()to be called.
vscode-gitlens/src/trackers/gitLineTracker.ts
Lines 107 to 113 in a70e2b9
| private onDirtyStateChanged(e: DocumentDirtyStateChangeEvent<GitDocumentState>) { | |
| if (e.dirty) { | |
| this.suspend(); | |
| } else { | |
| this.resume({ force: true }); | |
| } | |
| } |
- After the user stops editing the file for 5 seconds (the
advanced.blame.delayAfterEdittime), theonDirtyIdleTriggeredcallback is fired andthis.resume()is supposed to unsuspendGitLineTracker.
vscode-gitlens/src/trackers/gitLineTracker.ts
Lines 95 to 100 in a70e2b9
| private onDirtyIdleTriggered(e: DocumentDirtyIdleTriggerEvent<GitDocumentState>) { | |
| const maxLines = configuration.get('advanced.blame.sizeThresholdAfterEdit'); | |
| if (maxLines > 0 && e.document.lineCount > maxLines) return; | |
| this.resume(); | |
| } |
As the code above shows, this intentionally doesn't resume the GitLineTracker if the dirty file is >5000 lines long (or advanced.blame.sizeThresholdAfterEdit). That part feels correct.
However, what's surprising (and this code doesn't seem to handle), is the case when users switch tabs or open a different file after the idle timeout. The GitLineTracker shared instance is still suspended for the previous large file and never resumes for other smaller files in other tabs.
Steps to Reproduce
I was excited to see the theory above is indeed reproducible. Using the current latest version at the time of writing (v14.6.1) and the GitLens code base itself:
- Open
src/trackers/gitLineTracker.tsand observe the current line blame updating properly as the cursor moves. - Open
yarn.lock(currently at7582lines) and make an edit. - Wait 5 seconds.
- Close the file and do not save changes.
- Observe the current line blame no longer appear in
gitLineTracker.tsor any other file.
Screen.Recording.2023-12-19.at.7.24.27.PM.mov
Pull Request
Here's one possible fix. #3067
GitLens Version
v14.6.1
VS Code Version
Version: 1.85.1
Commit: 0ee08df0cf4527e40edc9aa28f4b5bd38bbff2b2
Date: 2023-12-13T09:48:16.874Z
Electron: 25.9.7
ElectronBuildId: 25551756
Chromium: 114.0.5735.289
Node.js: 18.15.0
V8: 11.4.183.29-electron.0
OS: Darwin arm64 23.2.0
Git Version
git version 2.43.0