Re: [PATCH v4 1/1] Make gitdir work with worktrees, respect core.hooksPath, etc
From: Johannes Schindelin <hidden>
Date: 2019-10-13 22:19:11
Hi Pratyush, On Mon, 14 Oct 2019, Pratyush Yadav wrote:
On 12/10/19 11:24PM, Johannes Schindelin wrote:quoted
Hi Pratyush, On Sat, 12 Oct 2019, Pratyush Yadav wrote:quoted
On 08/10/19 04:33AM, Johannes Schindelin via GitGitGadget wrote:quoted
@@ -1453,10 +1501,16 @@ proc rescan {after {honor_trustmtime 1}} { global HEAD PARENT MERGE_HEAD commit_type global ui_index ui_workdir ui_comm global rescan_active file_states - global repo_config + global repo_config _gitdir_cache if {$rescan_active > 0 || ![lock_index read]} return + # Only re-prime gitdir cache on a full rescan + if {$after ne "ui_ready"} {What do you mean by a "full rescan"? I assume you use it as the differentiator between `ui_do_rescan` (called when you hit F5 or choose rescan from the menu) and `do_rescan` (called when you revert a line or hunk), and a "full rescan" refers to `ui_do_rescan`. Well in that case, this check is incorrect. `do_rescan` passes only "ui_ready" and `ui_do_rescan` passes "force_first_diff ui_ready". But either way, I'm not a big fan of this. This check makes assumptions about the behaviour of its callers based on what they pass to $after. The way I see it, $after should be a black box to `rescan`, and it should make absolutely no assumptions about it. Doing it this way is really brittle, and would break as soon as someone changes the behaviour of `ui_do_rescan`. If someone in the future passes a different value in $after, this would stop working as intended and would not refresh the cached list on a rescan. So, I think a better place for this if statement would be in `ui_do_rescan`. This would mean adding a new function that does this. But if we unset _gitdir_cache in prime_gitdir_cache (I see no reason not to), we can get away with just something like: proc ui_do_rescan {} { rescan {prime_gitdir_cache; ui_ready} } Though since `prime_gitdir_cache` does not really depend on the rescan being finished, something like this would also work fine: proc ui_do_rescan {} { rescan ui_ready prime_gitdir_cache }That was my first attempt. However, there is a very important piece of code that is even still quoted above: that `if {$rescan_active > 0 || ![lock_index read]} return` part. I do _not_ want to interfere with an actively-going-on rescan. If there is an active one, I don't want to re-prime the `_gitdir` cache.Good catch! In that case I suppose refreshing the cache in $after would be the way to go (IOW, the former of my two suggestions). Anything $after won't get executed if we return early from that check.
The obvious problem with that solution is that the `_gitdir` is reset _after_ the rescan. In my solution, it is reset _before_, as I have no idea how often the `_gitdir` values are used during a rescan (and if none of they were, I would like to be very cautious to prepare for a future where any of those `_gitdir` values _are_ used during a rescan). So I am afraid that I find way too serious problems with both of your proposed alternatives. Ciao, Johannes
quoted
That was the reason why I put the additional code into `rescan` rather than into `ui_do_rescan()`. Ciao, Johannesquoted
This would allow us to do these two things in parallel since `rescan` is asynchronous. But that would also mean it is possible that the status bar would show "Ready" while `prime_gitdir_cache` is still executing. I can't really make up my mind on what is better. I'm inclining on using the latter way, effectively trading a bit of UI inconsistency for performance (at least in theory). Thoughts?quoted
+ array unset _gitdir_cache + prime_gitdir_cache + } + repository_state newType newHEAD newMERGE_HEAD if {[string match amend* $commit_type] && $newType eq {normal}-- Regards, Pratyush Yadav