Skip to content

Commit 5a1827f

Browse files
committed
Merge branch 'release/v8.17'
2 parents e7c52d0 + 10fc231 commit 5a1827f

Some content is hidden

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

73 files changed

+2045
-1520
lines changed

README.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Opensource Git GUI client.
99
* Fast
1010
* English/简体中文/繁體中文
1111
* Built-in light/dark themes
12+
* Customize theme
1213
* Visual commit graph
1314
* Supports SSH access with each remote
1415
* GIT commands with GUI
@@ -24,6 +25,8 @@ Opensource Git GUI client.
2425
* File histories
2526
* Blame
2627
* Revision Diffs
28+
* Branch Diff
29+
* Image Diff
2730
* GitFlow support
2831

2932
> **Linux** only tested on **Ubuntu 22.04** on **X11**.
@@ -87,6 +90,48 @@ This app supports open repository in external tools listed in the table below.
8790

8891
![Theme Light](./screenshots/theme_light.png)
8992

93+
## How to Customize Theme
94+
95+
1. Create a new json file, and provide your favorite colors with follow keys:
96+
97+
| Key | Description |
98+
| --- | --- |
99+
| Color.Window | Window background color |
100+
| Color.WindowBorder | Window border color. Only used on Linux. |
101+
| Color.TitleBar | Title bar background color |
102+
| Color.ToolBar | Tool bar background color |
103+
| Color.Popup | Popup panel background color |
104+
| Color.Contents | Background color used in inputs, data grids, file content viewer, change lists, text diff viewer, etc. |
105+
| Color.Badage | Badage background color |
106+
| Color.Conflict | Conflict panel background color |
107+
| Color.ConflictForeground | Conflict panel foreground color |
108+
| Color.Border0 | Border color used in some controls, like Window, Tab, Toolbar, etc. |
109+
| Color.Border1 | Border color used in inputs, like TextBox, ComboBox, etc. |
110+
| Color.Border2 | Border color used in visual lines, like seperators, Rectange, etc. |
111+
| Color.FlatButton.Background | Flat button background color, like `Cancel`, `Commit & Push` button |
112+
| Color.FlatButton.BackgroundHovered | Flat button background color when hovered, like `Cancel` button |
113+
| Color.FlatButton.PrimaryBackground | Primary flat button background color, like `Ok`, `Commit` button |
114+
| Color.FlatButton.PrimaryBackgroundHovered | Primary flat button background color when hovered, like `Ok`, `Commit` button |
115+
| Color.FG1 | Primary foreground color for all text elements |
116+
| Color.FG2 | Secondary foreground color for all text elements |
117+
| Color.Diff.EmptyBG | Background color used in empty lines in diff viewer |
118+
| Color.Diff.AddedBG | Background color used in added lines in diff viewer |
119+
| Color.Diff.DeletedBG | Background color used in deleted lines in diff viewer |
120+
| Color.Diff.AddedHighlight | Background color used for changed words in added lines in diff viewer |
121+
| Color.Diff.DeletedHighlight | Background color used for changed words in deleted lines in diff viewer |
122+
123+
For example:
124+
125+
```json
126+
{
127+
"Color.Window": "#FFFF6059"
128+
}
129+
```
130+
131+
2. Open `Preference` -> `Appearance`, choose the json file you just created in `Custom Color Schema`.
132+
133+
> **NOTE**: The `Custom Color Schema` will override the colors with same keys in current active theme.
134+
90135
## Contributing
91136

92137
Thanks to all the people who contribute.

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
8.16
1+
8.17

build/build.windows.ps1

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ if (Test-Path SourceGit) {
66

77
Remove-Item *.zip -Force
88

9+
dotnet publish ..\src\SourceGit.csproj -c Release -r win-arm64 -o SourceGit -p:PublishAot=true -p:PublishTrimmed=true -p:TrimMode=link --self-contained
10+
11+
Remove-Item SourceGit\*.pdb -Force
12+
13+
Compress-Archive -Path SourceGit -DestinationPath "sourcegit_$version.win-arm64.zip"
14+
15+
if (Test-Path SourceGit) {
16+
Remove-Item SourceGit -Recurse -Force
17+
}
18+
919
dotnet publish ..\src\SourceGit.csproj -c Release -r win-x64 -o SourceGit -p:PublishAot=true -p:PublishTrimmed=true -p:TrimMode=link --self-contained
1020

1121
Remove-Item SourceGit\*.pdb -Force

src/Commands/GitFlow.cs

Lines changed: 132 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,90 +1,164 @@
1-
using System.Collections.Generic;
1+
using System;
2+
using System.Collections.Generic;
23

34
using Avalonia.Threading;
45

56
namespace SourceGit.Commands
67
{
7-
public class GitFlow : Command
8+
public static class GitFlow
89
{
9-
public GitFlow(string repo)
10+
public class BranchDetectResult
1011
{
11-
WorkingDirectory = repo;
12-
Context = repo;
12+
public bool IsGitFlowBranch { get; set; } = false;
13+
public string Type { get; set; } = string.Empty;
14+
public string Prefix { get; set; } = string.Empty;
1315
}
1416

15-
public bool Init(List<Models.Branch> branches, string master, string develop, string feature, string release, string hotfix, string version)
17+
public static bool IsEnabled(string repo, List<Models.Branch> branches)
18+
{
19+
var localBrancheNames = new HashSet<string>();
20+
foreach (var branch in branches)
21+
{
22+
if (branch.IsLocal)
23+
localBrancheNames.Add(branch.Name);
24+
}
25+
26+
var config = new Config(repo).ListAll();
27+
if (!config.TryGetValue("gitflow.branch.master", out string master) || !localBrancheNames.Contains(master))
28+
return false;
29+
30+
if (!config.TryGetValue("gitflow.branch.develop", out string develop) || !localBrancheNames.Contains(develop))
31+
return false;
32+
33+
return config.ContainsKey("gitflow.prefix.feature") &&
34+
config.ContainsKey("gitflow.prefix.release") &&
35+
config.ContainsKey("gitflow.prefix.hotfix");
36+
}
37+
38+
public static bool Init(string repo, List<Models.Branch> branches, string master, string develop, string feature, string release, string hotfix, string version)
1639
{
1740
var current = branches.Find(x => x.IsCurrent);
1841

1942
var masterBranch = branches.Find(x => x.Name == master);
2043
if (masterBranch == null && current != null)
21-
Branch.Create(WorkingDirectory, master, current.Head);
44+
Branch.Create(repo, master, current.Head);
2245

2346
var devBranch = branches.Find(x => x.Name == develop);
2447
if (devBranch == null && current != null)
25-
Branch.Create(WorkingDirectory, develop, current.Head);
26-
27-
var cmd = new Config(WorkingDirectory);
28-
cmd.Set("gitflow.branch.master", master);
29-
cmd.Set("gitflow.branch.develop", develop);
30-
cmd.Set("gitflow.prefix.feature", feature);
31-
cmd.Set("gitflow.prefix.bugfix", "bugfix/");
32-
cmd.Set("gitflow.prefix.release", release);
33-
cmd.Set("gitflow.prefix.hotfix", hotfix);
34-
cmd.Set("gitflow.prefix.support", "support/");
35-
cmd.Set("gitflow.prefix.versiontag", version, true);
36-
37-
Args = "flow init -d";
38-
return Exec();
48+
Branch.Create(repo, develop, current.Head);
49+
50+
var config = new Config(repo);
51+
config.Set("gitflow.branch.master", master);
52+
config.Set("gitflow.branch.develop", develop);
53+
config.Set("gitflow.prefix.feature", feature);
54+
config.Set("gitflow.prefix.bugfix", "bugfix/");
55+
config.Set("gitflow.prefix.release", release);
56+
config.Set("gitflow.prefix.hotfix", hotfix);
57+
config.Set("gitflow.prefix.support", "support/");
58+
config.Set("gitflow.prefix.versiontag", version, true);
59+
60+
var init = new Command();
61+
init.WorkingDirectory = repo;
62+
init.Context = repo;
63+
init.Args = "flow init -d";
64+
return init.Exec();
3965
}
4066

41-
public bool Start(Models.GitFlowBranchType type, string name)
67+
public static string Prefix(string repo, string type)
4268
{
43-
switch (type)
69+
return new Config(repo).Get($"gitflow.prefix.{type}");
70+
}
71+
72+
public static BranchDetectResult DetectType(string repo, List<Models.Branch> branches, string branch)
73+
{
74+
var rs = new BranchDetectResult();
75+
var localBrancheNames = new HashSet<string>();
76+
foreach (var b in branches)
4477
{
45-
case Models.GitFlowBranchType.Feature:
46-
Args = $"flow feature start {name}";
47-
break;
48-
case Models.GitFlowBranchType.Release:
49-
Args = $"flow release start {name}";
50-
break;
51-
case Models.GitFlowBranchType.Hotfix:
52-
Args = $"flow hotfix start {name}";
53-
break;
54-
default:
55-
Dispatcher.UIThread.Invoke(() =>
56-
{
57-
App.RaiseException(Context, "Bad branch type!!!");
58-
});
59-
return false;
78+
if (b.IsLocal)
79+
localBrancheNames.Add(b.Name);
6080
}
6181

62-
return Exec();
82+
var config = new Config(repo).ListAll();
83+
if (!config.TryGetValue("gitflow.branch.master", out string master) || !localBrancheNames.Contains(master))
84+
return rs;
85+
86+
if (!config.TryGetValue("gitflow.branch.develop", out string develop) || !localBrancheNames.Contains(develop))
87+
return rs;
88+
89+
if (!config.TryGetValue("gitflow.prefix.feature", out var feature) ||
90+
!config.TryGetValue("gitflow.prefix.release", out var release) ||
91+
!config.TryGetValue("gitflow.prefix.hotfix", out var hotfix))
92+
return rs;
93+
94+
if (branch.StartsWith(feature, StringComparison.Ordinal))
95+
{
96+
rs.IsGitFlowBranch = true;
97+
rs.Type = "feature";
98+
rs.Prefix = feature;
99+
}
100+
else if (branch.StartsWith(release, StringComparison.Ordinal))
101+
{
102+
rs.IsGitFlowBranch = true;
103+
rs.Type = "release";
104+
rs.Prefix = release;
105+
}
106+
else if (branch.StartsWith(hotfix, StringComparison.Ordinal))
107+
{
108+
rs.IsGitFlowBranch = true;
109+
rs.Type = "hotfix";
110+
rs.Prefix = hotfix;
111+
}
112+
113+
return rs;
63114
}
64115

65-
public bool Finish(Models.GitFlowBranchType type, string name, bool keepBranch)
116+
public static bool Start(string repo, string type, string name)
66117
{
67-
var option = keepBranch ? "-k" : string.Empty;
68-
switch (type)
118+
if (!SUPPORTED_BRANCH_TYPES.Contains(type))
69119
{
70-
case Models.GitFlowBranchType.Feature:
71-
Args = $"flow feature finish {option} {name}";
72-
break;
73-
case Models.GitFlowBranchType.Release:
74-
Args = $"flow release finish {option} {name} -m \"RELEASE_DONE\"";
75-
break;
76-
case Models.GitFlowBranchType.Hotfix:
77-
Args = $"flow hotfix finish {option} {name} -m \"HOTFIX_DONE\"";
78-
break;
79-
default:
80-
Dispatcher.UIThread.Invoke(() =>
81-
{
82-
App.RaiseException(Context, "Bad branch type!!!");
83-
});
84-
return false;
120+
Dispatcher.UIThread.Post(() =>
121+
{
122+
App.RaiseException(repo, "Bad branch type!!!");
123+
});
124+
125+
return false;
85126
}
86127

87-
return Exec();
128+
var start = new Command();
129+
start.WorkingDirectory = repo;
130+
start.Context = repo;
131+
start.Args = $"flow {type} start {name}";
132+
return start.Exec();
88133
}
134+
135+
public static bool Finish(string repo, string type, string name, bool keepBranch)
136+
{
137+
if (!SUPPORTED_BRANCH_TYPES.Contains(type))
138+
{
139+
Dispatcher.UIThread.Post(() =>
140+
{
141+
App.RaiseException(repo, "Bad branch type!!!");
142+
});
143+
144+
return false;
145+
}
146+
147+
var option = keepBranch ? "-k" : string.Empty;
148+
var finish = new Command();
149+
finish.WorkingDirectory = repo;
150+
finish.Context = repo;
151+
finish.Args = $"flow {type} finish {option} {name}";
152+
return finish.Exec();
153+
}
154+
155+
private static readonly List<string> SUPPORTED_BRANCH_TYPES = new List<string>()
156+
{
157+
"feature",
158+
"release",
159+
"bugfix",
160+
"hotfix",
161+
"support",
162+
};
89163
}
90164
}

src/Commands/GitIgnore.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System.IO;
2+
3+
namespace SourceGit.Commands
4+
{
5+
public static class GitIgnore
6+
{
7+
public static void Add(string repo, string pattern)
8+
{
9+
var file = Path.Combine(repo, ".gitignore");
10+
if (!File.Exists(file))
11+
File.WriteAllLines(file, [ pattern ]);
12+
else
13+
File.AppendAllLines(file, [ pattern ]);
14+
}
15+
}
16+
}

src/Commands/QueryCommitFullMessage.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ public QueryCommitFullMessage(string repo, string sha)
1212
public string Result()
1313
{
1414
var rs = ReadToEnd();
15-
if (rs.IsSuccess) return rs.StdOut.TrimEnd();
15+
if (rs.IsSuccess)
16+
return rs.StdOut.TrimEnd();
1617
return string.Empty;
1718
}
1819
}

src/Commands/QueryCommits.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,14 @@ public QueryCommits(string repo, string limits, bool needFindHead = true)
5858
}
5959

6060
nextPartIdx++;
61-
61+
6262
start = end + 1;
6363
end = rs.StdOut.IndexOf('\n', start);
6464
}
6565

66+
if (start < rs.StdOut.Length)
67+
_current.Subject = rs.StdOut.Substring(start);
68+
6669
if (_findFirstMerged && !_isHeadFounded && _commits.Count > 0)
6770
MarkFirstMerged();
6871

src/Commands/QuerySingleCommit.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.Text;
43

54
namespace SourceGit.Commands
65
{

src/Converters/WindowStateConverters.cs

Lines changed: 0 additions & 34 deletions
This file was deleted.

0 commit comments

Comments
 (0)