Skip to content

Commit d8fe0e2

Browse files
committed
Merge branch 'release/v8.15'
2 parents 8c23cf7 + 9d46a9a commit d8fe0e2

File tree

85 files changed

+2693
-1905
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

85 files changed

+2693
-1905
lines changed

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
8.14
1+
8.15

src/App.axaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
<Application.Styles>
2020
<FluentTheme />
2121
<StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml"/>
22+
<StyleInclude Source="avares://Avalonia.Controls.TreeDataGrid/Themes/Fluent.axaml"/>
2223
<StyleInclude Source="avares://AvaloniaEdit/Themes/Fluent/AvaloniaEdit.xaml" />
2324
<StyleInclude Source="/Resources/Styles.axaml"/>
2425
</Application.Styles>

src/App.axaml.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,7 @@ public static void Main(string[] args)
6262
builder.Append(ex.StackTrace);
6363

6464
var time = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss");
65-
var file = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
66-
"SourceGit",
67-
$"crash_{time}.log");
65+
var file = Path.Combine(Native.OS.DataDir, $"crash_{time}.log");
6866
File.WriteAllText(file, builder.ToString());
6967
}
7068
}

src/Commands/QueryCommits.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ namespace SourceGit.Commands
55
{
66
public class QueryCommits : Command
77
{
8-
private const string GPGSIG_START = "gpgsig -----BEGIN PGP SIGNATURE-----";
9-
private const string GPGSIG_END = " -----END PGP SIGNATURE-----";
8+
private const string GPGSIG_START = "gpgsig -----BEGIN ";
9+
private const string GPGSIG_END = " -----END ";
1010

1111
private readonly List<Models.Commit> commits = new List<Models.Commit>();
1212
private Models.Commit current = null;
@@ -17,6 +17,7 @@ public class QueryCommits : Command
1717
public QueryCommits(string repo, string limits, bool needFindHead = true)
1818
{
1919
WorkingDirectory = repo;
20+
Context = repo;
2021
Args = "log --date-order --decorate=full --pretty=raw " + limits;
2122
findFirstMerged = needFindHead;
2223
}

src/Commands/QuerySingleCommit.cs

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace SourceGit.Commands
5+
{
6+
public class QuerySingleCommit : Command
7+
{
8+
private const string GPGSIG_START = "gpgsig -----BEGIN PGP SIGNATURE-----";
9+
private const string GPGSIG_END = " -----END PGP SIGNATURE-----";
10+
11+
public QuerySingleCommit(string repo, string sha) {
12+
WorkingDirectory = repo;
13+
Context = repo;
14+
Args = $"show --pretty=raw --decorate=full -s {sha}";
15+
}
16+
17+
public Models.Commit Result()
18+
{
19+
var succ = Exec();
20+
if (!succ)
21+
return null;
22+
23+
_commit.Message.Trim();
24+
return _commit;
25+
}
26+
27+
protected override void OnReadline(string line)
28+
{
29+
if (isSkipingGpgsig)
30+
{
31+
if (line.StartsWith(GPGSIG_END, StringComparison.Ordinal))
32+
isSkipingGpgsig = false;
33+
return;
34+
}
35+
else if (line.StartsWith(GPGSIG_START, StringComparison.Ordinal))
36+
{
37+
isSkipingGpgsig = true;
38+
return;
39+
}
40+
41+
if (line.StartsWith("commit ", StringComparison.Ordinal))
42+
{
43+
line = line.Substring(7);
44+
45+
var decoratorStart = line.IndexOf('(', StringComparison.Ordinal);
46+
if (decoratorStart < 0)
47+
{
48+
_commit.SHA = line.Trim();
49+
}
50+
else
51+
{
52+
_commit.SHA = line.Substring(0, decoratorStart).Trim();
53+
ParseDecorators(_commit.Decorators, line.Substring(decoratorStart + 1));
54+
}
55+
56+
return;
57+
}
58+
59+
if (line.StartsWith("tree ", StringComparison.Ordinal))
60+
{
61+
return;
62+
}
63+
else if (line.StartsWith("parent ", StringComparison.Ordinal))
64+
{
65+
_commit.Parents.Add(line.Substring("parent ".Length));
66+
}
67+
else if (line.StartsWith("author ", StringComparison.Ordinal))
68+
{
69+
Models.User user = Models.User.Invalid;
70+
ulong time = 0;
71+
Models.Commit.ParseUserAndTime(line.Substring(7), ref user, ref time);
72+
_commit.Author = user;
73+
_commit.AuthorTime = time;
74+
}
75+
else if (line.StartsWith("committer ", StringComparison.Ordinal))
76+
{
77+
Models.User user = Models.User.Invalid;
78+
ulong time = 0;
79+
Models.Commit.ParseUserAndTime(line.Substring(10), ref user, ref time);
80+
_commit.Committer = user;
81+
_commit.CommitterTime = time;
82+
}
83+
else if (string.IsNullOrEmpty(_commit.Subject))
84+
{
85+
_commit.Subject = line.Trim();
86+
}
87+
else
88+
{
89+
_commit.Message += (line.Trim() + "\n");
90+
}
91+
}
92+
93+
private bool ParseDecorators(List<Models.Decorator> decorators, string data)
94+
{
95+
bool isHeadOfCurrent = false;
96+
97+
var subs = data.Split(new char[] { ',', ')', '(' }, StringSplitOptions.RemoveEmptyEntries);
98+
foreach (var sub in subs)
99+
{
100+
var d = sub.Trim();
101+
if (d.StartsWith("tag: refs/tags/", StringComparison.Ordinal))
102+
{
103+
decorators.Add(new Models.Decorator()
104+
{
105+
Type = Models.DecoratorType.Tag,
106+
Name = d.Substring(15).Trim(),
107+
});
108+
}
109+
else if (d.EndsWith("/HEAD", StringComparison.Ordinal))
110+
{
111+
continue;
112+
}
113+
else if (d.StartsWith("HEAD -> refs/heads/", StringComparison.Ordinal))
114+
{
115+
isHeadOfCurrent = true;
116+
decorators.Add(new Models.Decorator()
117+
{
118+
Type = Models.DecoratorType.CurrentBranchHead,
119+
Name = d.Substring(19).Trim(),
120+
});
121+
}
122+
else if (d.Equals("HEAD"))
123+
{
124+
isHeadOfCurrent = true;
125+
decorators.Add(new Models.Decorator()
126+
{
127+
Type = Models.DecoratorType.CurrentCommitHead,
128+
Name = d.Trim(),
129+
});
130+
}
131+
else if (d.StartsWith("refs/heads/", StringComparison.Ordinal))
132+
{
133+
decorators.Add(new Models.Decorator()
134+
{
135+
Type = Models.DecoratorType.LocalBranchHead,
136+
Name = d.Substring(11).Trim(),
137+
});
138+
}
139+
else if (d.StartsWith("refs/remotes/", StringComparison.Ordinal))
140+
{
141+
decorators.Add(new Models.Decorator()
142+
{
143+
Type = Models.DecoratorType.RemoteBranchHead,
144+
Name = d.Substring(13).Trim(),
145+
});
146+
}
147+
}
148+
149+
decorators.Sort((l, r) =>
150+
{
151+
if (l.Type != r.Type)
152+
{
153+
return (int)l.Type - (int)r.Type;
154+
}
155+
else
156+
{
157+
return l.Name.CompareTo(r.Name);
158+
}
159+
});
160+
161+
return isHeadOfCurrent;
162+
}
163+
164+
private Models.Commit _commit = new Models.Commit();
165+
private bool isSkipingGpgsig = false;
166+
}
167+
}

src/Converters/BoolConverters.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
1-
using Avalonia.Controls;
2-
using Avalonia.Data.Converters;
1+
using Avalonia.Data.Converters;
32
using Avalonia.Media;
43

54
namespace SourceGit.Converters
65
{
76
public static class BoolConverters
87
{
8+
public static readonly FuncValueConverter<bool, double> ToPageTabWidth =
9+
new FuncValueConverter<bool, double>(x => x ? 200 : double.NaN);
10+
911
public static readonly FuncValueConverter<bool, double> HalfIfFalse =
1012
new FuncValueConverter<bool, double>(x => x ? 1 : 0.5);
1113

1214
public static readonly FuncValueConverter<bool, FontWeight> BoldIfTrue =
1315
new FuncValueConverter<bool, FontWeight>(x => x ? FontWeight.Bold : FontWeight.Regular);
14-
15-
public static readonly FuncValueConverter<bool, GridLength> ToStarOrAutoGridLength =
16-
new(value => value ? new GridLength(1, GridUnitType.Star) : new GridLength(1, GridUnitType.Auto));
1716
}
1817
}

src/Converters/StringConverters.cs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
using System;
22
using System.Globalization;
3+
using System.Text.RegularExpressions;
34

45
using Avalonia.Data.Converters;
56
using Avalonia.Styling;
67

78
namespace SourceGit.Converters
89
{
9-
public static class StringConverters
10+
public static partial class StringConverters
1011
{
1112
public class ToLocaleConverter : IValueConverter
1213
{
@@ -68,6 +69,27 @@ public object ConvertBack(object value, Type targetType, object parameter, Cultu
6869
public static readonly FormatByResourceKeyConverter FormatByResourceKey = new FormatByResourceKeyConverter();
6970

7071
public static readonly FuncValueConverter<string, string> ToShortSHA =
71-
new FuncValueConverter<string, string>(v => v.Length > 10 ? v.Substring(0, 10) : v);
72+
new FuncValueConverter<string, string>(v => v == null ? string.Empty : (v.Length > 10 ? v.Substring(0, 10) : v));
73+
74+
public static readonly FuncValueConverter<string, bool> UnderRecommendGitVersion =
75+
new(v =>
76+
{
77+
var match = REG_GIT_VERSION().Match(v ?? "");
78+
if (match.Success)
79+
{
80+
var major = int.Parse(match.Groups[1].Value);
81+
var minor = int.Parse(match.Groups[2].Value);
82+
var build = int.Parse(match.Groups[3].Value);
83+
84+
return new Version(major, minor, build) < MINIMAL_GIT_VERSION;
85+
}
86+
87+
return true;
88+
});
89+
90+
[GeneratedRegex(@"^[\s\w]*(\d+)\.(\d+)[\.\-](\d+).*$")]
91+
private static partial Regex REG_GIT_VERSION();
92+
93+
private static readonly Version MINIMAL_GIT_VERSION = new Version(2, 23, 0);
7294
}
7395
}

src/Converters/WindowStateConverters.cs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
using Avalonia;
44
using Avalonia.Controls;
55
using Avalonia.Data.Converters;
6-
using Avalonia.Media;
76

87
namespace SourceGit.Converters
98
{
@@ -39,19 +38,6 @@ public static class WindowStateConverters
3938
}
4039
});
4140

42-
public static readonly FuncValueConverter<WindowState, StreamGeometry> ToMaxOrRestoreIcon =
43-
new FuncValueConverter<WindowState, StreamGeometry>(state =>
44-
{
45-
if (state == WindowState.Maximized)
46-
{
47-
return Application.Current?.FindResource("Icons.Window.Restore") as StreamGeometry;
48-
}
49-
else
50-
{
51-
return Application.Current?.FindResource("Icons.Window.Maximize") as StreamGeometry;
52-
}
53-
});
54-
5541
public static readonly FuncValueConverter<WindowState, bool> IsNormal =
5642
new FuncValueConverter<WindowState, bool>(state => state == WindowState.Normal);
5743
}

src/Models/AvatarManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public static string SelectedServer
2525

2626
static AvatarManager()
2727
{
28-
_storePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "SourceGit", "avatars");
28+
_storePath = Path.Combine(Native.OS.DataDir, "avatars");
2929
if (!Directory.Exists(_storePath))
3030
Directory.CreateDirectory(_storePath);
3131

src/Models/DealWithLocalChanges.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace SourceGit.Models
2+
{
3+
public enum DealWithLocalChanges
4+
{
5+
StashAndReaply,
6+
Discard,
7+
DoNothing,
8+
}
9+
}

0 commit comments

Comments
 (0)