Bug 551289 - Pull operation should not refresh _all_ projects of that repository
Summary: Pull operation should not refresh _all_ projects of that repository
Status: RESOLVED FIXED
Alias: None
Product: EGit
Classification: Technology
Component: UI (show other bugs)
Version: 5.6   Edit
Hardware: PC Windows 10
: P3 normal (vote)
Target Milestone: 5.6   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords: performance
: 416199 (view as bug list)
Depends on:
Blocks:
 
Reported: 2019-09-20 02:13 EDT by Michael Keppler CLA
Modified: 2019-12-04 11:45 EST (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Michael Keppler CLA 2019-09-20 02:13:05 EDT
Currently each egit operation refreshes _all_ projects of a repository via

projects = ProjectUtil#getValidOpenProjects()
Operation.perform()
ProjectUtil#refreshValidProjects(projects, IProgressMonitor)

Shouldn't we instead take the operation result (if available) to calculate only those projects which contain modified files, and not refresh all the other ones?

Example: I just pulled from a repo where I have checked out about 140 projects. The pull result was a fast-forward of 1 commit with 1 changed file on my currently checked out branch (and some other remote branch updates). It would have been sufficient to refresh the single project containing the changed file, and to leave everything else to the auto build of eclipse. But egit refreshed every project of that repository, thereby making the refresh the very dominant part of the overall operation (i.e. taking several times longer than the actual git operation).
Comment 1 Thomas Wolf CLA 2019-09-20 03:51:37 EDT
Using the operation result may be difficult; basically you'd need to do a diff between the last HEAD and the pulled and checked-out/merged tip.

But JGit should send a WorkingTreeModifiedEvent that would tell exactly which files got modified. That might be much quicker.

However, I've been wondering about these refreshes anyway. We do have the ResourceRefreshJob in Activator already. It reacts exactly on that event and does a background refresh of affected files/folders/projects.
Comment 2 Matthias Sohn CLA 2019-09-20 11:51:05 EDT
(In reply to Thomas Wolf from comment #1)
> Using the operation result may be difficult; basically you'd need to do a
> diff between the last HEAD and the pulled and checked-out/merged tip.
> 
> But JGit should send a WorkingTreeModifiedEvent that would tell exactly
> which files got modified. That might be much quicker.
> 
> However, I've been wondering about these refreshes anyway. We do have the
> ResourceRefreshJob in Activator already. It reacts exactly on that event and
> does a background refresh of affected files/folders/projects.

yes, you added this in b13a285098305149b34924bce2679a0cd98d9b2c, looks like we should remove the coarse grained refreshes.
Comment 3 Eclipse Genie CLA 2019-09-20 11:51:33 EDT
New Gerrit change created: https://git.eclipse.org/r/149917
Comment 4 Eclipse Genie CLA 2019-09-23 19:00:32 EDT
New Gerrit change created: https://git.eclipse.org/r/150032
Comment 5 Eclipse Genie CLA 2019-10-11 09:19:38 EDT
Gerrit change https://git.eclipse.org/r/150032 was merged to [master].
Commit: http://git.eclipse.org/c/egit/egit.git/commit/?id=110b54a5ffd44b1151328abbac4cdd8ccbd3ee50
Comment 6 Thomas Wolf CLA 2019-10-11 12:43:23 EDT
This breaks closing of non-existing projects. The problem is that the refresh occurs too early. Try checking out in EGit a commit from before 108-11-20, when the o.e.egit.core.junit project didn't exist yet...
Comment 7 Thomas Wolf CLA 2019-10-11 13:48:15 EDT
(In reply to Thomas Wolf from comment #6)
> This breaks closing of non-existing projects. The problem is that the
> refresh occurs too early. Try checking out in EGit a commit from before
> 108-11-20, when the o.e.egit.core.junit project didn't exist yet...

Of course I meant "before 2018-11-20". With autobuild on, the Java builder kicks in before we can close the project.

Another problem: the RepositoryRefreshScanner runs with a non-resource rule, but with synchronous refresh, it'll then try to acquire Resource rules. So there we have to run in a separate job.
Comment 8 Eclipse Genie CLA 2019-10-11 17:33:14 EDT
New Gerrit change created: https://git.eclipse.org/r/150967
Comment 9 Thomas Wolf CLA 2019-10-11 17:46:08 EDT
(In reply to Eclipse Genie from comment #8)
> New Gerrit change created: https://git.eclipse.org/r/150967

With this change everything seems to work again as it should. Have not been able to reproduce the problem mentioned in comment 6 anymore. That one, BTW, occurred with the project tracker off and switching from master to some very old commit. It gave me the stack trace

!ENTRY org.eclipse.egit.ui 4 0 2019-10-11 18:33:57.525
!MESSAGE Branch failed
!STACK 1
org.eclipse.core.internal.resources.ResourceException: Errors occurred while refreshing resources with the local file system.
	at org.eclipse.core.internal.localstore.FileSystemResourceManager.refreshResource(FileSystemResourceManager.java:979)
	at org.eclipse.core.internal.localstore.FileSystemResourceManager.refresh(FileSystemResourceManager.java:959)
	at org.eclipse.core.internal.resources.AliasManager.updateAliases(AliasManager.java:727)
	at org.eclipse.core.internal.resources.Resource.delete(Resource.java:769)
	at org.eclipse.core.internal.resources.Project.delete(Project.java:322)
	at org.eclipse.egit.core.internal.util.ProjectUtil.refreshValidProjects(ProjectUtil.java:156)
	at org.eclipse.egit.core.op.BranchOperation$1.refreshAffectedProjects(BranchOperation.java:208)
	at org.eclipse.egit.core.op.BranchOperation$1.run(BranchOperation.java:147)
	at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2295)
	at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2322)
	at org.eclipse.egit.core.op.BranchOperation.execute(BranchOperation.java:233)
	at org.eclipse.egit.ui.internal.branch.BranchOperationUI.doCheckout(BranchOperationUI.java:192)
	at org.eclipse.egit.ui.internal.branch.BranchOperationUI.access$2(BranchOperationUI.java:188)
	at org.eclipse.egit.ui.internal.branch.BranchOperationUI$CheckoutJob.run(BranchOperationUI.java:262)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)
Contains: The project description file (.project) for 'org.eclipse.egit.core.junit' is missing.  This file contains important information about the project.  The project will not function properly until this file is restored.
java.lang.Exception: The project description file (.project) for 'org.eclipse.egit.core.junit' is missing.  This file contains important information about the project.  The project will not function properly until this file is restored.
	at org.eclipse.core.internal.resources.ResourceException.provideStackTrace(ResourceException.java:42)
	at org.eclipse.core.internal.resources.ResourceException.<init>(ResourceException.java:38)
	at org.eclipse.core.internal.localstore.FileSystemResourceManager.read(FileSystemResourceManager.java:906)
	at org.eclipse.core.internal.resources.Project.updateDescription(Project.java:1344)
	at org.eclipse.core.internal.resources.File.updateMetadataFiles(File.java:382)
	at org.eclipse.core.internal.localstore.RefreshLocalVisitor.visit(RefreshLocalVisitor.java:291)
	at org.eclipse.core.internal.localstore.UnifiedTree.accept(UnifiedTree.java:118)
	at org.eclipse.core.internal.localstore.FileSystemResourceManager.refreshResource(FileSystemResourceManager.java:976)
	at org.eclipse.core.internal.localstore.FileSystemResourceManager.refresh(FileSystemResourceManager.java:959)
	at org.eclipse.core.internal.resources.AliasManager.updateAliases(AliasManager.java:727)
	at org.eclipse.core.internal.resources.Resource.delete(Resource.java:769)
	at org.eclipse.core.internal.resources.Project.delete(Project.java:322)
	at org.eclipse.egit.core.internal.util.ProjectUtil.refreshValidProjects(ProjectUtil.java:156)
	at org.eclipse.egit.core.op.BranchOperation$1.refreshAffectedProjects(BranchOperation.java:208)
	at org.eclipse.egit.core.op.BranchOperation$1.run(BranchOperation.java:147)
	at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2295)
	at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2322)
	at org.eclipse.egit.core.op.BranchOperation.execute(BranchOperation.java:233)
	at org.eclipse.egit.ui.internal.branch.BranchOperationUI.doCheckout(BranchOperationUI.java:192)
	at org.eclipse.egit.ui.internal.branch.BranchOperationUI.access$2(BranchOperationUI.java:188)
	at org.eclipse.egit.ui.internal.branch.BranchOperationUI$CheckoutJob.run(BranchOperationUI.java:262)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)

The RepositoryChangeScanner problem mentioned in comment 7 had the stack trace

!ENTRY org.eclipse.core.jobs 4 2 2019-10-11 19:29:14.999
!MESSAGE An internal error occurred during: "Git Repository Change Scanner".
!STACK 0
java.lang.IllegalArgumentException: Attempted to beginRule: F/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal, does not match outer scope rule: org.eclipse.egit.ui.internal.RepositoryCacheRule@6384b9e9
	at org.eclipse.core.runtime.Assert.isLegal(Assert.java:63)
	at org.eclipse.core.internal.jobs.ThreadJob.illegalPush(ThreadJob.java:134)
	at org.eclipse.core.internal.jobs.ThreadJob.push(ThreadJob.java:333)
	at org.eclipse.core.internal.jobs.ImplicitJobs.begin(ImplicitJobs.java:85)
	at org.eclipse.core.internal.jobs.JobManager.beginRule(JobManager.java:307)
	at org.eclipse.core.internal.resources.WorkManager.checkIn(WorkManager.java:121)
	at org.eclipse.core.internal.resources.Workspace.prepareOperation(Workspace.java:2188)
	at org.eclipse.core.internal.resources.Resource.refreshLocal(Resource.java:1586)
	at org.eclipse.egit.core.internal.ResourceRefreshHandler.refreshRepository(ResourceRefreshHandler.java:100)
	at org.eclipse.egit.core.internal.ResourceRefreshHandler.onWorkingTreeModified(ResourceRefreshHandler.java:67)
	at org.eclipse.jgit.events.WorkingTreeModifiedEvent.dispatch(WorkingTreeModifiedEvent.java:132)
	at org.eclipse.jgit.events.WorkingTreeModifiedEvent.dispatch(WorkingTreeModifiedEvent.java:1)
	at org.eclipse.jgit.events.ListenerList.dispatch(ListenerList.java:133)
	at org.eclipse.jgit.lib.Repository.fireEvent(Repository.java:198)
	at org.eclipse.egit.ui.Activator$RepositoryChangeScanner.lambda$0(Activator.java:605)
	at org.eclipse.jgit.events.IndexChangedEvent.dispatch(IndexChangedEvent.java:81)
	at org.eclipse.jgit.events.IndexChangedEvent.dispatch(IndexChangedEvent.java:1)
	at org.eclipse.jgit.events.ListenerList.dispatch(ListenerList.java:133)
	at org.eclipse.jgit.lib.Repository.fireEvent(Repository.java:197)
	at org.eclipse.jgit.internal.storage.file.FileRepository.notifyIndexChanged(FileRepository.java:528)
	at org.eclipse.jgit.internal.storage.file.FileRepository.detectIndexChanges(FileRepository.java:519)
	at org.eclipse.jgit.internal.storage.file.FileRepository.scanForRepoChanges(FileRepository.java:500)
	at org.eclipse.egit.ui.Activator$RepositoryChangeScanner.run(Activator.java:670)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)
Comment 10 Eclipse Genie CLA 2019-10-12 11:19:21 EDT
Gerrit change https://git.eclipse.org/r/150967 was merged to [master].
Commit: http://git.eclipse.org/c/egit/egit.git/commit/?id=4eb4faf6079dde8e19f38fa9e677147c5145470e
Comment 11 Michael Keppler CLA 2019-10-13 14:48:00 EDT
Just to give some feedback: I had the rule conflicts on Saturday in several different IDEs (with the first change only), and I have not seen any such thing again after upgrading to your second change.
Comment 12 Thomas Wolf CLA 2019-12-04 11:45:49 EST
*** Bug 416199 has been marked as a duplicate of this bug. ***