diff --git a/README.md b/README.md
index 63bbe45f..22e909bf 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@ Opensource Git GUI client.
* Supports Windows/macOS/Linux
* Opensource/Free
* Fast
-* English/简体中文
+* English/简体中文/繁體中文
* Built-in light/dark themes
* Visual commit graph
* Supports SSH access with each remote
@@ -75,6 +75,7 @@ This app supports open repository in external tools listed in the table below.
> * You can set the given environment variable for special tool if it can NOT be found by this app automatically.
> * Installing `JetBrains Toolbox` will help this app to find other JetBrains tools installed on your device.
+> * On macOS, you may need to use `launchctl setenv` to make sure the app can read these environment variables.
## Screenshots
diff --git a/VERSION b/VERSION
index d9316e8b..b14fccec 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-8.15
\ No newline at end of file
+8.16
\ No newline at end of file
diff --git a/build/resources/app/App.plist b/build/resources/app/App.plist
index 01d93ad7..3ccf7335 100644
--- a/build/resources/app/App.plist
+++ b/build/resources/app/App.plist
@@ -12,6 +12,11 @@
SOURCE_GIT_VERSION.0
LSMinimumSystemVersion
10.12
+ LSEnvironment
+
+ PATH
+ /opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
+
CFBundleExecutable
SourceGit
CFBundleInfoDictionaryVersion
diff --git a/src/App.JsonCodeGen.cs b/src/App.JsonCodeGen.cs
index 7269b252..af2e9913 100644
--- a/src/App.JsonCodeGen.cs
+++ b/src/App.JsonCodeGen.cs
@@ -1,10 +1,12 @@
-using System.Text.Json.Serialization;
+using System.Collections.Generic;
+using System.Text.Json.Serialization;
namespace SourceGit
{
[JsonSourceGenerationOptions(WriteIndented = true, IgnoreReadOnlyFields = true, IgnoreReadOnlyProperties = true)]
[JsonSerializable(typeof(Models.Version))]
[JsonSerializable(typeof(Models.JetBrainsState))]
+ [JsonSerializable(typeof(Dictionary))]
[JsonSerializable(typeof(ViewModels.Preference))]
internal partial class JsonCodeGen : JsonSerializerContext { }
}
diff --git a/src/App.axaml b/src/App.axaml
index fff2ca0d..d73ea45d 100644
--- a/src/App.axaml
+++ b/src/App.axaml
@@ -13,6 +13,7 @@
+
diff --git a/src/App.axaml.cs b/src/App.axaml.cs
index df491dd0..69917120 100644
--- a/src/App.axaml.cs
+++ b/src/App.axaml.cs
@@ -132,32 +132,48 @@ namespace SourceGit
var app = Current as App;
var targetLocale = app.Resources[localeKey] as ResourceDictionary;
if (targetLocale == null || targetLocale == app._activeLocale)
- {
return;
- }
if (app._activeLocale != null)
- {
app.Resources.MergedDictionaries.Remove(app._activeLocale);
- }
app.Resources.MergedDictionaries.Add(targetLocale);
app._activeLocale = targetLocale;
}
- public static void SetTheme(string theme)
+ public static void SetTheme(string theme, string colorsFile)
{
+ var app = Current as App;
+
if (theme.Equals("Light", StringComparison.OrdinalIgnoreCase))
- {
- Current.RequestedThemeVariant = ThemeVariant.Light;
- }
+ app.RequestedThemeVariant = ThemeVariant.Light;
else if (theme.Equals("Dark", StringComparison.OrdinalIgnoreCase))
- {
- Current.RequestedThemeVariant = ThemeVariant.Dark;
- }
+ app.RequestedThemeVariant = ThemeVariant.Dark;
else
+ app.RequestedThemeVariant = ThemeVariant.Default;
+
+ if (app._colorOverrides != null)
{
- Current.RequestedThemeVariant = ThemeVariant.Default;
+ app.Resources.MergedDictionaries.Remove(app._colorOverrides);
+ app._colorOverrides = null;
+ }
+
+ if (!string.IsNullOrEmpty(colorsFile) && File.Exists(colorsFile))
+ {
+ try
+ {
+ var resDic = new ResourceDictionary();
+
+ var schema = JsonSerializer.Deserialize(File.ReadAllText(colorsFile), JsonCodeGen.Default.DictionaryStringString);
+ foreach (var kv in schema)
+ resDic[kv.Key] = Color.Parse(kv.Value);
+
+ app.Resources.MergedDictionaries.Add(resDic);
+ app._colorOverrides = resDic;
+ }
+ catch
+ {
+ }
}
}
@@ -166,9 +182,7 @@ namespace SourceGit
if (Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
if (desktop.MainWindow.Clipboard is { } clipbord)
- {
await clipbord.SetTextAsync(data);
- }
}
}
@@ -256,7 +270,7 @@ namespace SourceGit
var pref = ViewModels.Preference.Instance;
SetLocale(pref.Locale);
- SetTheme(pref.Theme);
+ SetTheme(pref.Theme, pref.ColorOverrides);
}
public override void OnFrameworkInitializationCompleted()
@@ -300,6 +314,7 @@ namespace SourceGit
}
private ResourceDictionary _activeLocale = null;
+ private ResourceDictionary _colorOverrides = null;
private Models.INotificationReceiver _notificationReceiver = null;
}
}
diff --git a/src/Commands/QueryBranches.cs b/src/Commands/QueryBranches.cs
index ed5282f7..9200db4b 100644
--- a/src/Commands/QueryBranches.cs
+++ b/src/Commands/QueryBranches.cs
@@ -52,12 +52,12 @@ namespace SourceGit.Commands
var refName = parts[0];
if (refName.EndsWith("/HEAD", StringComparison.Ordinal))
return;
-
+
if (refName.StartsWith(PREFIX_DETACHED, StringComparison.Ordinal))
{
branch.IsHead = true;
}
-
+
if (refName.StartsWith(PREFIX_LOCAL, StringComparison.Ordinal))
{
branch.Name = refName.Substring(PREFIX_LOCAL.Length);
diff --git a/src/Commands/QueryCommitFullMessage.cs b/src/Commands/QueryCommitFullMessage.cs
new file mode 100644
index 00000000..f4be9bc5
--- /dev/null
+++ b/src/Commands/QueryCommitFullMessage.cs
@@ -0,0 +1,19 @@
+namespace SourceGit.Commands
+{
+ public class QueryCommitFullMessage : Command
+ {
+ public QueryCommitFullMessage(string repo, string sha)
+ {
+ WorkingDirectory = repo;
+ Context = repo;
+ Args = $"show --no-show-signature --pretty=format:%B -s {sha}";
+ }
+
+ public string Result()
+ {
+ var rs = ReadToEnd();
+ if (rs.IsSuccess) return rs.StdOut.TrimEnd();
+ return string.Empty;
+ }
+ }
+}
diff --git a/src/Commands/QueryCommits.cs b/src/Commands/QueryCommits.cs
index 6788884c..075d6467 100644
--- a/src/Commands/QueryCommits.cs
+++ b/src/Commands/QueryCommits.cs
@@ -5,133 +5,101 @@ namespace SourceGit.Commands
{
public class QueryCommits : Command
{
- private const string GPGSIG_START = "gpgsig -----BEGIN ";
- private const string GPGSIG_END = " -----END ";
-
- private readonly List commits = new List();
- private Models.Commit current = null;
- private bool isSkipingGpgsig = false;
- private bool isHeadFounded = false;
- private readonly bool findFirstMerged = true;
-
public QueryCommits(string repo, string limits, bool needFindHead = true)
{
WorkingDirectory = repo;
Context = repo;
- Args = "log --date-order --decorate=full --pretty=raw " + limits;
- findFirstMerged = needFindHead;
+ Args = $"log --date-order --no-show-signature --decorate=full --pretty=format:%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%s " + limits;
+ _findFirstMerged = needFindHead;
}
public List Result()
{
- Exec();
+ var rs = ReadToEnd();
+ if (!rs.IsSuccess)
+ return _commits;
- if (current != null)
+ var nextPartIdx = 0;
+ var start = 0;
+ var end = rs.StdOut.IndexOf('\n', start);
+ while (end > 0)
{
- current.Message = current.Message.Trim();
- commits.Add(current);
+ var line = rs.StdOut.Substring(start, end - start);
+ switch (nextPartIdx)
+ {
+ case 0:
+ _current = new Models.Commit() { SHA = line };
+ _commits.Add(_current);
+ break;
+ case 1:
+ ParseParent(line);
+ break;
+ case 2:
+ ParseDecorators(line);
+ break;
+ case 3:
+ _current.Author = Models.User.FindOrAdd(line);
+ break;
+ case 4:
+ _current.AuthorTime = ulong.Parse(line);
+ break;
+ case 5:
+ _current.Committer = Models.User.FindOrAdd(line);
+ break;
+ case 6:
+ _current.CommitterTime = ulong.Parse(line);
+ break;
+ case 7:
+ _current.Subject = line;
+ nextPartIdx = -1;
+ break;
+ default:
+ break;
+ }
+
+ nextPartIdx++;
+
+ start = end + 1;
+ end = rs.StdOut.IndexOf('\n', start);
}
- if (findFirstMerged && !isHeadFounded && commits.Count > 0)
- {
+ if (_findFirstMerged && !_isHeadFounded && _commits.Count > 0)
MarkFirstMerged();
- }
- return commits;
+ return _commits;
}
- protected override void OnReadline(string line)
+ private void ParseParent(string data)
{
- if (isSkipingGpgsig)
- {
- if (line.StartsWith(GPGSIG_END, StringComparison.Ordinal))
- isSkipingGpgsig = false;
+ if (data.Length < 8)
return;
- }
- else if (line.StartsWith(GPGSIG_START, StringComparison.Ordinal))
+
+ var idx = data.IndexOf(' ', StringComparison.Ordinal);
+ if (idx == -1)
{
- isSkipingGpgsig = true;
+ _current.Parents.Add(data);
return;
}
- if (line.StartsWith("commit ", StringComparison.Ordinal))
- {
- if (current != null)
- {
- current.Message = current.Message.Trim();
- commits.Add(current);
- }
-
- current = new Models.Commit();
- line = line.Substring(7);
-
- var decoratorStart = line.IndexOf('(', StringComparison.Ordinal);
- if (decoratorStart < 0)
- {
- current.SHA = line.Trim();
- }
- else
- {
- current.SHA = line.Substring(0, decoratorStart).Trim();
- current.IsMerged = ParseDecorators(current.Decorators, line.Substring(decoratorStart + 1));
- if (!isHeadFounded)
- isHeadFounded = current.IsMerged;
- }
-
- return;
- }
-
- if (current == null)
- return;
-
- if (line.StartsWith("tree ", StringComparison.Ordinal))
- {
- return;
- }
- else if (line.StartsWith("parent ", StringComparison.Ordinal))
- {
- current.Parents.Add(line.Substring("parent ".Length));
- }
- else if (line.StartsWith("author ", StringComparison.Ordinal))
- {
- Models.User user = Models.User.Invalid;
- ulong time = 0;
- Models.Commit.ParseUserAndTime(line.Substring(7), ref user, ref time);
- current.Author = user;
- current.AuthorTime = time;
- }
- else if (line.StartsWith("committer ", StringComparison.Ordinal))
- {
- Models.User user = Models.User.Invalid;
- ulong time = 0;
- Models.Commit.ParseUserAndTime(line.Substring(10), ref user, ref time);
- current.Committer = user;
- current.CommitterTime = time;
- }
- else if (string.IsNullOrEmpty(current.Subject))
- {
- current.Subject = line.Trim();
- }
- else
- {
- current.Message += (line.Trim() + "\n");
- }
+ _current.Parents.Add(data.Substring(0, idx));
+ _current.Parents.Add(data.Substring(idx + 1));
}
- private bool ParseDecorators(List decorators, string data)
+ private void ParseDecorators(string data)
{
- bool isHeadOfCurrent = false;
+ if (data.Length < 3)
+ return;
- var subs = data.Split(new char[] { ',', ')', '(' }, StringSplitOptions.RemoveEmptyEntries);
+ var subs = data.Split(',', StringSplitOptions.RemoveEmptyEntries);
foreach (var sub in subs)
{
var d = sub.Trim();
if (d.StartsWith("tag: refs/tags/", StringComparison.Ordinal))
{
- decorators.Add(new Models.Decorator()
+ _current.Decorators.Add(new Models.Decorator()
{
Type = Models.DecoratorType.Tag,
- Name = d.Substring(15).Trim(),
+ Name = d.Substring(15),
});
}
else if (d.EndsWith("/HEAD", StringComparison.Ordinal))
@@ -140,58 +108,55 @@ namespace SourceGit.Commands
}
else if (d.StartsWith("HEAD -> refs/heads/", StringComparison.Ordinal))
{
- isHeadOfCurrent = true;
- decorators.Add(new Models.Decorator()
+ _current.IsMerged = true;
+ _current.Decorators.Add(new Models.Decorator()
{
Type = Models.DecoratorType.CurrentBranchHead,
- Name = d.Substring(19).Trim(),
+ Name = d.Substring(19),
});
}
else if (d.Equals("HEAD"))
{
- isHeadOfCurrent = true;
- decorators.Add(new Models.Decorator()
+ _current.IsMerged = true;
+ _current.Decorators.Add(new Models.Decorator()
{
Type = Models.DecoratorType.CurrentCommitHead,
- Name = d.Trim(),
+ Name = d,
});
}
else if (d.StartsWith("refs/heads/", StringComparison.Ordinal))
{
- decorators.Add(new Models.Decorator()
+ _current.Decorators.Add(new Models.Decorator()
{
Type = Models.DecoratorType.LocalBranchHead,
- Name = d.Substring(11).Trim(),
+ Name = d.Substring(11),
});
}
else if (d.StartsWith("refs/remotes/", StringComparison.Ordinal))
{
- decorators.Add(new Models.Decorator()
+ _current.Decorators.Add(new Models.Decorator()
{
Type = Models.DecoratorType.RemoteBranchHead,
- Name = d.Substring(13).Trim(),
+ Name = d.Substring(13),
});
}
}
- decorators.Sort((l, r) =>
+ _current.Decorators.Sort((l, r) =>
{
if (l.Type != r.Type)
- {
return (int)l.Type - (int)r.Type;
- }
else
- {
- return l.Name.CompareTo(r.Name);
- }
+ return string.Compare(l.Name, r.Name, StringComparison.Ordinal);
});
- return isHeadOfCurrent;
+ if (_current.IsMerged && !_isHeadFounded)
+ _isHeadFounded = true;
}
private void MarkFirstMerged()
{
- Args = $"log --since=\"{commits[commits.Count - 1].CommitterTimeStr}\" --format=\"%H\"";
+ Args = $"log --since=\"{_commits[_commits.Count - 1].CommitterTimeStr}\" --format=\"%H\"";
var rs = ReadToEnd();
var shas = rs.StdOut.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
@@ -202,7 +167,7 @@ namespace SourceGit.Commands
foreach (var sha in shas)
set.Add(sha);
- foreach (var c in commits)
+ foreach (var c in _commits)
{
if (set.Contains(c.SHA))
{
@@ -211,5 +176,10 @@ namespace SourceGit.Commands
}
}
}
+
+ private List _commits = new List();
+ private Models.Commit _current = null;
+ private bool _findFirstMerged = false;
+ private bool _isHeadFounded = false;
}
}
diff --git a/src/Commands/QueryRevisionObjects.cs b/src/Commands/QueryRevisionObjects.cs
index 7a3db057..bcad9129 100644
--- a/src/Commands/QueryRevisionObjects.cs
+++ b/src/Commands/QueryRevisionObjects.cs
@@ -5,22 +5,23 @@ namespace SourceGit.Commands
{
public partial class QueryRevisionObjects : Command
{
-
[GeneratedRegex(@"^\d+\s+(\w+)\s+([0-9a-f]+)\s+(.*)$")]
private static partial Regex REG_FORMAT();
- private readonly List objects = new List();
- public QueryRevisionObjects(string repo, string sha)
+ public QueryRevisionObjects(string repo, string sha, string parentFolder)
{
WorkingDirectory = repo;
Context = repo;
- Args = $"ls-tree -r {sha}";
+ Args = $"ls-tree {sha}";
+
+ if (!string.IsNullOrEmpty(parentFolder))
+ Args += $" -- \"{parentFolder}\"";
}
public List Result()
{
Exec();
- return objects;
+ return _objects;
}
protected override void OnReadline(string line)
@@ -50,7 +51,9 @@ namespace SourceGit.Commands
break;
}
- objects.Add(obj);
+ _objects.Add(obj);
}
+
+ private List _objects = new List();
}
}
diff --git a/src/Commands/QuerySingleCommit.cs b/src/Commands/QuerySingleCommit.cs
index 5c0fd760..4a553817 100644
--- a/src/Commands/QuerySingleCommit.cs
+++ b/src/Commands/QuerySingleCommit.cs
@@ -1,100 +1,50 @@
using System;
using System.Collections.Generic;
+using System.Text;
namespace SourceGit.Commands
{
public class QuerySingleCommit : Command
{
- private const string GPGSIG_START = "gpgsig -----BEGIN PGP SIGNATURE-----";
- private const string GPGSIG_END = " -----END PGP SIGNATURE-----";
-
- public QuerySingleCommit(string repo, string sha) {
+ public QuerySingleCommit(string repo, string sha)
+ {
WorkingDirectory = repo;
Context = repo;
- Args = $"show --pretty=raw --decorate=full -s {sha}";
+ Args = $"show --no-show-signature --decorate=full --pretty=format:%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%s -s {sha}";
}
public Models.Commit Result()
{
- var succ = Exec();
- if (!succ)
- return null;
-
- _commit.Message.Trim();
- return _commit;
- }
-
- protected override void OnReadline(string line)
- {
- if (isSkipingGpgsig)
+ var rs = ReadToEnd();
+ if (rs.IsSuccess && !string.IsNullOrEmpty(rs.StdOut))
{
- if (line.StartsWith(GPGSIG_END, StringComparison.Ordinal))
- isSkipingGpgsig = false;
- return;
- }
- else if (line.StartsWith(GPGSIG_START, StringComparison.Ordinal))
- {
- isSkipingGpgsig = true;
- return;
+ var commit = new Models.Commit();
+ var lines = rs.StdOut.Split('\n');
+ if (lines.Length < 8)
+ return null;
+
+ commit.SHA = lines[0];
+ if (!string.IsNullOrEmpty(lines[1]))
+ commit.Parents.AddRange(lines[1].Split(' ', StringSplitOptions.RemoveEmptyEntries));
+ if (!string.IsNullOrEmpty(lines[2]))
+ commit.IsMerged = ParseDecorators(commit.Decorators, lines[2]);
+ commit.Author = Models.User.FindOrAdd(lines[3]);
+ commit.AuthorTime = ulong.Parse(lines[4]);
+ commit.Committer = Models.User.FindOrAdd(lines[5]);
+ commit.CommitterTime = ulong.Parse(lines[6]);
+ commit.Subject = lines[7];
+
+ return commit;
}
- if (line.StartsWith("commit ", StringComparison.Ordinal))
- {
- line = line.Substring(7);
-
- var decoratorStart = line.IndexOf('(', StringComparison.Ordinal);
- if (decoratorStart < 0)
- {
- _commit.SHA = line.Trim();
- }
- else
- {
- _commit.SHA = line.Substring(0, decoratorStart).Trim();
- ParseDecorators(_commit.Decorators, line.Substring(decoratorStart + 1));
- }
-
- return;
- }
-
- if (line.StartsWith("tree ", StringComparison.Ordinal))
- {
- return;
- }
- else if (line.StartsWith("parent ", StringComparison.Ordinal))
- {
- _commit.Parents.Add(line.Substring("parent ".Length));
- }
- else if (line.StartsWith("author ", StringComparison.Ordinal))
- {
- Models.User user = Models.User.Invalid;
- ulong time = 0;
- Models.Commit.ParseUserAndTime(line.Substring(7), ref user, ref time);
- _commit.Author = user;
- _commit.AuthorTime = time;
- }
- else if (line.StartsWith("committer ", StringComparison.Ordinal))
- {
- Models.User user = Models.User.Invalid;
- ulong time = 0;
- Models.Commit.ParseUserAndTime(line.Substring(10), ref user, ref time);
- _commit.Committer = user;
- _commit.CommitterTime = time;
- }
- else if (string.IsNullOrEmpty(_commit.Subject))
- {
- _commit.Subject = line.Trim();
- }
- else
- {
- _commit.Message += (line.Trim() + "\n");
- }
+ return null;
}
private bool ParseDecorators(List decorators, string data)
{
bool isHeadOfCurrent = false;
- var subs = data.Split(new char[] { ',', ')', '(' }, StringSplitOptions.RemoveEmptyEntries);
+ var subs = data.Split(',', StringSplitOptions.RemoveEmptyEntries);
foreach (var sub in subs)
{
var d = sub.Trim();
@@ -103,7 +53,7 @@ namespace SourceGit.Commands
decorators.Add(new Models.Decorator()
{
Type = Models.DecoratorType.Tag,
- Name = d.Substring(15).Trim(),
+ Name = d.Substring(15),
});
}
else if (d.EndsWith("/HEAD", StringComparison.Ordinal))
@@ -116,7 +66,7 @@ namespace SourceGit.Commands
decorators.Add(new Models.Decorator()
{
Type = Models.DecoratorType.CurrentBranchHead,
- Name = d.Substring(19).Trim(),
+ Name = d.Substring(19),
});
}
else if (d.Equals("HEAD"))
@@ -125,7 +75,7 @@ namespace SourceGit.Commands
decorators.Add(new Models.Decorator()
{
Type = Models.DecoratorType.CurrentCommitHead,
- Name = d.Trim(),
+ Name = d,
});
}
else if (d.StartsWith("refs/heads/", StringComparison.Ordinal))
@@ -133,7 +83,7 @@ namespace SourceGit.Commands
decorators.Add(new Models.Decorator()
{
Type = Models.DecoratorType.LocalBranchHead,
- Name = d.Substring(11).Trim(),
+ Name = d.Substring(11),
});
}
else if (d.StartsWith("refs/remotes/", StringComparison.Ordinal))
@@ -141,7 +91,7 @@ namespace SourceGit.Commands
decorators.Add(new Models.Decorator()
{
Type = Models.DecoratorType.RemoteBranchHead,
- Name = d.Substring(13).Trim(),
+ Name = d.Substring(13),
});
}
}
@@ -149,19 +99,12 @@ namespace SourceGit.Commands
decorators.Sort((l, r) =>
{
if (l.Type != r.Type)
- {
return (int)l.Type - (int)r.Type;
- }
else
- {
- return l.Name.CompareTo(r.Name);
- }
+ return string.Compare(l.Name, r.Name, StringComparison.Ordinal);
});
return isHeadOfCurrent;
}
-
- private Models.Commit _commit = new Models.Commit();
- private bool isSkipingGpgsig = false;
}
}
diff --git a/src/Commands/QueryStashes.cs b/src/Commands/QueryStashes.cs
index 5362f87b..6d089f8e 100644
--- a/src/Commands/QueryStashes.cs
+++ b/src/Commands/QueryStashes.cs
@@ -1,64 +1,48 @@
-using System;
-using System.Collections.Generic;
-using System.Text.RegularExpressions;
+using System.Collections.Generic;
namespace SourceGit.Commands
{
- public partial class QueryStashes : Command
+ public class QueryStashes : Command
{
-
- [GeneratedRegex(@"^Reflog: refs/(stash@\{\d+\}).*$")]
- private static partial Regex REG_STASH();
-
public QueryStashes(string repo)
{
WorkingDirectory = repo;
Context = repo;
- Args = "stash list --pretty=raw";
+ Args = "stash list --pretty=format:%H%n%ct%n%gd%n%s";
}
public List Result()
{
Exec();
- if (_current != null)
- _stashes.Add(_current);
return _stashes;
}
protected override void OnReadline(string line)
{
- if (line.StartsWith("commit ", StringComparison.Ordinal))
+ switch (_nextLineIdx)
{
- if (_current != null && !string.IsNullOrEmpty(_current.Name))
+ case 0:
+ _current = new Models.Stash() { SHA = line };
_stashes.Add(_current);
- _current = new Models.Stash() { SHA = line.Substring(7, 8) };
- return;
+ break;
+ case 1:
+ _current.Time = ulong.Parse(line);
+ break;
+ case 2:
+ _current.Name = line;
+ break;
+ case 3:
+ _current.Message = line;
+ break;
}
- if (_current == null)
- return;
-
- if (line.StartsWith("Reflog: refs/stash@", StringComparison.Ordinal))
- {
- var match = REG_STASH().Match(line);
- if (match.Success)
- _current.Name = match.Groups[1].Value;
- }
- else if (line.StartsWith("Reflog message: ", StringComparison.Ordinal))
- {
- _current.Message = line.Substring(16);
- }
- else if (line.StartsWith("author ", StringComparison.Ordinal))
- {
- Models.User user = Models.User.Invalid;
- ulong time = 0;
- Models.Commit.ParseUserAndTime(line.Substring(7), ref user, ref time);
- _current.Author = user;
- _current.Time = time;
- }
+ _nextLineIdx++;
+ if (_nextLineIdx > 3)
+ _nextLineIdx = 0;
}
private readonly List _stashes = new List();
private Models.Stash _current = null;
+ private int _nextLineIdx = 0;
}
}
diff --git a/src/Commands/Submodule.cs b/src/Commands/Submodule.cs
index 428c10d1..3c4460ea 100644
--- a/src/Commands/Submodule.cs
+++ b/src/Commands/Submodule.cs
@@ -29,9 +29,10 @@ namespace SourceGit.Commands
}
}
- public bool Update()
+ public bool Update(Action outputHandler)
{
Args = $"submodule update --rebase --remote";
+ _outputHandler = outputHandler;
return Exec();
}
diff --git a/src/Converters/ChangeViewModeConverters.cs b/src/Converters/ChangeViewModeConverters.cs
index 01bc1774..a5b07bca 100644
--- a/src/Converters/ChangeViewModeConverters.cs
+++ b/src/Converters/ChangeViewModeConverters.cs
@@ -19,14 +19,5 @@ namespace SourceGit.Converters
return App.Current?.FindResource("Icons.Tree") as StreamGeometry;
}
});
-
- public static readonly FuncValueConverter IsList =
- new FuncValueConverter(v => v == Models.ChangeViewMode.List);
-
- public static readonly FuncValueConverter IsGrid =
- new FuncValueConverter(v => v == Models.ChangeViewMode.Grid);
-
- public static readonly FuncValueConverter IsTree =
- new FuncValueConverter(v => v == Models.ChangeViewMode.Tree);
}
}
diff --git a/src/Converters/DecoratorTypeConverters.cs b/src/Converters/DecoratorTypeConverters.cs
index 9f3d9447..e19cb37c 100644
--- a/src/Converters/DecoratorTypeConverters.cs
+++ b/src/Converters/DecoratorTypeConverters.cs
@@ -38,8 +38,8 @@ namespace SourceGit.Converters
});
public static readonly FuncValueConverter ToFontWeight =
- new FuncValueConverter(v =>
- v is Models.DecoratorType.CurrentBranchHead or Models.DecoratorType.CurrentCommitHead
+ new FuncValueConverter(v =>
+ v is Models.DecoratorType.CurrentBranchHead or Models.DecoratorType.CurrentCommitHead
? FontWeight.Bold : FontWeight.Regular
);
}
diff --git a/src/Converters/LauncherPageConverters.cs b/src/Converters/LauncherPageConverters.cs
deleted file mode 100644
index 05eec2b1..00000000
--- a/src/Converters/LauncherPageConverters.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using System.Collections.Generic;
-
-using Avalonia.Collections;
-using Avalonia.Data.Converters;
-
-namespace SourceGit.Converters
-{
- public static class LauncherPageConverters
- {
- public static readonly FuncMultiValueConverter