diff --git a/src/ViewModels/CommitDetail.cs b/src/ViewModels/CommitDetail.cs index 602f1db3..85dcaa6a 100644 --- a/src/ViewModels/CommitDetail.cs +++ b/src/ViewModels/CommitDetail.cs @@ -114,6 +114,24 @@ namespace SourceGit.ViewModels { _repo = repo; } + public void Cleanup() { + _repo = null; + _commit = null; + if (_changes != null) _changes.Clear(); + if (_visibleChanges != null) _visibleChanges.Clear(); + if (_changeTree != null) _changeTree.Clear(); + _selectedChange = null; + _selectedChangeNode = null; + _searchChangeFilter = null; + _diffContext = null; + if (_revisionFiles != null) _revisionFiles.Clear(); + if (_revisionFilesTree != null) _revisionFilesTree.Clear(); + _selectedRevisionFileNode = null; + _searchFileFilter = null; + _viewRevisionFileContent = null; + _cancelToken = null; + } + public void NavigateTo(string commitSHA) { var repo = Preference.FindRepository(_repo); if (repo != null) repo.NavigateToCommit(commitSHA); diff --git a/src/ViewModels/Histories.cs b/src/ViewModels/Histories.cs index 942e3144..6878f58b 100644 --- a/src/ViewModels/Histories.cs +++ b/src/ViewModels/Histories.cs @@ -56,6 +56,22 @@ namespace SourceGit.ViewModels { _repo = repo; } + public void Cleanup() { + Commits = new List(); + + _repo = null; + _graph = null; + _autoSelectedCommit = null; + + if (_detailContext is CommitDetail cd) { + cd.Cleanup(); + } else if (_detailContext is RevisionCompare rc) { + rc.Cleanup(); + } + + _detailContext = null; + } + public void NavigateTo(string commitSHA) { var commit = _commits.Find(x => x.SHA.StartsWith(commitSHA)); if (commit != null) { diff --git a/src/ViewModels/Launcher.cs b/src/ViewModels/Launcher.cs index e53171f6..3d40574e 100644 --- a/src/ViewModels/Launcher.cs +++ b/src/ViewModels/Launcher.cs @@ -1,5 +1,8 @@ using Avalonia.Collections; +using Avalonia.Markup.Xaml.MarkupExtensions; using CommunityToolkit.Mvvm.ComponentModel; +using System; +using System.Collections.Generic; using System.IO; namespace SourceGit.ViewModels { @@ -74,8 +77,6 @@ namespace SourceGit.ViewModels { LauncherPage page = param as LauncherPage; if (page == null) page = _activePage; - CloseRepositoryInTab(page); - var removeIdx = Pages.IndexOf(page); var activeIdx = Pages.IndexOf(_activePage); if (removeIdx == activeIdx) { @@ -85,31 +86,37 @@ namespace SourceGit.ViewModels { ActivePage = Pages[removeIdx + 1]; } + CloseRepositoryInTab(page); Pages.RemoveAt(removeIdx); OnPropertyChanged(nameof(Pages)); } else if (removeIdx + 1 == activeIdx) { + CloseRepositoryInTab(page); Pages.RemoveAt(removeIdx); OnPropertyChanged(nameof(Pages)); } else { + CloseRepositoryInTab(page); Pages.RemoveAt(removeIdx); } + + GC.Collect(); } public void CloseOtherTabs(object param) { if (Pages.Count == 1) return; - LauncherPage page = param as LauncherPage; + var page = param as LauncherPage; if (page == null) page = _activePage; + ActivePage = page; + foreach (var one in Pages) { - if (one.Node.Id != page.Node.Id) { - CloseRepositoryInTab(one); - } + if (one.Node.Id != page.Node.Id) CloseRepositoryInTab(one); } - ActivePage = page; Pages = new AvaloniaList { page }; OnPropertyChanged(nameof(Pages)); + + GC.Collect(); } public void CloseRightTabs(object param) { @@ -126,6 +133,8 @@ namespace SourceGit.ViewModels { CloseRepositoryInTab(Pages[i]); Pages.Remove(Pages[i]); } + + GC.Collect(); } public void OpenRepositoryInTab(RepositoryNode node, LauncherPage page) { @@ -164,13 +173,15 @@ namespace SourceGit.ViewModels { } private void CloseRepositoryInTab(LauncherPage page) { - if (!page.Node.IsRepository) return; + if (page.Node.IsRepository) { + var repo = Preference.FindRepository(page.Node.Id); + if (repo != null) { + Commands.AutoFetch.RemoveRepository(repo.FullPath); + repo.Close(); + } + } - var repo = Preference.FindRepository(page.Node.Id); - if (repo == null) return; - - Commands.AutoFetch.RemoveRepository(repo.FullPath); - repo.Close(); + page.View = null; } private LauncherPage _activePage = null; diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index b42bb31b..a2da4b2e 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -189,12 +189,17 @@ namespace SourceGit.ViewModels { } public void Close() { + SelectedView = 0.0; // Do NOT modify. Used to remove exists widgets for GC.Collect + _watcher.Dispose(); + _histories.Cleanup(); + _workingCopy.Cleanup(); + _stashesPage.Cleanup(); + _watcher = null; _histories = null; _workingCopy = null; _stashesPage = null; - _selectedView = null; _isSearching = false; _searchCommitFilter = string.Empty; @@ -205,8 +210,6 @@ namespace SourceGit.ViewModels { _tags.Clear(); _submodules.Clear(); _searchedCommits.Clear(); - - GC.Collect(); } public void OpenInFileManager() { diff --git a/src/ViewModels/RevisionCompare.cs b/src/ViewModels/RevisionCompare.cs index c5534931..c85e5865 100644 --- a/src/ViewModels/RevisionCompare.cs +++ b/src/ViewModels/RevisionCompare.cs @@ -96,6 +96,17 @@ namespace SourceGit.ViewModels { }); } + public void Cleanup() { + _repo = null; + if (_changes != null) _changes.Clear(); + if (_visibleChanges != null) _visibleChanges.Clear(); + if (_changeTree != null) _changeTree.Clear(); + _selectedChange = null; + _selectedNode = null; + _searchFilter = null; + _diffContext = null; + } + public void NavigateTo(string commitSHA) { var repo = Preference.FindRepository(_repo); if (repo != null) repo.NavigateToCommit(commitSHA); diff --git a/src/ViewModels/StashesPage.cs b/src/ViewModels/StashesPage.cs index 12f8383b..c3dc0d8f 100644 --- a/src/ViewModels/StashesPage.cs +++ b/src/ViewModels/StashesPage.cs @@ -67,6 +67,15 @@ namespace SourceGit.ViewModels { _repo = repo; } + public void Cleanup() { + _repo = null; + if (_stashes != null) _stashes.Clear(); + _selectedStash = null; + if (_changes != null) _changes.Clear(); + _selectedChange = null; + _diffContext = null; + } + public void Apply(object param) { if (param is Models.Stash stash) { Task.Run(() => { diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs index 2306f9fa..50392174 100644 --- a/src/ViewModels/WorkingCopy.cs +++ b/src/ViewModels/WorkingCopy.cs @@ -78,6 +78,17 @@ namespace SourceGit.ViewModels { _repo = repo; } + public void Cleanup() { + _repo = null; + if (_unstaged != null) _unstaged.Clear(); + if (_staged != null) _staged.Clear(); + if (_unstagedTree != null) _unstagedTree.Clear(); + if (_stagedTree != null) _stagedTree.Clear(); + _lastViewChange = null; + _detailContext = null; + _commitMessage = string.Empty; + } + public bool SetData(List changes) { var unstaged = new List(); var staged = new List(); diff --git a/src/Views/Repository.axaml b/src/Views/Repository.axaml index 23c544c5..4876121f 100644 --- a/src/Views/Repository.axaml +++ b/src/Views/Repository.axaml @@ -466,6 +466,10 @@ + + + +