-
-
Notifications
You must be signed in to change notification settings - Fork 46
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
diff-hl-magit-post-refresh doesn't work anymore #171
Comments
AFAIK the code worked in the past, and I'm not a Magit user, to be able to ensure that it continues working after every update.
It's not a problem if the file wasn't The problem with calling |
The problem is, I'm not sure how best to fix this without calling |
Perhaps @tarsius could advise.
Recalling certain bug reports on the Emacs bug tracker, you would be surprised. |
Why can't you take a snapshot of the vc-state of all the files with diff-hl-mode turned on pre-refresh, and then just diff them again post-fresh? This way you don't have to go thru magit at all. |
Isn't that what I'm going? But I have to use Magit's hooks to find out when the "refresh" is happening. |
Briefly, I don't remember making any changes over the last year that might cause a change in behavior but while I use diff-hl and find it useful, I apparently don't rely on it enough to have noticed and change. I can look at how magit and diff-hl interact again at a later time, but right now I have to much on my plate to get going right away. |
Ah, I see there's a patch already. Of course I am happy if I don't have to dig into this myself. Please note though that some magit users have turned of vc support for git -- would this patch work for users who have done that? |
Probably not, but what we have now wouldn't work for them anyway. |
How do you even turn off vc support for git anyway? |
Since you wrote the patch and have now been made aware of this potential issue, you should investigate it. We should fix it for everyone.
|
My patch is straightly an improvement. I'm satisfied with my patch. I don't have time to cater to those who have turned off the git backend and uses diff-hl, since that has never worked for them. Catering to them would require Magit changes to keep the files unstaged when pre-refresh is run. That sounds far far more complicated than what I need. |
How would you fix it, aside from implementing Magit-specific code paths for that case? Like an override for Anyway, it does indeed seem orthogonal to the present issue. |
@dgutov I'll try to look into this soon but I am a bit swamped right now. |
Turns out that is not a problem because |
Right. |
I have taken an in depth look and now think that this never worked properly. Not since fdbf34a and while I stopped my investigation there probably also not before. I believe the perception that this "worked a while ago" and now doesn't work anymore is due to certain states/state chances having always worked while others never did, and people remember the good cases and have run into the bad cases more often before reporting that there is "a regression". Two major issues with the current implementation are:
I now think this should be implemented in magit and have a little proof-of-concept implementation, though it hasn't been optimized at all yet. I'll improve that over the next week or two. This implementation hooks into the So all in all I recommend you just leave things as they are now; this was broken for five years and we can wait a few more weeks. (This is high on my priority list, but not all the way at the top.) |
Thanks, Jonas! That certainly works for me. |
Hi @tarsius , has this been implemented in magit yet? |
No, sorry I haven't gotten around to that yet. |
I cannot promise anything but I am almost caught up with leftovers, so it's possible I will look into this soonish. Then again I am trying to spend more time in the sun instead of on the computer in the summer months, so maybe not. |
Good deal, let me know if there's anything I can help with. |
Here's a recent related report: #201 |
@tarsius How did your past 3 years go? Any chance you can put this at the very top of your todo list this year? If not, can you outline a workaround here please? Thanks. |
Priority one is getting releases out. Then I want to complete a very important secret project. Then a "work on things I actually want to work on" period must follow to avoid burnout. Then I have to work on earning more than 1/3 of the median income where I live (i.e., get above below poverty line). After that I plan to work on longstanding issues such as this. |
@tarsius I really hear you, on all of those points. Perhaps when time permits, you could outline your idea of the solution, though? I'd suggest going with the simplest approach among the ones being considered. EDIT: I understand that you might really want to review (and/or guide and/or fix) halfway solutions by somebody else, but perhaps some middle ground could be reached. |
Alternatively, somebody particularly motivated by this issue could start with their view of the solution, hopefully one that addresses the problems outlined in #171 (comment). To reiterate what's already been said, a part of the change will likely be in Magit, so being familiar with its structure is a requirement. |
What goes wrong in diff-hl if you apply updates only for visible buffers? There are likely to be much fewer of those. This is what git-gutter offers (adding this to the right hooks is left to the user): (defun git-gutter:update-all-windows ()
"Update git-gutter information for all visible buffers."
(interactive)
(dolist (buf (buffer-list))
(when (get-buffer-window buf 'visible)
(with-current-buffer buf
(when git-gutter-mode
(git-gutter)))))) Calling it from a magit hook seems to work just fine, but I haven't tested it with a large number of buffers open. It is still technically linear in the number of buffers, because it has to check each buffer for visibility, but should be much cheaper than running There may also be an emacs idiom for "do the following only for visible buffers" that is better than git-gutter's approach; I don't hack on this stuff often. Actually, one possibly better mechanism might be something like: (dolist (frame (visible-frame-list))
(dolist (window (window-list frame))
(with-current-buffer (window-buffer window)
(when diff-hl-mode
(diff-hl-update)))))) which avoids slowdowns in the case (It might be possible to do slightly better by only triggering an update for a buffer visiting a file inside the repository that triggered the update, but that optimization may not be worthwhile since this approach already tries to update very few buffers. I'd guess under 10 in the vast majority of cases, the median might be more like 1 or 2.) |
I have a strong suspicion that something like this will work: (let ((diff-hl--magit-staged-files))
(add-hook 'git-commit-setup-hook
(lambda ()
(unless (and diff-hl-disable-on-remote
(file-remote-p default-directory))
(setq diff-hl--magit-staged-files
(magit-staged-files)))))
(add-hook 'magit-post-refresh-hook
(lambda ()
(unless (and diff-hl-disable-on-remote
(file-remote-p default-directory))
(let* ((topdir (magit-toplevel))
(modified-files
(mapcar (lambda (file) (expand-file-name file topdir))
diff-hl--magit-staged-files))
(unmodified-states '(up-to-date ignored unregistered)))
(setq diff-hl--magit-staged-files nil)
(dolist (buf (buffer-list))
(when (and (buffer-local-value 'diff-hl-mode buf)
(not (buffer-modified-p buf))
;; Solve the "cloned indirect buffer" problem
;; (diff-hl-mode could be non-nil there, even if
;; buffer-file-name is nil):
(buffer-file-name buf)
(file-in-directory-p (buffer-file-name buf) topdir)
(file-exists-p (buffer-file-name buf)))
(with-current-buffer buf
(let* ((file buffer-file-name)
(backend (vc-backend file)))
(when backend
(cond
((member file modified-files)
(when (memq (vc-state file) unmodified-states)
(vc-state-refresh file backend))
(diff-hl-update))
((not (memq (vc-state file backend) unmodified-states))
(vc-state-refresh file backend)
(diff-hl-update)))))))))))
100)) |
@dpathakj Updating all visible windows seems like a good idea for git-gutter, which I think updates the views after every command. We have it a bit more complicated here, with the default configuration only updating buffers after an edit was made and saved. With diff-hl-flydiff-mode it should work better, though. Perhaps we should offer this approach as an option. (Just commented on wyuenho's patch in the PR.) |
I'm on the emacs-28 branch HEAD and using latest Magit and libgit from Melpa, I've followed the README to do
However, the post-fresh hook doesn't seem to be able to call
diff-hl-update
update anymore aftermagit-commit
. The reason seems to be aftermagit-commit
, the file is considered asup-to-date
by git, so neither of the branches will hitdiff-hl-update
.What I don't understand is, why is
diff-hl-magit-post-refresh
so complicated? Why not just calldiff-hl-update
as long as the file still exists on disk and in vc?The text was updated successfully, but these errors were encountered: