Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit ab4ef4f

Browse files
Merge branch 'release/v2025.33'
2 parents 6d28822 + 98150ac commit ab4ef4f

File tree

92 files changed

+1366
-844
lines changed

Some content is hidden

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

92 files changed

+1366
-844
lines changed

‎TRANSLATION.md

Lines changed: 118 additions & 23 deletions
Large diffs are not rendered by default.

‎VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2025.32
1+
2025.33

‎src/App.axaml.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,19 @@ public static async Task<bool> AskConfirmAsync(string message)
170170
return false;
171171
}
172172

173+
public static async Task<Models.ConfirmEmptyCommitResult> AskConfirmEmptyCommitAsync(bool hasLocalChanges)
174+
{
175+
if (Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime { MainWindow: { } owner })
176+
{
177+
var confirm = new Views.ConfirmEmptyCommit();
178+
confirm.TxtMessage.Text = Text(hasLocalChanges ? "ConfirmEmptyCommit.WithLocalChanges" : "ConfirmEmptyCommit.NoLocalChanges");
179+
confirm.BtnStageAllAndCommit.IsVisible = hasLocalChanges;
180+
return await confirm.ShowDialog<Models.ConfirmEmptyCommitResult>(owner);
181+
}
182+
183+
return Models.ConfirmEmptyCommitResult.Cancel;
184+
}
185+
173186
public static void RaiseException(string context, string message)
174187
{
175188
if (Current is App { _launcher: not null } app)

‎src/Commands/Commit.cs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,39 @@
11
using System.IO;
2+
using System.Text;
23
using System.Threading.Tasks;
34

45
namespace SourceGit.Commands
56
{
67
public class Commit : Command
78
{
8-
public Commit(string repo, string message, bool signOff, bool amend, bool resetAuthor)
9+
public Commit(string repo, string message, bool signOff, bool noVerify,boolamend, bool resetAuthor)
910
{
1011
_tmpFile = Path.GetTempFileName();
1112
_message = message;
1213

1314
WorkingDirectory = repo;
1415
Context = repo;
15-
Args = $"commit --allow-empty --file={_tmpFile.Quoted()}";
16+
17+
var builder = new StringBuilder();
18+
builder.Append("commit --allow-empty --file=");
19+
builder.Append(_tmpFile.Quoted());
20+
builder.Append(' ');
21+
1622
if (signOff)
17-
Args += " --signoff";
23+
builder.Append("--signoff ");
24+
25+
if (noVerify)
26+
builder.Append("--no-verify ");
27+
1828
if (amend)
19-
Args += resetAuthor ? " --amend --reset-author --no-edit" : " --amend --no-edit";
29+
{
30+
builder.Append("--amend ");
31+
if (resetAuthor)
32+
builder.Append("--reset-author ");
33+
builder.Append("--no-edit");
34+
}
35+
36+
Args = builder.ToString();
2037
}
2138

2239
public async Task<bool> RunAsync()

‎src/Commands/DiffTool.cs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,15 @@ public void Open()
1717
var tool = Native.OS.GetDiffMergeTool(true);
1818
if (tool == null)
1919
{
20-
App.RaiseException(Context, "Invalid merge tool in preference setting!");
20+
App.RaiseException(Context, "Invalid diff/merge tool in preference setting!");
2121
return;
2222
}
2323

2424
if (string.IsNullOrEmpty(tool.Cmd))
2525
{
26+
if (!CheckGitConfiguration())
27+
return;
28+
2629
Args = $"difftool -g --no-prompt {_option}";
2730
}
2831
else
@@ -41,6 +44,34 @@ public void Open()
4144
}
4245
}
4346

47+
private bool CheckGitConfiguration()
48+
{
49+
var config = new Config(WorkingDirectory).ReadAll();
50+
if (config.TryGetValue("diff.guitool", out var guiTool))
51+
return CheckCLIBasedTool(guiTool);
52+
if (config.TryGetValue("merge.guitool", out var mergeGuiTool))
53+
return CheckCLIBasedTool(mergeGuiTool);
54+
if (config.TryGetValue("diff.tool", out var diffTool))
55+
return CheckCLIBasedTool(diffTool);
56+
if (config.TryGetValue("merge.tool", out var mergeTool))
57+
return CheckCLIBasedTool(mergeTool);
58+
59+
App.RaiseException(Context, "Missing git configuration: diff.guitool");
60+
return false;
61+
}
62+
63+
private bool CheckCLIBasedTool(string tool)
64+
{
65+
if (tool.StartsWith("vimdiff", StringComparison.Ordinal) ||
66+
tool.StartsWith("nvimdiff", StringComparison.Ordinal))
67+
{
68+
App.RaiseException(Context, $"CLI based diff tool \"{tool}\" is not supported by this app!");
69+
return false;
70+
}
71+
72+
return true;
73+
}
74+
4475
private Models.DiffOption _option;
4576
}
4677
}

‎src/Commands/IssueTracker.cs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,21 @@ namespace SourceGit.Commands
77
{
88
public class IssueTracker : Command
99
{
10-
public IssueTracker(string repo, stringstorage)
10+
public IssueTracker(string repo, boolisShared)
1111
{
1212
WorkingDirectory = repo;
1313
Context = repo;
1414

15-
if (string.IsNullOrEmpty(storage))
15+
if (isShared)
1616
{
17-
_isStorageFileExists = true;
18-
_baseArg = "config --local";
17+
var storage = $"{repo}/.issuetracker";
18+
_isStorageFileExists = File.Exists(storage);
19+
_baseArg = $"config -f {storage.Quoted()}";
1920
}
2021
else
2122
{
22-
_isStorageFileExists = File.Exists(storage);
23-
_baseArg = $"config -f {storage.Quoted()}";
23+
_isStorageFileExists = true;
24+
_baseArg = "config --local";
2425
}
2526
}
2627

@@ -79,12 +80,24 @@ public async Task<bool> AddAsync(Models.IssueTracker rule)
7980
return false;
8081
}
8182

82-
public async Task<bool> RemoveAsync(Models.IssueTracker rule)
83+
public async Task<bool> UpdateRegexAsync(Models.IssueTracker rule)
84+
{
85+
Args = $"{_baseArg} issuetracker.{rule.Name.Quoted()}.regex {rule.RegexString.Quoted()}";
86+
return await ExecAsync().ConfigureAwait(false);
87+
}
88+
89+
public async Task<bool> UpdateURLTemplateAsync(Models.IssueTracker rule)
90+
{
91+
Args = $"{_baseArg} issuetracker.{rule.Name.Quoted()}.url {rule.URLTemplate.Quoted()}";
92+
return await ExecAsync().ConfigureAwait(false);
93+
}
94+
95+
public async Task<bool> RemoveAsync(string name)
8396
{
8497
if (!_isStorageFileExists)
8598
return true;
8699

87-
Args = $"{_baseArg} --remove-section issuetracker.{rule.Name.Quoted()}";
100+
Args = $"{_baseArg} --remove-section issuetracker.{name.Quoted()}";
88101
return await ExecAsync().ConfigureAwait(false);
89102
}
90103

‎src/Commands/MergeTool.cs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Threading.Tasks;
1+
using System;
2+
using System.Threading.Tasks;
23

34
namespace SourceGit.Commands
45
{
@@ -16,13 +17,17 @@ public async Task<bool> OpenAsync()
1617
var tool = Native.OS.GetDiffMergeTool(false);
1718
if (tool == null)
1819
{
19-
App.RaiseException(Context, "Invalid merge tool in preference setting!");
20+
App.RaiseException(Context, "Invalid diff/merge tool in preference setting!");
2021
return false;
2122
}
2223

2324
if (string.IsNullOrEmpty(tool.Cmd))
2425
{
25-
Args = $"mergetool {_file}";
26+
var ok = await CheckGitConfigurationAsync();
27+
if (!ok)
28+
return false;
29+
30+
Args = $"mergetool -g --no-prompt {_file}";
2631
}
2732
else
2833
{
@@ -33,6 +38,28 @@ public async Task<bool> OpenAsync()
3338
return await ExecAsync().ConfigureAwait(false);
3439
}
3540

41+
private async Task<bool> CheckGitConfigurationAsync()
42+
{
43+
var tool = await new Config(WorkingDirectory).GetAsync("merge.guitool");
44+
if (string.IsNullOrEmpty(tool))
45+
tool = await new Config(WorkingDirectory).GetAsync("merge.tool");
46+
47+
if (string.IsNullOrEmpty(tool))
48+
{
49+
App.RaiseException(Context, "Missing git configuration: merge.guitool");
50+
return false;
51+
}
52+
53+
if (tool.StartsWith("vimdiff", StringComparison.Ordinal) ||
54+
tool.StartsWith("nvimdiff", StringComparison.Ordinal))
55+
{
56+
App.RaiseException(Context, $"CLI based merge tool \"{tool}\" is not supported by this app!");
57+
return false;
58+
}
59+
60+
return true;
61+
}
62+
3663
private string _file;
3764
}
3865
}

‎src/Commands/QueryBranches.cs

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public QueryBranches(string repo)
1515
{
1616
WorkingDirectory = repo;
1717
Context = repo;
18-
Args = "branch -l --all -v --format=\"%(refname)%00%(committerdate:unix)%00%(objectname)%00%(HEAD)%00%(upstream)%00%(upstream:trackshort)\"";
18+
Args = "branch -l --all -v --format=\"%(refname)%00%(committerdate:unix)%00%(objectname)%00%(HEAD)%00%(upstream)%00%(upstream:trackshort)%00%(worktreepath)\"";
1919
}
2020

2121
public async Task<List<Models.Branch>> GetResultAsync()
@@ -26,42 +26,44 @@ public QueryBranches(string repo)
2626
return branches;
2727

2828
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
29-
var remoteHeads = new Dictionary<string, string>();
29+
var mismatched = new HashSet<string>();
30+
var remotes = new Dictionary<string, Models.Branch>();
3031
foreach (var line in lines)
3132
{
32-
var b = ParseLine(line);
33+
var b = ParseLine(line,mismatched);
3334
if (b != null)
3435
{
3536
branches.Add(b);
3637
if (!b.IsLocal)
37-
remoteHeads.Add(b.FullName, b.Head);
38+
remotes.Add(b.FullName, b);
3839
}
3940
}
4041

4142
foreach (var b in branches)
4243
{
4344
if (b.IsLocal && !string.IsNullOrEmpty(b.Upstream))
4445
{
45-
if (remoteHeads.TryGetValue(b.Upstream, out var upstreamHead))
46+
if (remotes.TryGetValue(b.Upstream, out var upstream))
4647
{
4748
b.IsUpstreamGone = false;
48-
b.TrackStatus ??= await new QueryTrackStatus(WorkingDirectory, b.Head, upstreamHead).GetResultAsync().ConfigureAwait(false);
49+
50+
if (mismatched.Contains(b.FullName))
51+
await new QueryTrackStatus(WorkingDirectory).GetResultAsync(b, upstream).ConfigureAwait(false);
4952
}
5053
else
5154
{
5255
b.IsUpstreamGone = true;
53-
b.TrackStatus ??= new Models.BranchTrackStatus();
5456
}
5557
}
5658
}
5759

5860
return branches;
5961
}
6062

61-
private Models.Branch ParseLine(string line)
63+
private Models.Branch ParseLine(string line,HashSet<string>mismatched)
6264
{
6365
var parts = line.Split('0円');
64-
if (parts.Length != 6)
66+
if (parts.Length != 7)
6567
return null;
6668

6769
var branch = new Models.Branch();
@@ -103,12 +105,13 @@ private Models.Branch ParseLine(string line)
103105
branch.Upstream = parts[4];
104106
branch.IsUpstreamGone = false;
105107

106-
if (!branch.IsLocal ||
107-
string.IsNullOrEmpty(branch.Upstream) ||
108-
string.IsNullOrEmpty(parts[5]) ||
109-
parts[5].Equals("=", StringComparison.Ordinal))
110-
branch.TrackStatus=newModels.BranchTrackStatus();
108+
if (branch.IsLocal &&
109+
!string.IsNullOrEmpty(branch.Upstream) &&
110+
!string.IsNullOrEmpty(parts[5]) &&
111+
!parts[5].Equals("=", StringComparison.Ordinal))
112+
mismatched.Add(branch.FullName);
111113

114+
branch.WorktreePath = parts[6];
112115
return branch;
113116
}
114117
}

‎src/Commands/QueryCommitsForInteractiveRebase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public QueryCommitsForInteractiveRebase(string repo, string on)
1212

1313
WorkingDirectory = repo;
1414
Context = repo;
15-
Args = $"log --date-order --no-show-signature --decorate=full --format=\"%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%B%n{_boundary}\" {on}..HEAD";
15+
Args = $"log --topo-order --right-only --max-parents=1 --no-show-signature --decorate=full --format=\"%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%B%n{_boundary}\" {on}..HEAD";
1616
}
1717

1818
public async Task<List<Models.InteractiveCommit>> GetResultAsync()

‎src/Commands/QueryGitCommonDir.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System.IO;
2+
using System.Threading.Tasks;
3+
4+
namespace SourceGit.Commands
5+
{
6+
public class QueryGitCommonDir : Command
7+
{
8+
public QueryGitCommonDir(string workDir)
9+
{
10+
WorkingDirectory = workDir;
11+
Args = "rev-parse --git-common-dir";
12+
RaiseError = false;
13+
}
14+
15+
public async Task<string> GetResultAsync()
16+
{
17+
var rs = await ReadToEndAsync().ConfigureAwait(false);
18+
if (!rs.IsSuccess || string.IsNullOrEmpty(rs.StdOut))
19+
return string.Empty;
20+
21+
var dir = rs.StdOut.Trim();
22+
if (Path.IsPathRooted(dir))
23+
return dir;
24+
return Path.GetFullPath(Path.Combine(WorkingDirectory, dir));
25+
}
26+
}
27+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /