Skip to content

Commit fb6b57b

Browse files
committed
Merge branch 'release/v2025.06'
2 parents ed37b42 + 0b7805b commit fb6b57b

36 files changed

+582
-232
lines changed

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
4848
## Translation Status
4949

50-
[![en_US](https://img.shields.io/badge/en__US-%E2%88%9A-brightgreen)](TRANSLATION.md) [![de__DE](https://img.shields.io/badge/de__DE-99.47%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-97.61%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-92.42%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-97.87%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-92.15%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-99.73%25-yellow)](TRANSLATION.md) [![zh__CN](https://img.shields.io/badge/zh__CN-%E2%88%9A-brightgreen)](TRANSLATION.md) [![zh__TW](https://img.shields.io/badge/zh__TW-%E2%88%9A-brightgreen)](TRANSLATION.md)
50+
[![en_US](https://img.shields.io/badge/en__US-%E2%88%9A-brightgreen)](TRANSLATION.md) [![de__DE](https://img.shields.io/badge/de__DE-99.34%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-99.74%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-91.93%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-97.35%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-91.67%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-99.21%25-yellow)](TRANSLATION.md) [![zh__CN](https://img.shields.io/badge/zh__CN-%E2%88%9A-brightgreen)](TRANSLATION.md) [![zh__TW](https://img.shields.io/badge/zh__TW-%E2%88%9A-brightgreen)](TRANSLATION.md)
5151

5252
> [!NOTE]
5353
> You can find the missing keys in [TRANSLATION.md](TRANSLATION.md)
@@ -132,7 +132,7 @@ For **Linux** users:
132132

133133
## OpenAI
134134

135-
This software supports using OpenAI or other AI service that has an OpenAI comaptible HTTP API to generate commit message. You need configurate the service in `Preference` window.
135+
This software supports using OpenAI or other AI service that has an OpenAI compatible HTTP API to generate commit message. You need configurate the service in `Preference` window.
136136

137137
For `OpenAI`:
138138

TRANSLATION.md

+28-27
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,29 @@
1-
### de_DE.axaml: 99.47%
1+
### de_DE.axaml: 99.34%
22

33

44
<details>
55
<summary>Missing Keys</summary>
66

7-
- Text.BranchCM.CustomAction
8-
- Text.Configure.CustomAction.Scope.Branch
7+
- Text.BranchUpstreamInvalid
98
- Text.Configure.CustomAction.WaitForExit
10-
- Text.Repository.Notifications.Clear
9+
- Text.Diff.First
10+
- Text.Diff.Last
11+
- Text.Preferences.AI.Streaming
1112

1213
</details>
1314

14-
### es_ES.axaml: 97.61%
15+
### es_ES.axaml: 99.74%
1516

1617

1718
<details>
1819
<summary>Missing Keys</summary>
1920

20-
- Text.AIAssistant.Regen
21-
- Text.AIAssistant.Use
22-
- Text.ApplyStash
23-
- Text.ApplyStash.DropAfterApply
24-
- Text.ApplyStash.RestoreIndex
25-
- Text.ApplyStash.Stash
26-
- Text.BranchCM.CustomAction
27-
- Text.Clone.RecurseSubmodules
28-
- Text.Configure.CustomAction.Scope.Branch
29-
- Text.Configure.CustomAction.WaitForExit
30-
- Text.CreateBranch.Name.WarnSpace
31-
- Text.DeleteRepositoryNode.Path
32-
- Text.DeleteRepositoryNode.TipForGroup
33-
- Text.DeleteRepositoryNode.TipForRepository
34-
- Text.Repository.Notifications.Clear
35-
- Text.Stash.AutoRestore
36-
- Text.Stash.AutoRestore.Tip
37-
- Text.WorkingCopy.SignOff
21+
- Text.Diff.First
22+
- Text.Diff.Last
3823

3924
</details>
4025

41-
### fr_FR.axaml: 92.42%
26+
### fr_FR.axaml: 91.93%
4227

4328

4429
<details>
@@ -51,13 +36,16 @@
5136
- Text.ApplyStash.RestoreIndex
5237
- Text.ApplyStash.Stash
5338
- Text.BranchCM.CustomAction
39+
- Text.BranchUpstreamInvalid
5440
- Text.Clone.RecurseSubmodules
5541
- Text.Configure.CustomAction.Scope.Branch
5642
- Text.Configure.CustomAction.WaitForExit
5743
- Text.CreateBranch.Name.WarnSpace
5844
- Text.DeleteRepositoryNode.Path
5945
- Text.DeleteRepositoryNode.TipForGroup
6046
- Text.DeleteRepositoryNode.TipForRepository
47+
- Text.Diff.First
48+
- Text.Diff.Last
6149
- Text.InProgress.CherryPick.Head
6250
- Text.InProgress.Merge.Operating
6351
- Text.InProgress.Rebase.StoppedAt
@@ -67,6 +55,7 @@
6755
- Text.MergeMultiple.CommitChanges
6856
- Text.MergeMultiple.Strategy
6957
- Text.MergeMultiple.Targets
58+
- Text.Preferences.AI.Streaming
7059
- Text.Preferences.Appearance.FontSize
7160
- Text.Preferences.Appearance.FontSize.Default
7261
- Text.Preferences.Appearance.FontSize.Editor
@@ -104,7 +93,7 @@
10493

10594
</details>
10695

107-
### it_IT.axaml: 97.87%
96+
### it_IT.axaml: 97.35%
10897

10998

11099
<details>
@@ -117,19 +106,23 @@
117106
- Text.ApplyStash.RestoreIndex
118107
- Text.ApplyStash.Stash
119108
- Text.BranchCM.CustomAction
109+
- Text.BranchUpstreamInvalid
120110
- Text.Clone.RecurseSubmodules
121111
- Text.Configure.CustomAction.Scope.Branch
122112
- Text.Configure.CustomAction.WaitForExit
123113
- Text.DeleteRepositoryNode.Path
124114
- Text.DeleteRepositoryNode.TipForGroup
125115
- Text.DeleteRepositoryNode.TipForRepository
116+
- Text.Diff.First
117+
- Text.Diff.Last
118+
- Text.Preferences.AI.Streaming
126119
- Text.Repository.Notifications.Clear
127120
- Text.Stash.AutoRestore
128121
- Text.Stash.AutoRestore.Tip
129122

130123
</details>
131124

132-
### pt_BR.axaml: 92.15%
125+
### pt_BR.axaml: 91.67%
133126

134127

135128
<details>
@@ -143,6 +136,7 @@
143136
- Text.ApplyStash.Stash
144137
- Text.BranchCM.CustomAction
145138
- Text.BranchCM.MergeMultiBranches
139+
- Text.BranchUpstreamInvalid
146140
- Text.Clone.RecurseSubmodules
147141
- Text.CommitCM.Merge
148142
- Text.CommitCM.MergeMultiple
@@ -156,6 +150,8 @@
156150
- Text.DeleteRepositoryNode.Path
157151
- Text.DeleteRepositoryNode.TipForGroup
158152
- Text.DeleteRepositoryNode.TipForRepository
153+
- Text.Diff.First
154+
- Text.Diff.Last
159155
- Text.Diff.UseBlockNavigation
160156
- Text.Fetch.Force
161157
- Text.FileCM.ResolveUsing
@@ -169,6 +165,7 @@
169165
- Text.MergeMultiple.CommitChanges
170166
- Text.MergeMultiple.Strategy
171167
- Text.MergeMultiple.Targets
168+
- Text.Preferences.AI.Streaming
172169
- Text.Preferences.General.DateFormat
173170
- Text.Preferences.General.ShowChildren
174171
- Text.Preferences.Git.SSLVerify
@@ -197,14 +194,18 @@
197194

198195
</details>
199196

200-
### ru_RU.axaml: 99.73%
197+
### ru_RU.axaml: 99.21%
201198

202199

203200
<details>
204201
<summary>Missing Keys</summary>
205202

206203
- Text.BranchCM.CustomAction
204+
- Text.BranchUpstreamInvalid
207205
- Text.Configure.CustomAction.Scope.Branch
206+
- Text.Diff.First
207+
- Text.Diff.Last
208+
- Text.Preferences.AI.Streaming
208209

209210
</details>
210211

VERSION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2025.05
1+
2025.06

src/Commands/Add.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public Add(string repo, bool includeUntracked)
1212
Args = includeUntracked ? "add ." : "add -u .";
1313
}
1414

15-
public Add(string repo, List<Models.Change> changes)
15+
public Add(string repo, List<string> changes)
1616
{
1717
WorkingDirectory = repo;
1818
Context = repo;
@@ -22,7 +22,7 @@ public Add(string repo, List<Models.Change> changes)
2222
foreach (var c in changes)
2323
{
2424
builder.Append(" \"");
25-
builder.Append(c.Path);
25+
builder.Append(c);
2626
builder.Append("\"");
2727
}
2828
Args = builder.ToString();

src/Commands/GenerateCommitMessage.cs

+12-69
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Text;
4-
using System.Text.RegularExpressions;
54
using System.Threading;
65

76
using Avalonia.Threading;
@@ -36,6 +35,8 @@ public void Exec()
3635
{
3736
try
3837
{
38+
_onResponse?.Invoke("Waiting for pre-file analyzing to completed...\n\n");
39+
3940
var responseBuilder = new StringBuilder();
4041
var summaryBuilder = new StringBuilder();
4142
foreach (var change in _changes)
@@ -49,18 +50,17 @@ public void Exec()
4950
var rs = new GetDiffContent(_repo, new Models.DiffOption(change, false)).ReadToEnd();
5051
if (rs.IsSuccess)
5152
{
52-
var hasFirstValidChar = false;
53-
var thinkingBuffer = new StringBuilder();
5453
_service.Chat(
5554
_service.AnalyzeDiffPrompt,
5655
$"Here is the `git diff` output: {rs.StdOut}",
5756
_cancelToken,
5857
update =>
59-
ProcessChatResponse(update, ref hasFirstValidChar, thinkingBuffer,
60-
(responseBuilder, text =>
61-
_onResponse?.Invoke(
62-
$"Waiting for pre-file analyzing to completed...\n\n{text}")),
63-
(summaryBuilder, null)));
58+
{
59+
responseBuilder.Append(update);
60+
summaryBuilder.Append(update);
61+
62+
_onResponse?.Invoke($"Waiting for pre-file analyzing to completed...\n\n{responseBuilder}");
63+
});
6464
}
6565

6666
responseBuilder.Append("\n");
@@ -74,83 +74,26 @@ public void Exec()
7474

7575
var responseBody = responseBuilder.ToString();
7676
var subjectBuilder = new StringBuilder();
77-
var hasSubjectFirstValidChar = false;
78-
var subjectThinkingBuffer = new StringBuilder();
7977
_service.Chat(
8078
_service.GenerateSubjectPrompt,
8179
$"Here are the summaries changes:\n{summaryBuilder}",
8280
_cancelToken,
8381
update =>
84-
ProcessChatResponse(update, ref hasSubjectFirstValidChar, subjectThinkingBuffer,
85-
(subjectBuilder, text => _onResponse?.Invoke($"{text}\n\n{responseBody}"))));
82+
{
83+
subjectBuilder.Append(update);
84+
_onResponse?.Invoke($"{subjectBuilder}\n\n{responseBody}");
85+
});
8686
}
8787
catch (Exception e)
8888
{
8989
Dispatcher.UIThread.Post(() => App.RaiseException(_repo, $"Failed to generate commit message: {e}"));
9090
}
9191
}
9292

93-
private void ProcessChatResponse(
94-
string update,
95-
ref bool hasFirstValidChar,
96-
StringBuilder thinkingBuffer,
97-
params (StringBuilder builder, Action<string> callback)[] outputs)
98-
{
99-
if (!hasFirstValidChar)
100-
{
101-
update = update.TrimStart();
102-
if (string.IsNullOrEmpty(update))
103-
return;
104-
if (update.StartsWith("<", StringComparison.Ordinal))
105-
thinkingBuffer.Append(update);
106-
hasFirstValidChar = true;
107-
}
108-
109-
if (thinkingBuffer.Length > 0)
110-
thinkingBuffer.Append(update);
111-
112-
if (thinkingBuffer.Length > 15)
113-
{
114-
var match = REG_COT.Match(thinkingBuffer.ToString());
115-
if (match.Success)
116-
{
117-
update = REG_COT.Replace(thinkingBuffer.ToString(), "").TrimStart();
118-
if (update.Length > 0)
119-
{
120-
foreach (var output in outputs)
121-
output.builder.Append(update);
122-
thinkingBuffer.Clear();
123-
}
124-
return;
125-
}
126-
127-
match = REG_THINK_START.Match(thinkingBuffer.ToString());
128-
if (!match.Success)
129-
{
130-
foreach (var output in outputs)
131-
output.builder.Append(thinkingBuffer);
132-
thinkingBuffer.Clear();
133-
return;
134-
}
135-
}
136-
137-
if (thinkingBuffer.Length == 0)
138-
{
139-
foreach (var output in outputs)
140-
{
141-
output.builder.Append(update);
142-
output.callback?.Invoke(output.builder.ToString());
143-
}
144-
}
145-
}
146-
14793
private Models.OpenAIService _service;
14894
private string _repo;
14995
private List<Models.Change> _changes;
15096
private CancellationToken _cancelToken;
15197
private Action<string> _onResponse;
152-
153-
private static readonly Regex REG_COT = new(@"^<(think|thought|thinking|thought_chain)>(.*?)</\1>", RegexOptions.Singleline);
154-
private static readonly Regex REG_THINK_START = new(@"^<(think|thought|thinking|thought_chain)>", RegexOptions.Singleline);
15598
}
15699
}

src/Commands/QueryBranches.cs

+12
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,22 @@ public QueryBranches(string repo)
2525
return branches;
2626

2727
var lines = rs.StdOut.Split('\n', StringSplitOptions.RemoveEmptyEntries);
28+
var remoteBranches = new HashSet<string>();
2829
foreach (var line in lines)
2930
{
3031
var b = ParseLine(line);
3132
if (b != null)
33+
{
3234
branches.Add(b);
35+
if (!b.IsLocal)
36+
remoteBranches.Add(b.FullName);
37+
}
38+
}
39+
40+
foreach (var b in branches)
41+
{
42+
if (b.IsLocal && !string.IsNullOrEmpty(b.Upstream))
43+
b.IsUpsteamGone = !remoteBranches.Contains(b.Upstream);
3344
}
3445

3546
return branches;
@@ -75,6 +86,7 @@ private Models.Branch ParseLine(string line)
7586
branch.Head = parts[1];
7687
branch.IsCurrent = parts[2] == "*";
7788
branch.Upstream = parts[3];
89+
branch.IsUpsteamGone = false;
7890

7991
if (branch.IsLocal && !string.IsNullOrEmpty(parts[4]) && !parts[4].Equals("=", StringComparison.Ordinal))
8092
branch.TrackStatus = new QueryTrackStatus(WorkingDirectory, branch.Name, branch.Upstream).Result();

src/Converters/BoolConverters.cs

+4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
using Avalonia.Data.Converters;
2+
using Avalonia.Media;
23

34
namespace SourceGit.Converters
45
{
56
public static class BoolConverters
67
{
78
public static readonly FuncValueConverter<bool, double> ToPageTabWidth =
89
new FuncValueConverter<bool, double>(x => x ? 200 : double.NaN);
10+
11+
public static readonly FuncValueConverter<bool, FontWeight> IsBoldToFontWeight =
12+
new FuncValueConverter<bool, FontWeight>(x => x ? FontWeight.Bold : FontWeight.Normal);
913
}
1014
}

src/Models/Branch.cs

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public class Branch
3434
public string Upstream { get; set; }
3535
public BranchTrackStatus TrackStatus { get; set; }
3636
public string Remote { get; set; }
37+
public bool IsUpsteamGone { get; set; }
3738

3839
public string FriendlyName => IsLocal ? Name : $"{Remote}/{Name}";
3940
}

0 commit comments

Comments
 (0)