refactor: move settings of repository, such as filters, commit message, from Preference to each repository's gitdir.

* avoid invalid repository setting remains in preference.json
* supports to restore tabs that not added to the Welcome page
This commit is contained in:
leo 2024-07-01 11:57:13 +08:00
parent 56a42dd6e8
commit 7f389b2e6f
No known key found for this signature in database
18 changed files with 187 additions and 209 deletions

View file

@ -9,5 +9,6 @@ namespace SourceGit
[JsonSerializable(typeof(List<Models.InteractiveRebaseJob>))] [JsonSerializable(typeof(List<Models.InteractiveRebaseJob>))]
[JsonSerializable(typeof(Dictionary<string, string>))] [JsonSerializable(typeof(Dictionary<string, string>))]
[JsonSerializable(typeof(ViewModels.Preference))] [JsonSerializable(typeof(ViewModels.Preference))]
[JsonSerializable(typeof(ViewModels.RepositorySettings))]
internal partial class JsonCodeGen : JsonSerializerContext { } internal partial class JsonCodeGen : JsonSerializerContext { }
} }

View file

@ -187,6 +187,18 @@ namespace SourceGit
} }
} }
public static async Task<string> GetClipboardTextAsync()
{
if (Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
if (desktop.MainWindow.Clipboard is { } clipboard)
{
return await clipboard.GetTextAsync();
}
}
return default;
}
public static string Text(string key, params object[] args) public static string Text(string key, params object[] args)
{ {
var fmt = Current.FindResource($"Text.{key}") as string; var fmt = Current.FindResource($"Text.{key}") as string;
@ -259,6 +271,21 @@ namespace SourceGit
}); });
} }
public static ViewModels.Repository FindOpenedRepository(string repoPath)
{
if (Current is App app && app._launcher != null)
{
foreach (var page in app._launcher.Pages)
{
var id = page.Node.Id.Replace("\\", "/");
if (id == repoPath && page.Data is ViewModels.Repository repo)
return repo;
}
}
return null;
}
public static void Quit() public static void Quit()
{ {
if (Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) if (Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
@ -288,9 +315,10 @@ namespace SourceGit
_launcher = new ViewModels.Launcher(); _launcher = new ViewModels.Launcher();
desktop.MainWindow = new Views.Launcher() { DataContext = _launcher }; desktop.MainWindow = new Views.Launcher() { DataContext = _launcher };
if (ViewModels.Preference.Instance.ShouldCheck4UpdateOnStartup) var pref = ViewModels.Preference.Instance;
if (pref.ShouldCheck4UpdateOnStartup)
{ {
ViewModels.Preference.Save(); pref.Save();
Check4Update(); Check4Update();
} }
} }
@ -317,18 +345,6 @@ namespace SourceGit
}); });
} }
public static async Task<string> GetClipboardTextAsync()
{
if (Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
if (desktop.MainWindow.Clipboard is { } clipboard)
{
return await clipboard.GetTextAsync();
}
}
return default;
}
private ViewModels.Launcher _launcher = null; private ViewModels.Launcher _launcher = null;
private ResourceDictionary _activeLocale = null; private ResourceDictionary _activeLocale = null;
private ResourceDictionary _colorOverrides = null; private ResourceDictionary _colorOverrides = null;

View file

@ -49,9 +49,8 @@ namespace SourceGit.ViewModels
public void NavigateToCommit(string commitSHA) public void NavigateToCommit(string commitSHA)
{ {
var repo = Preference.FindRepository(_repo); var repo = App.FindOpenedRepository(_repo);
if (repo != null) repo?.NavigateToCommit(commitSHA);
repo.NavigateToCommit(commitSHA);
} }
private readonly string _repo = string.Empty; private readonly string _repo = string.Empty;

View file

@ -110,9 +110,8 @@ namespace SourceGit.ViewModels
public void NavigateTo(string commitSHA) public void NavigateTo(string commitSHA)
{ {
var repo = Preference.FindRepository(_repo); var repo = App.FindOpenedRepository(_repo);
if (repo != null) repo?.NavigateToCommit(commitSHA);
repo.NavigateToCommit(commitSHA);
} }
public void ClearSearchFilter() public void ClearSearchFilter()

View file

@ -128,8 +128,8 @@ namespace SourceGit.ViewModels
CallUIThread(() => CallUIThread(() =>
{ {
var repo = Preference.AddRepository(path, Path.Combine(path, ".git")); var normalizedPath = path.Replace("\\", "/");
var node = Preference.FindOrAddNodeByRepositoryPath(repo.FullPath, null, true); var node = Preference.FindOrAddNodeByRepositoryPath(normalizedPath, null, true);
_launcher.OpenRepositoryInTab(node, _page); _launcher.OpenRepositoryInTab(node, _page);
}); });

View file

@ -110,9 +110,8 @@ namespace SourceGit.ViewModels
public void NavigateTo(string commitSHA) public void NavigateTo(string commitSHA)
{ {
var repo = Preference.FindRepository(_repo); var repo = App.FindOpenedRepository(_repo);
if (repo != null) repo?.NavigateToCommit(commitSHA);
repo.NavigateToCommit(commitSHA);
} }
public void ClearSearchChangeFilter() public void ClearSearchChangeFilter()

View file

@ -111,7 +111,7 @@ namespace SourceGit.ViewModels
if (latest.TextDiff != null) if (latest.TextDiff != null)
{ {
var repo = Preference.FindRepository(_repo); var repo = App.FindOpenedRepository(_repo);
if (repo != null && repo.Submodules.Contains(_option.Path)) if (repo != null && repo.Submodules.Contains(_option.Path))
{ {
var submoduleDiff = new Models.SubmoduleDiff(); var submoduleDiff = new Models.SubmoduleDiff();

View file

@ -1,5 +1,4 @@
using System.IO; using System.Threading.Tasks;
using System.Threading.Tasks;
namespace SourceGit.ViewModels namespace SourceGit.ViewModels
{ {
@ -29,11 +28,10 @@ namespace SourceGit.ViewModels
if (!succ) if (!succ)
return false; return false;
var gitDir = Path.GetFullPath(Path.Combine(_targetPath, ".git"));
CallUIThread(() => CallUIThread(() =>
{ {
var repo = Preference.AddRepository(_targetPath, gitDir); var normalizedPath = _targetPath.Replace("\\", "/");
Preference.FindOrAddNodeByRepositoryPath(repo.FullPath, _parentNode, true); Preference.FindOrAddNodeByRepositoryPath(normalizedPath, _parentNode, true);
}); });
return true; return true;

View file

@ -48,9 +48,8 @@ namespace SourceGit.ViewModels
return; return;
} }
var gitDir = new Commands.QueryGitDir(root).Result(); var normalized = root.Replace("\\", "/");
var repo = Preference.AddRepository(root, gitDir); var node = Preference.FindOrAddNodeByRepositoryPath(normalized, null, false);
var node = Preference.FindOrAddNodeByRepositoryPath(repo.FullPath, null, false);
OpenRepositoryInTab(node, null); OpenRepositoryInTab(node, null);
} }
else if (Preference.Instance.RestoreTabs) else if (Preference.Instance.RestoreTabs)
@ -59,7 +58,15 @@ namespace SourceGit.ViewModels
{ {
var node = Preference.FindNode(id); var node = Preference.FindNode(id);
if (node == null) if (node == null)
continue; {
node = new RepositoryNode()
{
Id = id,
Name = Path.GetFileName(id),
Bookmark = 0,
IsRepository = true,
};
}
OpenRepositoryInTab(node, null); OpenRepositoryInTab(node, null);
} }
@ -72,19 +79,26 @@ namespace SourceGit.ViewModels
public void Quit() public void Quit()
{ {
Preference.Instance.OpenedTabs.Clear(); var pref = Preference.Instance;
pref.OpenedTabs.Clear();
if (Preference.Instance.RestoreTabs) if (pref.RestoreTabs)
{ {
foreach (var page in Pages) foreach (var page in Pages)
{ {
if (page.Node.IsRepository) if (page.Node.IsRepository)
Preference.Instance.OpenedTabs.Add(page.Node.Id); pref.OpenedTabs.Add(page.Node.Id);
} }
} }
Preference.Instance.LastActiveTabIdx = Pages.IndexOf(ActivePage); pref.LastActiveTabIdx = Pages.IndexOf(ActivePage);
Preference.Save(); pref.Save();
foreach (var page in Pages)
{
if (page.Data is Repository repo)
repo.Close();
}
} }
public void AddNewTab() public void AddNewTab()
@ -211,14 +225,27 @@ namespace SourceGit.ViewModels
} }
} }
var repo = Preference.FindRepository(node.Id); if (!Path.Exists(node.Id))
if (repo == null || !Path.Exists(repo.FullPath))
{ {
var ctx = page == null ? ActivePage.Node.Id : page.Node.Id; var ctx = page == null ? ActivePage.Node.Id : page.Node.Id;
App.RaiseException(ctx, "Repository does NOT exists any more. Please remove it."); App.RaiseException(ctx, "Repository does NOT exists any more. Please remove it.");
return; return;
} }
var gitDir = new Commands.QueryGitDir(node.Id).Result();
if (string.IsNullOrEmpty(gitDir))
{
var ctx = page == null ? ActivePage.Node.Id : page.Node.Id;
App.RaiseException(ctx, "Given path is not a valid git repository!");
return;
}
var repo = new Repository()
{
FullPath = node.Id,
GitDir = gitDir,
};
repo.Open(); repo.Open();
Commands.AutoFetch.AddRepository(repo.FullPath); Commands.AutoFetch.AddRepository(repo.FullPath);

View file

@ -37,23 +37,14 @@ namespace SourceGit.ViewModels
} }
} }
// It will cause some issue on Linux. See https://github.com/sourcegit-scm/sourcegit/issues/99
// _instance.Repositories.RemoveAll(x => !Directory.Exists(x.FullPath));
if (_instance.DefaultFont == null) if (_instance.DefaultFont == null)
{
_instance.DefaultFont = FontManager.Current.DefaultFontFamily; _instance.DefaultFont = FontManager.Current.DefaultFontFamily;
}
if (_instance.MonospaceFont == null) if (_instance.MonospaceFont == null)
{
_instance.MonospaceFont = new FontFamily("fonts:SourceGit#JetBrains Mono"); _instance.MonospaceFont = new FontFamily("fonts:SourceGit#JetBrains Mono");
}
if (!_instance.IsGitConfigured) if (!_instance.IsGitConfigured)
{
_instance.GitInstallPath = Native.OS.FindGitExecutable(); _instance.GitInstallPath = Native.OS.FindGitExecutable();
}
return _instance; return _instance;
} }
@ -274,9 +265,8 @@ namespace SourceGit.ViewModels
set set
{ {
if (value is null or < 1) if (value is null or < 1)
{
return; return;
}
if (Commands.AutoFetch.Interval != value) if (Commands.AutoFetch.Interval != value)
{ {
Commands.AutoFetch.Interval = (int)value; Commands.AutoFetch.Interval = (int)value;
@ -308,12 +298,6 @@ namespace SourceGit.ViewModels
set => SetProperty(ref _externalMergeToolPath, value); set => SetProperty(ref _externalMergeToolPath, value);
} }
public List<Repository> Repositories
{
get;
set;
} = new List<Repository>();
public AvaloniaList<RepositoryNode> RepositoryNodes public AvaloniaList<RepositoryNode> RepositoryNodes
{ {
get => _repositoryNodes; get => _repositoryNodes;
@ -366,20 +350,14 @@ namespace SourceGit.ViewModels
list.Sort((l, r) => list.Sort((l, r) =>
{ {
if (l.IsRepository != r.IsRepository) if (l.IsRepository != r.IsRepository)
{
return l.IsRepository ? 1 : -1; return l.IsRepository ? 1 : -1;
}
else else
{
return l.Name.CompareTo(r.Name); return l.Name.CompareTo(r.Name);
}
}); });
collection.Clear(); collection.Clear();
foreach (var one in list) foreach (var one in list)
{
collection.Add(one); collection.Add(one);
}
} }
public static RepositoryNode FindNode(string id) public static RepositoryNode FindNode(string id)
@ -451,39 +429,9 @@ namespace SourceGit.ViewModels
container.Add(one); container.Add(one);
} }
public static Repository FindRepository(string path) public void Save()
{ {
foreach (var repo in _instance.Repositories) var data = JsonSerializer.Serialize(this, JsonCodeGen.Default.Preference);
{
if (repo.FullPath == path)
return repo;
}
return null;
}
public static Repository AddRepository(string rootDir, string gitDir)
{
var normalized = rootDir.Replace('\\', '/');
var repo = FindRepository(normalized);
if (repo != null)
{
repo.GitDir = gitDir;
return repo;
}
repo = new Repository()
{
FullPath = normalized,
GitDir = gitDir
};
_instance.Repositories.Add(repo);
return repo;
}
public static void Save()
{
var data = JsonSerializer.Serialize(_instance, JsonCodeGen.Default.Preference);
File.WriteAllText(_savePath, data); File.WriteAllText(_savePath, data);
} }

View file

@ -55,8 +55,8 @@ namespace SourceGit.ViewModels
public bool UseRebase public bool UseRebase
{ {
get => _repo.PreferRebaseInsteadOfMerge; get => _repo.Settings.PreferRebaseInsteadOfMerge;
set => _repo.PreferRebaseInsteadOfMerge = value; set => _repo.Settings.PreferRebaseInsteadOfMerge = value;
} }
public Pull(Repository repo, Models.Branch specifiedRemoteBranch) public Pull(Repository repo, Models.Branch specifiedRemoteBranch)

View file

@ -1,7 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Text.Json.Serialization; using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
using Avalonia.Collections; using Avalonia.Collections;
@ -14,6 +14,45 @@ using CommunityToolkit.Mvvm.ComponentModel;
namespace SourceGit.ViewModels namespace SourceGit.ViewModels
{ {
public class RepositorySettings : ObservableObject
{
public bool PreferRebaseInsteadOfMerge
{
get;
set;
} = true;
public AvaloniaList<string> Filters
{
get;
set;
} = new AvaloniaList<string>();
public AvaloniaList<string> CommitMessages
{
get;
set;
} = new AvaloniaList<string>();
public void PushCommitMessage(string message)
{
var existIdx = CommitMessages.IndexOf(message);
if (existIdx == 0)
return;
if (existIdx > 0)
{
CommitMessages.Move(existIdx, 0);
return;
}
if (CommitMessages.Count > 9)
CommitMessages.RemoveRange(9, CommitMessages.Count - 9);
CommitMessages.Insert(0, message);
}
}
public class Repository : ObservableObject, Models.IRepository public class Repository : ObservableObject, Models.IRepository
{ {
public string FullPath public string FullPath
@ -39,25 +78,12 @@ namespace SourceGit.ViewModels
set => SetProperty(ref _gitDir, value); set => SetProperty(ref _gitDir, value);
} }
public bool PreferRebaseInsteadOfMerge public RepositorySettings Settings
{ {
get; get => _settings;
set; private set => SetProperty(ref _settings, value);
} = true; }
public AvaloniaList<string> Filters
{
get;
set;
} = new AvaloniaList<string>();
public AvaloniaList<string> CommitMessages
{
get;
set;
} = new AvaloniaList<string>();
[JsonIgnore]
public int SelectedViewIndex public int SelectedViewIndex
{ {
get => _selectedViewIndex; get => _selectedViewIndex;
@ -81,14 +107,12 @@ namespace SourceGit.ViewModels
} }
} }
[JsonIgnore]
public object SelectedView public object SelectedView
{ {
get => _selectedView; get => _selectedView;
set => SetProperty(ref _selectedView, value); set => SetProperty(ref _selectedView, value);
} }
[JsonIgnore]
public string SearchBranchFilter public string SearchBranchFilter
{ {
get => _searchBranchFilter; get => _searchBranchFilter;
@ -104,75 +128,64 @@ namespace SourceGit.ViewModels
} }
} }
[JsonIgnore]
public List<Models.Remote> Remotes public List<Models.Remote> Remotes
{ {
get => _remotes; get => _remotes;
private set => SetProperty(ref _remotes, value); private set => SetProperty(ref _remotes, value);
} }
[JsonIgnore]
public List<Models.Branch> Branches public List<Models.Branch> Branches
{ {
get => _branches; get => _branches;
private set => SetProperty(ref _branches, value); private set => SetProperty(ref _branches, value);
} }
[JsonIgnore]
public List<BranchTreeNode> LocalBranchTrees public List<BranchTreeNode> LocalBranchTrees
{ {
get => _localBranchTrees; get => _localBranchTrees;
private set => SetProperty(ref _localBranchTrees, value); private set => SetProperty(ref _localBranchTrees, value);
} }
[JsonIgnore]
public List<BranchTreeNode> RemoteBranchTrees public List<BranchTreeNode> RemoteBranchTrees
{ {
get => _remoteBranchTrees; get => _remoteBranchTrees;
private set => SetProperty(ref _remoteBranchTrees, value); private set => SetProperty(ref _remoteBranchTrees, value);
} }
[JsonIgnore]
public List<Models.Worktree> Worktrees public List<Models.Worktree> Worktrees
{ {
get => _worktrees; get => _worktrees;
private set => SetProperty(ref _worktrees, value); private set => SetProperty(ref _worktrees, value);
} }
[JsonIgnore]
public List<Models.Tag> Tags public List<Models.Tag> Tags
{ {
get => _tags; get => _tags;
private set => SetProperty(ref _tags, value); private set => SetProperty(ref _tags, value);
} }
[JsonIgnore]
public List<Models.Tag> VisibleTags public List<Models.Tag> VisibleTags
{ {
get => _visibleTags; get => _visibleTags;
private set => SetProperty(ref _visibleTags, value); private set => SetProperty(ref _visibleTags, value);
} }
[JsonIgnore]
public List<string> Submodules public List<string> Submodules
{ {
get => _submodules; get => _submodules;
private set => SetProperty(ref _submodules, value); private set => SetProperty(ref _submodules, value);
} }
[JsonIgnore]
public int WorkingCopyChangesCount public int WorkingCopyChangesCount
{ {
get => _workingCopy == null ? 0 : _workingCopy.Count; get => _workingCopy == null ? 0 : _workingCopy.Count;
} }
[JsonIgnore]
public int StashesCount public int StashesCount
{ {
get => _stashesPage == null ? 0 : _stashesPage.Stashes.Count; get => _stashesPage == null ? 0 : _stashesPage.Stashes.Count;
} }
[JsonIgnore]
public bool IncludeUntracked public bool IncludeUntracked
{ {
get => _includeUntracked; get => _includeUntracked;
@ -183,7 +196,6 @@ namespace SourceGit.ViewModels
} }
} }
[JsonIgnore]
public bool IsSearching public bool IsSearching
{ {
get => _isSearching; get => _isSearching;
@ -199,63 +211,54 @@ namespace SourceGit.ViewModels
} }
} }
[JsonIgnore]
public int SearchCommitFilterType public int SearchCommitFilterType
{ {
get => _searchCommitFilterType; get => _searchCommitFilterType;
set => SetProperty(ref _searchCommitFilterType, value); set => SetProperty(ref _searchCommitFilterType, value);
} }
[JsonIgnore]
public string SearchCommitFilter public string SearchCommitFilter
{ {
get => _searchCommitFilter; get => _searchCommitFilter;
set => SetProperty(ref _searchCommitFilter, value); set => SetProperty(ref _searchCommitFilter, value);
} }
[JsonIgnore]
public List<Models.Commit> SearchedCommits public List<Models.Commit> SearchedCommits
{ {
get => _searchedCommits; get => _searchedCommits;
set => SetProperty(ref _searchedCommits, value); set => SetProperty(ref _searchedCommits, value);
} }
[JsonIgnore]
public bool IsTagGroupExpanded public bool IsTagGroupExpanded
{ {
get => _isTagGroupExpanded; get => _isTagGroupExpanded;
set => SetProperty(ref _isTagGroupExpanded, value); set => SetProperty(ref _isTagGroupExpanded, value);
} }
[JsonIgnore]
public bool IsSubmoduleGroupExpanded public bool IsSubmoduleGroupExpanded
{ {
get => _isSubmoduleGroupExpanded; get => _isSubmoduleGroupExpanded;
set => SetProperty(ref _isSubmoduleGroupExpanded, value); set => SetProperty(ref _isSubmoduleGroupExpanded, value);
} }
[JsonIgnore]
public bool IsWorktreeGroupExpanded public bool IsWorktreeGroupExpanded
{ {
get => _isWorktreeGroupExpanded; get => _isWorktreeGroupExpanded;
set => SetProperty(ref _isWorktreeGroupExpanded, value); set => SetProperty(ref _isWorktreeGroupExpanded, value);
} }
[JsonIgnore]
public InProgressContext InProgressContext public InProgressContext InProgressContext
{ {
get => _inProgressContext; get => _inProgressContext;
private set => SetProperty(ref _inProgressContext, value); private set => SetProperty(ref _inProgressContext, value);
} }
[JsonIgnore]
public bool HasUnsolvedConflicts public bool HasUnsolvedConflicts
{ {
get => _hasUnsolvedConflicts; get => _hasUnsolvedConflicts;
private set => SetProperty(ref _hasUnsolvedConflicts, value); private set => SetProperty(ref _hasUnsolvedConflicts, value);
} }
[JsonIgnore]
public Models.Commit SearchResultSelectedCommit public Models.Commit SearchResultSelectedCommit
{ {
get => _searchResultSelectedCommit; get => _searchResultSelectedCommit;
@ -264,6 +267,16 @@ namespace SourceGit.ViewModels
public void Open() public void Open()
{ {
var settingsFile = Path.Combine(_gitDir, "sourcegit.settings");
try
{
_settings = JsonSerializer.Deserialize(File.ReadAllText(settingsFile), JsonCodeGen.Default.RepositorySettings);
}
catch
{
_settings = new RepositorySettings();
}
_watcher = new Models.Watcher(this); _watcher = new Models.Watcher(this);
_histories = new Histories(this); _histories = new Histories(this);
_workingCopy = new WorkingCopy(this); _workingCopy = new WorkingCopy(this);
@ -280,6 +293,10 @@ namespace SourceGit.ViewModels
{ {
SelectedView = 0.0; // Do NOT modify. Used to remove exists widgets for GC.Collect SelectedView = 0.0; // Do NOT modify. Used to remove exists widgets for GC.Collect
var settingsSerialized = JsonSerializer.Serialize(_settings, JsonCodeGen.Default.RepositorySettings);
File.WriteAllText(Path.Combine(_gitDir, "sourcegit.settings"), settingsSerialized);
_settings = null;
_watcher.Dispose(); _watcher.Dispose();
_histories.Cleanup(); _histories.Cleanup();
_workingCopy.Cleanup(); _workingCopy.Cleanup();
@ -436,7 +453,7 @@ namespace SourceGit.ViewModels
public void ClearHistoriesFilter() public void ClearHistoriesFilter()
{ {
Filters.Clear(); _settings.Filters.Clear();
Task.Run(() => Task.Run(() =>
{ {
@ -525,15 +542,15 @@ namespace SourceGit.ViewModels
var changed = false; var changed = false;
if (toggle) if (toggle)
{ {
if (!Filters.Contains(filter)) if (!_settings.Filters.Contains(filter))
{ {
Filters.Add(filter); _settings.Filters.Add(filter);
changed = true; changed = true;
} }
} }
else else
{ {
changed = Filters.Remove(filter); changed = _settings.Filters.Remove(filter);
} }
if (changed) if (changed)
@ -637,7 +654,7 @@ namespace SourceGit.ViewModels
{ {
var tags = new Commands.QueryTags(FullPath).Result(); var tags = new Commands.QueryTags(FullPath).Result();
foreach (var tag in tags) foreach (var tag in tags)
tag.IsFiltered = Filters.Contains(tag.Name); tag.IsFiltered = _settings.Filters.Contains(tag.Name);
Dispatcher.UIThread.Invoke(() => Dispatcher.UIThread.Invoke(() =>
{ {
@ -652,7 +669,7 @@ namespace SourceGit.ViewModels
var limits = $"-{Preference.Instance.MaxHistoryCommits} "; var limits = $"-{Preference.Instance.MaxHistoryCommits} ";
var validFilters = new List<string>(); var validFilters = new List<string>();
foreach (var filter in Filters) foreach (var filter in _settings.Filters)
{ {
if (filter.StartsWith("refs/", StringComparison.Ordinal)) if (filter.StartsWith("refs/", StringComparison.Ordinal))
{ {
@ -670,12 +687,12 @@ namespace SourceGit.ViewModels
{ {
limits += string.Join(" ", validFilters); limits += string.Join(" ", validFilters);
if (Filters.Count != validFilters.Count) if (_settings.Filters.Count != validFilters.Count)
{ {
Dispatcher.UIThread.Post(() => Dispatcher.UIThread.Post(() =>
{ {
Filters.Clear(); _settings.Filters.Clear();
Filters.AddRange(validFilters); _settings.Filters.AddRange(validFilters);
}); });
} }
} }
@ -851,22 +868,23 @@ namespace SourceGit.ViewModels
public void OpenSubmodule(string submodule) public void OpenSubmodule(string submodule)
{ {
var root = Path.GetFullPath(Path.Combine(_fullpath, submodule)); var root = Path.GetFullPath(Path.Combine(_fullpath, submodule));
var gitDir = new Commands.QueryGitDir(root).Result(); var normalizedPath = root.Replace("\\", "/");
var repo = Preference.AddRepository(root, gitDir);
var node = new RepositoryNode() var node = Preference.FindNode(normalizedPath);
if (node == null)
{ {
Id = repo.FullPath, node = new RepositoryNode()
Name = Path.GetFileName(repo.FullPath), {
Bookmark = 0, Id = normalizedPath,
IsRepository = true, Name = Path.GetFileName(normalizedPath),
}; Bookmark = 0,
IsRepository = true,
};
}
var launcher = App.GetTopLevel().DataContext as Launcher; var launcher = App.GetTopLevel().DataContext as Launcher;
if (launcher != null) if (launcher != null)
{
launcher.OpenRepositoryInTab(node, null); launcher.OpenRepositoryInTab(node, null);
}
} }
public void AddWorktree() public void AddWorktree()
@ -883,16 +901,17 @@ namespace SourceGit.ViewModels
public void OpenWorktree(Models.Worktree worktree) public void OpenWorktree(Models.Worktree worktree)
{ {
var gitDir = new Commands.QueryGitDir(worktree.FullPath).Result(); var node = Preference.FindNode(worktree.FullPath);
var repo = Preference.AddRepository(worktree.FullPath, gitDir); if (node == null)
var node = new RepositoryNode()
{ {
Id = repo.FullPath, node = new RepositoryNode()
Name = Path.GetFileName(repo.FullPath), {
Bookmark = 0, Id = worktree.FullPath,
IsRepository = true, Name = Path.GetFileName(worktree.FullPath),
}; Bookmark = 0,
IsRepository = true,
};
}
var launcher = App.GetTopLevel().DataContext as Launcher; var launcher = App.GetTopLevel().DataContext as Launcher;
if (launcher != null) if (launcher != null)
@ -1814,7 +1833,7 @@ namespace SourceGit.ViewModels
private BranchTreeNode.Builder BuildBranchTree(List<Models.Branch> branches, List<Models.Remote> remotes) private BranchTreeNode.Builder BuildBranchTree(List<Models.Branch> branches, List<Models.Remote> remotes)
{ {
var builder = new BranchTreeNode.Builder(); var builder = new BranchTreeNode.Builder();
builder.SetFilters(Filters); builder.SetFilters(_settings.Filters);
if (string.IsNullOrEmpty(_searchBranchFilter)) if (string.IsNullOrEmpty(_searchBranchFilter))
{ {
@ -1858,6 +1877,7 @@ namespace SourceGit.ViewModels
private string _fullpath = string.Empty; private string _fullpath = string.Empty;
private string _gitDir = string.Empty; private string _gitDir = string.Empty;
private RepositorySettings _settings = null;
private Models.Watcher _watcher = null; private Models.Watcher _watcher = null;
private Histories _histories = null; private Histories _histories = null;

View file

@ -118,9 +118,8 @@ namespace SourceGit.ViewModels
public void NavigateTo(string commitSHA) public void NavigateTo(string commitSHA)
{ {
var repo = Preference.FindRepository(_repo); var repo = App.FindOpenedRepository(_repo);
if (repo != null) repo?.NavigateToCommit(commitSHA);
repo.NavigateToCommit(commitSHA);
} }
public void ClearSearchFilter() public void ClearSearchFilter()

View file

@ -90,7 +90,6 @@ namespace SourceGit.ViewModels
public ContextMenu CreateContextMenu(RepositoryNode node) public ContextMenu CreateContextMenu(RepositoryNode node)
{ {
var menu = new ContextMenu(); var menu = new ContextMenu();
var hasRepo = Preference.FindRepository(node.Id) != null;
if (!node.IsRepository && node.SubNodes.Count > 0) if (!node.IsRepository && node.SubNodes.Count > 0)
{ {
@ -115,7 +114,6 @@ namespace SourceGit.ViewModels
var edit = new MenuItem(); var edit = new MenuItem();
edit.Header = App.Text("Welcome.Edit"); edit.Header = App.Text("Welcome.Edit");
edit.Icon = App.CreateMenuIcon("Icons.Edit"); edit.Icon = App.CreateMenuIcon("Icons.Edit");
edit.IsEnabled = !node.IsRepository || hasRepo;
edit.Click += (_, e) => edit.Click += (_, e) =>
{ {
node.Edit(); node.Edit();
@ -128,7 +126,6 @@ namespace SourceGit.ViewModels
var explore = new MenuItem(); var explore = new MenuItem();
explore.Header = App.Text("Repository.Explore"); explore.Header = App.Text("Repository.Explore");
explore.Icon = App.CreateMenuIcon("Icons.Folder.Open"); explore.Icon = App.CreateMenuIcon("Icons.Folder.Open");
explore.IsEnabled = hasRepo;
explore.Click += (_, e) => explore.Click += (_, e) =>
{ {
node.OpenInFileManager(); node.OpenInFileManager();
@ -139,7 +136,6 @@ namespace SourceGit.ViewModels
var terminal = new MenuItem(); var terminal = new MenuItem();
terminal.Header = App.Text("Repository.Terminal"); terminal.Header = App.Text("Repository.Terminal");
terminal.Icon = App.CreateMenuIcon("Icons.Terminal"); terminal.Icon = App.CreateMenuIcon("Icons.Terminal");
terminal.IsEnabled = hasRepo;
terminal.Click += (_, e) => terminal.Click += (_, e) =>
{ {
node.OpenTerminal(); node.OpenTerminal();

View file

@ -1113,7 +1113,7 @@ namespace SourceGit.ViewModels
public ContextMenu CreateContextMenuForCommitMessages() public ContextMenu CreateContextMenuForCommitMessages()
{ {
var menu = new ContextMenu(); var menu = new ContextMenu();
if (_repo.CommitMessages.Count == 0) if (_repo.Settings.CommitMessages.Count == 0)
{ {
var empty = new MenuItem(); var empty = new MenuItem();
empty.Header = App.Text("WorkingCopy.NoCommitHistories"); empty.Header = App.Text("WorkingCopy.NoCommitHistories");
@ -1128,7 +1128,7 @@ namespace SourceGit.ViewModels
menu.Items.Add(tip); menu.Items.Add(tip);
menu.Items.Add(new MenuItem() { Header = "-" }); menu.Items.Add(new MenuItem() { Header = "-" });
foreach (var message in _repo.CommitMessages) foreach (var message in _repo.Settings.CommitMessages)
{ {
var dump = message; var dump = message;
@ -1228,7 +1228,7 @@ namespace SourceGit.ViewModels
return; return;
} }
PushCommitMessage(); _repo.Settings.PushCommitMessage(_commitMessage);
SetDetail(null); SetDetail(null);
IsCommitting = true; IsCommitting = true;
@ -1257,27 +1257,6 @@ namespace SourceGit.ViewModels
}); });
} }
private void PushCommitMessage()
{
var existIdx = _repo.CommitMessages.IndexOf(CommitMessage);
if (existIdx == 0)
{
return;
}
else if (existIdx > 0)
{
_repo.CommitMessages.Move(existIdx, 0);
return;
}
if (_repo.CommitMessages.Count > 9)
{
_repo.CommitMessages.RemoveRange(9, _repo.CommitMessages.Count - 9);
}
_repo.CommitMessages.Insert(0, CommitMessage);
}
private Repository _repo = null; private Repository _repo = null;
private bool _isLoadingData = false; private bool _isLoadingData = false;
private bool _isStaging = false; private bool _isStaging = false;

View file

@ -378,11 +378,9 @@ namespace SourceGit.Views
private void OnCommitSHAPointerPressed(object sender, PointerPressedEventArgs e) private void OnCommitSHAPointerPressed(object sender, PointerPressedEventArgs e)
{ {
if (DataContext is ViewModels.Blame blame) if (sender is TextBlock txt && DataContext is ViewModels.Blame blame)
{
var txt = sender as TextBlock;
blame.NavigateToCommit(txt.Text); blame.NavigateToCommit(txt.Text);
}
e.Handled = true; e.Handled = true;
} }

View file

@ -794,14 +794,14 @@
<Border.IsVisible> <Border.IsVisible>
<MultiBinding Converter="{x:Static BoolConverters.And}"> <MultiBinding Converter="{x:Static BoolConverters.And}">
<Binding Path="SelectedViewIndex" Converter="{x:Static c:IntConverters.IsZero}"/> <Binding Path="SelectedViewIndex" Converter="{x:Static c:IntConverters.IsZero}"/>
<Binding Path="Filters.Count" Converter="{x:Static c:IntConverters.IsGreaterThanZero}"/> <Binding Path="Settings.Filters.Count" Converter="{x:Static c:IntConverters.IsGreaterThanZero}"/>
</MultiBinding> </MultiBinding>
</Border.IsVisible> </Border.IsVisible>
<Grid Height="28" ColumnDefinitions="Auto,*,Auto"> <Grid Height="28" ColumnDefinitions="Auto,*,Auto">
<TextBlock Grid.Column="0" Margin="8,0,0,0" Classes="info_label" Text="{DynamicResource Text.Repository.FilterCommitPrefix}"/> <TextBlock Grid.Column="0" Margin="8,0,0,0" Classes="info_label" Text="{DynamicResource Text.Repository.FilterCommitPrefix}"/>
<ItemsControl Grid.Column="1" Margin="8,0,0,0" ItemsSource="{Binding Filters}"> <ItemsControl Grid.Column="1" Margin="8,0,0,0" ItemsSource="{Binding Settings.Filters}">
<ItemsControl.ItemsPanel> <ItemsControl.ItemsPanel>
<ItemsPanelTemplate> <ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal" VerticalAlignment="Center"/> <VirtualizingStackPanel Orientation="Horizontal" VerticalAlignment="Center"/>

View file

@ -253,11 +253,10 @@ namespace SourceGit.Views
return; return;
} }
var gitDir = new Commands.QueryGitDir(root).Result();
Dispatcher.UIThread.Invoke(() => Dispatcher.UIThread.Invoke(() =>
{ {
var repo = ViewModels.Preference.AddRepository(root, gitDir); var normalizedPath = root.Replace("\\", "/");
var node = ViewModels.Preference.FindOrAddNodeByRepositoryPath(repo.FullPath, parent, true); var node = ViewModels.Preference.FindOrAddNodeByRepositoryPath(normalizedPath, parent, true);
launcher.OpenRepositoryInTab(node, page); launcher.OpenRepositoryInTab(node, page);
}); });
}); });