diff --git a/src/Commands/Fetch.cs b/src/Commands/Fetch.cs index ad36051f..968ff1ca 100644 --- a/src/Commands/Fetch.cs +++ b/src/Commands/Fetch.cs @@ -1,4 +1,7 @@ using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; namespace SourceGit.Commands { public class Fetch : Command { @@ -18,6 +21,8 @@ namespace SourceGit.Commands { Args += "fetch --progress --verbose "; if (prune) Args += "--prune "; Args += remote; + + AutoFetch.MarkFetched(repo); } public Fetch(string repo, string remote, string localBranch, string remoteBranch, Action outputHandler) { @@ -42,4 +47,75 @@ namespace SourceGit.Commands { private Action _outputHandler; } + + public class AutoFetch { + public static bool IsEnabled { + get; + set; + } = false; + + class Job { + public Fetch Cmd = null; + public DateTime NextRunTimepoint = DateTime.MinValue; + } + + static AutoFetch() { + Task.Run(() => { + while (true) { + if (!IsEnabled) { + Thread.Sleep(10000); + continue; + } + + var now = DateTime.Now; + var uptodate = new List(); + lock (_lock) { + foreach (var job in _jobs) { + if (job.Value.NextRunTimepoint.Subtract(now).TotalSeconds <= 0) { + uptodate.Add(job.Value); + } + } + } + + foreach (var job in uptodate) { + job.Cmd.Exec(); + job.NextRunTimepoint = DateTime.Now.AddSeconds(_fetchInterval); + } + } + }); + } + + public static void AddRepository(string repo) { + var job = new Job { + Cmd = new Fetch(repo, "--all", true, null) { RaiseError = false }, + NextRunTimepoint = DateTime.Now.AddSeconds(_fetchInterval), + }; + + lock (_lock) { + if (_jobs.ContainsKey(repo)) { + _jobs[repo] = job; + } else { + _jobs.Add(repo, job); + } + } + } + + public static void RemoveRepository(string repo) { + lock (_lock) { + _jobs.Remove(repo); + } + } + + public static void MarkFetched(string repo) { + lock (_lock) { + if (_jobs.ContainsKey(repo)) { + _jobs[repo].NextRunTimepoint = DateTime.Now.AddSeconds(_fetchInterval); + } + } + } + + private static Dictionary _jobs = new Dictionary(); + private static object _lock = new object(); + private static double _fetchInterval = 10 * 60; + } } diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 93284e36..0f6ce087 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -393,7 +393,7 @@ User Email Global git user email Enable Auto CRLF - Fetch remotes automatically (need restart) + Fetch remotes automatically GPG SIGNING Commit GPG signing Install Path diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index 2ec13519..674de31d 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -392,7 +392,7 @@ 邮箱 默认GIT用户邮箱 自动换行转换 - 启用定时自动拉取远程更新(重启生效) + 启用定时自动拉取远程更新 GPG签名 启用提交签名 可执行文件位置 diff --git a/src/ViewModels/Launcher.cs b/src/ViewModels/Launcher.cs index d8754f73..38d684d4 100644 --- a/src/ViewModels/Launcher.cs +++ b/src/ViewModels/Launcher.cs @@ -123,6 +123,7 @@ namespace SourceGit.ViewModels { } repo.Open(); + Commands.AutoFetch.AddRepository(repo.FullPath); if (page == null) { if (ActivePage == null || ActivePage.Node.IsRepository) { @@ -146,6 +147,7 @@ namespace SourceGit.ViewModels { var repo = Preference.FindRepository(page.Node.Id); if (repo == null) return; + Commands.AutoFetch.RemoveRepository(repo.FullPath); repo.Close(); } diff --git a/src/ViewModels/Preference.cs b/src/ViewModels/Preference.cs index 03951664..0dcf20a9 100644 --- a/src/ViewModels/Preference.cs +++ b/src/ViewModels/Preference.cs @@ -112,8 +112,13 @@ namespace SourceGit.ViewModels { } public bool GitAutoFetch { - get => _gitAutoFetch; - set => SetProperty(ref _gitAutoFetch, value); + get => Commands.AutoFetch.IsEnabled; + set { + if (Commands.AutoFetch.IsEnabled != value) { + Commands.AutoFetch.IsEnabled = value; + OnPropertyChanged(nameof(GitAutoFetch)); + } + } } public int ExternalMergeToolType { @@ -242,7 +247,6 @@ namespace SourceGit.ViewModels { private Models.ChangeViewMode _commitChangeViewMode = Models.ChangeViewMode.List; private string _gitDefaultCloneDir = string.Empty; - private bool _gitAutoFetch = false; private int _externalMergeToolType = 0; private string _externalMergeToolPath = string.Empty; diff --git a/src/Views/CommitBaseInfo.axaml b/src/Views/CommitBaseInfo.axaml index 98ed1252..17c66f4c 100644 --- a/src/Views/CommitBaseInfo.axaml +++ b/src/Views/CommitBaseInfo.axaml @@ -103,7 +103,7 @@ - +