diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index e97d0b1b6..b3dd9d5ed 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -39,11 +39,11 @@ jobs:
apt-get install -y sudo
sudo apt-get install -y curl wget git unzip zip libicu66 tzdata clang
- name: Checkout sources
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
with:
submodules: true
- name: Setup .NET
- uses: actions/setup-dotnet@v4
+ uses: actions/setup-dotnet@v5
with:
dotnet-version: 10.0.x
- name: Configure arm64 packages
@@ -75,7 +75,7 @@ jobs:
rm -r publish/*
mv "sourcegit.${{ matrix.runtime }}.tar" publish
- name: Upload artifact
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v7
with:
name: sourcegit.${{ matrix.runtime }}
path: publish/*
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 50e02dc95..acd7dcde1 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,9 +1,9 @@
name: Continuous Integration
on:
push:
- branches: [develop]
+ branches: [develop, master]
pull_request:
- branches: [develop]
+ branches: [develop, master]
workflow_dispatch:
workflow_call:
jobs:
@@ -17,7 +17,7 @@ jobs:
version: ${{ steps.version.outputs.version }}
steps:
- name: Checkout sources
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
- name: Output version string
id: version
run: echo "version=$(cat VERSION)" >> "$GITHUB_OUTPUT"
diff --git a/.github/workflows/format-check.yml b/.github/workflows/format-check.yml
index adbeab527..43d5edf91 100644
--- a/.github/workflows/format-check.yml
+++ b/.github/workflows/format-check.yml
@@ -1,9 +1,9 @@
name: Format Check
on:
push:
- branches: [develop]
+ branches: [develop, master]
pull_request:
- branches: [develop]
+ branches: [develop, master]
workflow_dispatch:
workflow_call:
@@ -13,12 +13,12 @@ jobs:
steps:
- name: Checkout repository
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
with:
submodules: true
- name: Set up .NET
- uses: actions/setup-dotnet@v4
+ uses: actions/setup-dotnet@v5
with:
dotnet-version: 10.0.x
diff --git a/.github/workflows/localization-check.yml b/.github/workflows/localization-check.yml
index c5970870b..84274977a 100644
--- a/.github/workflows/localization-check.yml
+++ b/.github/workflows/localization-check.yml
@@ -1,7 +1,7 @@
name: Localization Check
on:
push:
- branches: [develop]
+ branches: [develop, master]
paths:
- 'src/Resources/Locales/**'
workflow_dispatch:
@@ -13,12 +13,12 @@ jobs:
steps:
- name: Checkout repository
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
- name: Set up Node.js
- uses: actions/setup-node@v4
+ uses: actions/setup-node@v6
with:
- node-version: '20.x'
+ node-version: '24.x'
- name: Install dependencies
run: npm install fs-extra@11.2.0 path@0.12.7 xml2js@0.6.2
diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml
index d203dd2e2..0845774fb 100644
--- a/.github/workflows/package.yml
+++ b/.github/workflows/package.yml
@@ -15,9 +15,9 @@ jobs:
runtime: [win-x64, win-arm64]
steps:
- name: Checkout sources
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
- name: Download build
- uses: actions/download-artifact@v4
+ uses: actions/download-artifact@v8
with:
name: sourcegit.${{ matrix.runtime }}
path: build/SourceGit
@@ -28,12 +28,12 @@ jobs:
RUNTIME: ${{ matrix.runtime }}
run: ./build/scripts/package.win.ps1
- name: Upload package artifact
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v7
with:
name: package.${{ matrix.runtime }}
path: build/sourcegit_*.zip
- name: Delete temp artifacts
- uses: geekyeggo/delete-artifact@v5
+ uses: geekyeggo/delete-artifact@v6
with:
name: sourcegit.${{ matrix.runtime }}
osx-app:
@@ -44,9 +44,9 @@ jobs:
runtime: [osx-x64, osx-arm64]
steps:
- name: Checkout sources
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
- name: Download build
- uses: actions/download-artifact@v4
+ uses: actions/download-artifact@v8
with:
name: sourcegit.${{ matrix.runtime }}
path: build
@@ -59,12 +59,12 @@ jobs:
tar -xf "build/sourcegit.${{ matrix.runtime }}.tar" -C build/SourceGit
./build/scripts/package.osx-app.sh
- name: Upload package artifact
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v7
with:
name: package.${{ matrix.runtime }}
path: build/sourcegit_*.zip
- name: Delete temp artifacts
- uses: geekyeggo/delete-artifact@v5
+ uses: geekyeggo/delete-artifact@v6
with:
name: sourcegit.${{ matrix.runtime }}
linux:
@@ -76,7 +76,7 @@ jobs:
runtime: [linux-x64, linux-arm64]
steps:
- name: Checkout sources
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
- name: Download package dependencies
run: |
export DEBIAN_FRONTEND=noninteractive
@@ -84,7 +84,7 @@ jobs:
apt-get update
apt-get install -y curl wget git dpkg-dev fakeroot tzdata zip unzip desktop-file-utils rpm libfuse2 file build-essential binutils
- name: Download build
- uses: actions/download-artifact@v4
+ uses: actions/download-artifact@v8
with:
name: sourcegit.${{ matrix.runtime }}
path: build
@@ -98,7 +98,7 @@ jobs:
tar -xf "build/sourcegit.${{ matrix.runtime }}.tar" -C build/SourceGit
./build/scripts/package.linux.sh
- name: Upload package artifacts
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v7
with:
name: package.${{ matrix.runtime }}
path: |
@@ -106,6 +106,6 @@ jobs:
build/sourcegit_*.deb
build/sourcegit-*.rpm
- name: Delete temp artifacts
- uses: geekyeggo/delete-artifact@v5
+ uses: geekyeggo/delete-artifact@v6
with:
name: sourcegit.${{ matrix.runtime }}
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index e61e608b0..816870a02 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -32,7 +32,7 @@ jobs:
contents: write
steps:
- name: Checkout sources
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
- name: Create release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -40,7 +40,7 @@ jobs:
VERSION: ${{ needs.version.outputs.version }}
run: gh release create "$TAG" -t "$VERSION" --notes-from-tag
- name: Download artifacts
- uses: actions/download-artifact@v4
+ uses: actions/download-artifact@v8
with:
pattern: package.*
path: packages
diff --git a/TRANSLATION.md b/TRANSLATION.md
index 994f52a3e..fd1e3672a 100644
--- a/TRANSLATION.md
+++ b/TRANSLATION.md
@@ -6,11 +6,12 @@ This document shows the translation status of each locale file in the repository
### 
-### 
+### 
Missing keys in de_DE.axaml
+- Text.Apply.3Way
- Text.CommandPalette.Branches
- Text.CommandPalette.BranchesAndTags
- Text.CommandPalette.RepositoryActions
@@ -18,6 +19,7 @@ This document shows the translation status of each locale file in the repository
- Text.CommitMessageTextBox.Column
- Text.ConfirmEmptyCommit.StageSelectedThenCommit
- Text.GotoRevisionSelector
+- Text.Hotkeys.Repo.CreateBranch
- Text.Hotkeys.Repo.GoToChild
- Text.Init.CommandTip
- Text.Init.ErrorMessageTip
@@ -29,21 +31,24 @@ This document shows the translation status of each locale file in the repository
-### 
+### 
Missing keys in es_ES.axaml
+- Text.Apply.3Way
+- Text.Hotkeys.Repo.CreateBranch
- Text.Preferences.General.Use24Hours
-### 
+### 
Missing keys in fr_FR.axaml
- Text.About.ReleaseDate
+- Text.Apply.3Way
- Text.Blame.IgnoreWhitespace
- Text.BranchCM.CompareTwo
- Text.BranchCM.CompareWith
@@ -70,6 +75,7 @@ This document shows the translation status of each locale file in the repository
- Text.Histories.ShowColumns
- Text.Hotkeys.Global.ShowWorkspaceDropdownMenu
- Text.Hotkeys.Global.Zoom
+- Text.Hotkeys.Repo.CreateBranch
- Text.Hotkeys.Repo.GoToChild
- Text.Hotkeys.Repo.GoToParent
- Text.Init.CommandTip
@@ -121,13 +127,14 @@ This document shows the translation status of each locale file in the repository
-### 
+### 
Missing keys in id_ID.axaml
- Text.About.ReleaseDate
- Text.About.ReleaseNotes
+- Text.Apply.3Way
- Text.Blame.BlameOnPreviousRevision
- Text.Blame.IgnoreWhitespace
- Text.BranchCM.CompareTwo
@@ -166,6 +173,7 @@ This document shows the translation status of each locale file in the repository
- Text.Histories.ShowColumns
- Text.Hotkeys.Global.ShowWorkspaceDropdownMenu
- Text.Hotkeys.Global.Zoom
+- Text.Hotkeys.Repo.CreateBranch
- Text.Hotkeys.Repo.GoToChild
- Text.Hotkeys.Repo.GoToParent
- Text.Hotkeys.Repo.OpenCommandPalette
@@ -224,11 +232,12 @@ This document shows the translation status of each locale file in the repository
-### 
+### 
Missing keys in it_IT.axaml
+- Text.Apply.3Way
- Text.ChangeCM.ResetFileTo
- Text.CommandPalette.Branches
- Text.CommandPalette.BranchesAndTags
@@ -239,6 +248,7 @@ This document shows the translation status of each locale file in the repository
- Text.GotoRevisionSelector
- Text.Histories.Header.DateTime
- Text.Histories.ShowColumns
+- Text.Hotkeys.Repo.CreateBranch
- Text.Hotkeys.Repo.GoToChild
- Text.Hotkeys.Repo.GoToParent
- Text.Init.CommandTip
@@ -253,16 +263,18 @@ This document shows the translation status of each locale file in the repository
-### 
+### 
Missing keys in ja_JP.axaml
+- Text.Apply.3Way
- Text.CommandPalette.Branches
- Text.CommandPalette.BranchesAndTags
- Text.CommandPalette.RepositoryActions
- Text.CommandPalette.RevisionFiles
- Text.ConfirmEmptyCommit.StageSelectedThenCommit
+- Text.Hotkeys.Repo.CreateBranch
- Text.Init.CommandTip
- Text.Init.ErrorMessageTip
- Text.Preferences.General.Use24Hours
@@ -272,12 +284,13 @@ This document shows the translation status of each locale file in the repository
-### 
+### 
Missing keys in ko_KR.axaml
- Text.About.ReleaseDate
+- Text.Apply.3Way
- Text.Blame.BlameOnPreviousRevision
- Text.Blame.IgnoreWhitespace
- Text.Blame.TypeNotSupported
@@ -312,6 +325,7 @@ This document shows the translation status of each locale file in the repository
- Text.Histories.ShowColumns
- Text.Hotkeys.Global.ShowWorkspaceDropdownMenu
- Text.Hotkeys.Global.Zoom
+- Text.Hotkeys.Repo.CreateBranch
- Text.Hotkeys.Repo.GoToChild
- Text.Hotkeys.Repo.GoToParent
- Text.Hotkeys.Repo.OpenCommandPalette
@@ -372,11 +386,12 @@ This document shows the translation status of each locale file in the repository
-### 
+### 
Missing keys in pt_BR.axaml
+- Text.Apply.3Way
- Text.Blame.BlameOnPreviousRevision
- Text.BranchCM.InteractiveRebase.Manually
- Text.BranchTree.AheadBehind
@@ -509,6 +524,7 @@ This document shows the translation status of each locale file in the repository
- Text.Hotkeys.Global.ShowWorkspaceDropdownMenu
- Text.Hotkeys.Global.SwitchTab
- Text.Hotkeys.Global.Zoom
+- Text.Hotkeys.Repo.CreateBranch
- Text.Hotkeys.Repo.GoToChild
- Text.Hotkeys.Repo.GoToParent
- Text.Hotkeys.Repo.OpenCommandPalette
@@ -686,23 +702,9 @@ This document shows the translation status of each locale file in the repository
-### 
+### 
-
-Missing keys in ru_RU.axaml
-
-- Text.CommandPalette.Branches
-- Text.CommandPalette.BranchesAndTags
-- Text.CommandPalette.RepositoryActions
-- Text.CommandPalette.RevisionFiles
-- Text.ConfirmEmptyCommit.StageSelectedThenCommit
-- Text.Init.CommandTip
-- Text.Init.ErrorMessageTip
-- Text.Preferences.General.Use24Hours
-
-
-
-### 
+### 
Missing keys in ta_IN.axaml
@@ -714,6 +716,7 @@ This document shows the translation status of each locale file in the repository
- Text.AddToIgnore.Storage
- Text.App.Hide
- Text.App.ShowAll
+- Text.Apply.3Way
- Text.Askpass.Passphrase
- Text.Avatar.Load
- Text.Bisect
@@ -850,6 +853,7 @@ This document shows the translation status of each locale file in the repository
- Text.Hotkeys.Global.ShowWorkspaceDropdownMenu
- Text.Hotkeys.Global.SwitchTab
- Text.Hotkeys.Global.Zoom
+- Text.Hotkeys.Repo.CreateBranch
- Text.Hotkeys.Repo.GoToChild
- Text.Hotkeys.Repo.GoToParent
- Text.Hotkeys.Repo.OpenCommandPalette
@@ -994,7 +998,7 @@ This document shows the translation status of each locale file in the repository
-### 
+### 
Missing keys in uk_UA.axaml
@@ -1006,6 +1010,7 @@ This document shows the translation status of each locale file in the repository
- Text.AddToIgnore.Storage
- Text.App.Hide
- Text.App.ShowAll
+- Text.Apply.3Way
- Text.Askpass.Passphrase
- Text.Avatar.Load
- Text.Bisect
@@ -1138,6 +1143,7 @@ This document shows the translation status of each locale file in the repository
- Text.Hotkeys.Global.ShowWorkspaceDropdownMenu
- Text.Hotkeys.Global.SwitchTab
- Text.Hotkeys.Global.Zoom
+- Text.Hotkeys.Repo.CreateBranch
- Text.Hotkeys.Repo.GoToChild
- Text.Hotkeys.Repo.GoToParent
- Text.Hotkeys.Repo.OpenCommandPalette
diff --git a/src/App.axaml.cs b/src/App.axaml.cs
index a4c25193d..f9c6117cc 100644
--- a/src/App.axaml.cs
+++ b/src/App.axaml.cs
@@ -6,7 +6,6 @@
using System.Reflection;
using System.Text;
using System.Text.Json;
-using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
@@ -286,6 +285,8 @@ public static void SetTheme(string theme, string themeOverridesFile)
else
Models.CommitGraph.SetDefaultPens(overrides.GraphPenThickness);
+ Native.OS.UseMicaOnWindows11 = overrides.UseMicaOnWindows11;
+
app.Resources.MergedDictionaries.Add(resDic);
app._themeOverrides = resDic;
}
@@ -486,23 +487,7 @@ private static bool TryLaunchAsRebaseTodoEditor(string[] args, out int exitCode)
using var stream = File.OpenRead(jobsFile);
var collection = JsonSerializer.Deserialize(stream, JsonCodeGen.Default.InteractiveRebaseJobCollection);
- using var writer = new StreamWriter(file);
- foreach (var job in collection.Jobs)
- {
- var code = job.Action switch
- {
- Models.InteractiveRebaseAction.Pick => 'p',
- Models.InteractiveRebaseAction.Edit => 'e',
- Models.InteractiveRebaseAction.Reword => 'r',
- Models.InteractiveRebaseAction.Squash => 's',
- Models.InteractiveRebaseAction.Fixup => 'f',
- _ => 'd'
- };
- writer.WriteLine($"{code} {job.SHA}");
- }
-
- writer.Flush();
-
+ collection.WriteTodoList(file);
exitCode = 0;
return true;
}
@@ -533,27 +518,8 @@ private static bool TryLaunchAsRebaseMessageEditor(string[] args, out int exitCo
var onto = File.ReadAllText(ontoFile).Trim();
using var stream = File.OpenRead(jobsFile);
var collection = JsonSerializer.Deserialize(stream, JsonCodeGen.Default.InteractiveRebaseJobCollection);
- if (!collection.Onto.Equals(onto) || !collection.OrigHead.Equals(origHead))
- return true;
-
- var done = File.ReadAllText(doneFile).Trim().Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
- if (done.Length == 0)
- return true;
-
- var current = done[^1].Trim();
- var match = REG_REBASE_TODO().Match(current);
- if (!match.Success)
- return true;
-
- var sha = match.Groups[1].Value;
- foreach (var job in collection.Jobs)
- {
- if (job.SHA.StartsWith(sha))
- {
- File.WriteAllText(file, job.Message);
- break;
- }
- }
+ if (collection.Onto.StartsWith(onto, StringComparison.OrdinalIgnoreCase) && collection.OrigHead.StartsWith(origHead, StringComparison.OrdinalIgnoreCase))
+ collection.WriteCommitMessage(doneFile, file);
return true;
}
@@ -804,9 +770,6 @@ private string FixFontFamilyName(string input)
return trimmed.Count > 0 ? string.Join(',', trimmed) : string.Empty;
}
- [GeneratedRegex(@"^[a-z]+\s+([a-fA-F0-9]{4,40})(\s+.*)?$")]
- private static partial Regex REG_REBASE_TODO();
-
private Models.IpcChannel _ipcChannel = null;
private ViewModels.Launcher _launcher = null;
private ResourceDictionary _activeLocale = null;
diff --git a/src/Commands/Clone.cs b/src/Commands/Clone.cs
index b0323528c..ffd11bda9 100644
--- a/src/Commands/Clone.cs
+++ b/src/Commands/Clone.cs
@@ -14,7 +14,7 @@ public Clone(string ctx, string path, string url, string localName, string sshKe
builder.Append("clone --progress --verbose ");
if (!string.IsNullOrEmpty(extraArgs))
builder.Append(extraArgs).Append(' ');
- builder.Append(url).Append(' ');
+ builder.Append(url.Quoted()).Append(' ');
if (!string.IsNullOrEmpty(localName))
builder.Append(localName.Quoted());
diff --git a/src/Commands/Diff.cs b/src/Commands/Diff.cs
index 680aff63d..4d0cc72ac 100644
--- a/src/Commands/Diff.cs
+++ b/src/Commands/Diff.cs
@@ -12,7 +12,7 @@ public partial class Diff : Command
[GeneratedRegex(@"^@@ \-(\d+),?\d* \+(\d+),?\d* @@")]
private static partial Regex REG_INDICATOR();
- [GeneratedRegex(@"^index\s([0-9a-f]{6,40})\.\.([0-9a-f]{6,40})(\s[1-9]{6})?")]
+ [GeneratedRegex(@"^index\s([0-9a-f]{6,64})\.\.([0-9a-f]{6,64})(\s[1-9]{6})?")]
private static partial Regex REG_HASH_CHANGE();
private const string PREFIX_LFS_NEW = "+version https://git-lfs.github.com/spec/";
@@ -194,6 +194,7 @@ private void ParseLine(string line)
return;
}
+ _result.TextDiff.DeletedLines++;
_last = new Models.TextDiffLine(Models.TextDiffLineType.Deleted, line.Substring(1), _oldLine, 0);
_deleted.Add(_last);
_oldLine++;
@@ -207,6 +208,7 @@ private void ParseLine(string line)
return;
}
+ _result.TextDiff.AddedLines++;
_last = new Models.TextDiffLine(Models.TextDiffLineType.Added, line.Substring(1), 0, _newLine);
_added.Add(_last);
_newLine++;
diff --git a/src/Commands/IsBinary.cs b/src/Commands/IsBinary.cs
index 087e71c7b..9dbe05459 100644
--- a/src/Commands/IsBinary.cs
+++ b/src/Commands/IsBinary.cs
@@ -8,11 +8,11 @@ public partial class IsBinary : Command
[GeneratedRegex(@"^\-\s+\-\s+.*$")]
private static partial Regex REG_TEST();
- public IsBinary(string repo, string commit, string path)
+ public IsBinary(string repo, string revision, string path)
{
WorkingDirectory = repo;
Context = repo;
- Args = $"diff --no-color --no-ext-diff --numstat {Models.Commit.EmptyTreeSHA1} {commit} -- {path.Quoted()}";
+ Args = $"diff --no-color --no-ext-diff --numstat {Models.EmptyTreeHash.Guess(revision)} {revision} -- {path.Quoted()}";
RaiseError = false;
}
diff --git a/src/Commands/QueryCommitChildren.cs b/src/Commands/QueryCommitChildren.cs
index 6af0abb73..7e7e88877 100644
--- a/src/Commands/QueryCommitChildren.cs
+++ b/src/Commands/QueryCommitChildren.cs
@@ -24,7 +24,7 @@ public async Task> GetResultAsync()
foreach (var line in lines)
{
if (line.Contains(_commit))
- outs.Add(line.Substring(0, 40));
+ outs.Add(line.Substring(0, _commit.Length));
}
}
diff --git a/src/Commands/QueryStagedChangesWithAmend.cs b/src/Commands/QueryStagedChangesWithAmend.cs
index cff939e2e..78109ce6b 100644
--- a/src/Commands/QueryStagedChangesWithAmend.cs
+++ b/src/Commands/QueryStagedChangesWithAmend.cs
@@ -6,9 +6,9 @@ namespace SourceGit.Commands
{
public partial class QueryStagedChangesWithAmend : Command
{
- [GeneratedRegex(@"^:[\d]{6} ([\d]{6}) ([0-9a-f]{40}) [0-9a-f]{40} ([ADMT])\d{0,6}\t(.*)$")]
+ [GeneratedRegex(@"^:[\d]{6} ([\d]{6}) ([0-9a-f]{4,64}) [0-9a-f]{4,64} ([ADMT])\d{0,6}\t(.*)$")]
private static partial Regex REG_FORMAT1();
- [GeneratedRegex(@"^:[\d]{6} ([\d]{6}) ([0-9a-f]{40}) [0-9a-f]{40} ([RC])\d{0,6}\t(.*\t.*)$")]
+ [GeneratedRegex(@"^:[\d]{6} ([\d]{6}) ([0-9a-f]{4,64}) [0-9a-f]{4,64} ([RC])\d{0,6}\t(.*\t.*)$")]
private static partial Regex REG_FORMAT2();
public QueryStagedChangesWithAmend(string repo, string parent)
diff --git a/src/Models/Commit.cs b/src/Models/Commit.cs
index 60501ba4a..7f55e31f8 100644
--- a/src/Models/Commit.cs
+++ b/src/Models/Commit.cs
@@ -15,8 +15,6 @@ public enum CommitSearchMethod
public class Commit
{
- public const string EmptyTreeSHA1 = "4b825dc642cb6eb9a060e54bf8d69288fbee4904";
-
public string SHA { get; set; } = string.Empty;
public User Author { get; set; } = User.Invalid;
public ulong AuthorTime { get; set; } = 0;
@@ -33,6 +31,7 @@ public class Commit
public bool IsCommitterVisible => !Author.Equals(Committer) || AuthorTime != CommitterTime;
public bool IsCurrentHead => Decorators.Find(x => x.Type is DecoratorType.CurrentBranchHead or DecoratorType.CurrentCommitHead) != null;
public bool HasDecorators => Decorators.Count > 0;
+ public string FirstParentToCompare => Parents.Count > 0 ? $"{SHA}^" : EmptyTreeHash.Guess(SHA);
public string GetFriendlyName()
{
diff --git a/src/Models/DiffOption.cs b/src/Models/DiffOption.cs
index 0dc8bc31f..def59bedd 100644
--- a/src/Models/DiffOption.cs
+++ b/src/Models/DiffOption.cs
@@ -60,8 +60,7 @@ public DiffOption(Change change, bool isUnstaged)
///
public DiffOption(Commit commit, Change change)
{
- var baseRevision = commit.Parents.Count == 0 ? Commit.EmptyTreeSHA1 : $"{commit.SHA}^";
- _revisions.Add(baseRevision);
+ _revisions.Add(commit.FirstParentToCompare);
_revisions.Add(commit.SHA);
_path = change.Path;
_orgPath = change.OriginalPath;
@@ -74,8 +73,7 @@ public DiffOption(Commit commit, Change change)
///
public DiffOption(Commit commit, string file)
{
- var baseRevision = commit.Parents.Count == 0 ? Commit.EmptyTreeSHA1 : $"{commit.SHA}^";
- _revisions.Add(baseRevision);
+ _revisions.Add(commit.FirstParentToCompare);
_revisions.Add(commit.SHA);
_path = file;
}
@@ -88,7 +86,7 @@ public DiffOption(FileVersion ver)
{
if (string.IsNullOrEmpty(ver.OriginalPath))
{
- _revisions.Add(ver.HasParent ? $"{ver.SHA}^" : Commit.EmptyTreeSHA1);
+ _revisions.Add(ver.HasParent ? $"{ver.SHA}^" : EmptyTreeHash.Guess(ver.SHA));
_revisions.Add(ver.SHA);
_path = ver.Path;
}
@@ -111,14 +109,14 @@ public DiffOption(FileVersion start, FileVersion end)
{
if (start.Change.Index == ChangeState.Deleted)
{
- _revisions.Add(Commit.EmptyTreeSHA1);
+ _revisions.Add(EmptyTreeHash.Guess(end.SHA));
_revisions.Add(end.SHA);
_path = end.Path;
}
else if (end.Change.Index == ChangeState.Deleted)
{
_revisions.Add(start.SHA);
- _revisions.Add(Commit.EmptyTreeSHA1);
+ _revisions.Add(EmptyTreeHash.Guess(start.SHA));
_path = start.Path;
}
else if (!end.Path.Equals(start.Path, StringComparison.Ordinal))
diff --git a/src/Models/DiffResult.cs b/src/Models/DiffResult.cs
index df8f204c0..32fff76ce 100644
--- a/src/Models/DiffResult.cs
+++ b/src/Models/DiffResult.cs
@@ -55,6 +55,8 @@ public partial class TextDiff
{
public List Lines { get; set; } = new List();
public int MaxLineNumber = 0;
+ public int AddedLines { get; set; } = 0;
+ public int DeletedLines { get; set; } = 0;
public TextDiffSelection MakeSelection(int startLine, int endLine, bool isCombined, bool isOldSide)
{
diff --git a/src/Models/EmptyTreeHash.cs b/src/Models/EmptyTreeHash.cs
new file mode 100644
index 000000000..bf1445a0f
--- /dev/null
+++ b/src/Models/EmptyTreeHash.cs
@@ -0,0 +1,13 @@
+namespace SourceGit.Models
+{
+ public static class EmptyTreeHash
+ {
+ public static string Guess(string revision)
+ {
+ return revision.Length == 40 ? SHA1 : SHA256;
+ }
+
+ private const string SHA1 = "4b825dc642cb6eb9a060e54bf8d69288fbee4904";
+ private const string SHA256 = "6ef19b41225c5369f1c104d45d8d85efa9b057b53b14b4b9b939dd74decc5321";
+ }
+}
diff --git a/src/Models/InteractiveRebase.cs b/src/Models/InteractiveRebase.cs
index bae99ac52..ac7e29d4f 100644
--- a/src/Models/InteractiveRebase.cs
+++ b/src/Models/InteractiveRebase.cs
@@ -1,4 +1,7 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text.RegularExpressions;
namespace SourceGit.Models
{
@@ -34,10 +37,55 @@ public class InteractiveRebaseJob
public string Message { get; set; } = string.Empty;
}
- public class InteractiveRebaseJobCollection
+ public partial class InteractiveRebaseJobCollection
{
public string OrigHead { get; set; } = string.Empty;
public string Onto { get; set; } = string.Empty;
public List Jobs { get; set; } = new List();
+
+ public void WriteTodoList(string todoFile)
+ {
+ using var writer = new StreamWriter(todoFile);
+ foreach (var job in Jobs)
+ {
+ var code = job.Action switch
+ {
+ InteractiveRebaseAction.Pick => 'p',
+ InteractiveRebaseAction.Edit => 'e',
+ InteractiveRebaseAction.Reword => 'r',
+ InteractiveRebaseAction.Squash => 's',
+ InteractiveRebaseAction.Fixup => 'f',
+ _ => 'd'
+ };
+ writer.WriteLine($"{code} {job.SHA}");
+ }
+
+ writer.Flush();
+ }
+
+ public void WriteCommitMessage(string doneFile, string msgFile)
+ {
+ var done = File.ReadAllText(doneFile).Trim().Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
+ if (done.Length == 0)
+ return;
+
+ var current = done[^1].Trim();
+ var match = REG_REBASE_TODO().Match(current);
+ if (!match.Success)
+ return;
+
+ var sha = match.Groups[1].Value;
+ foreach (var job in Jobs)
+ {
+ if (job.SHA.StartsWith(sha))
+ {
+ File.WriteAllText(msgFile, job.Message);
+ return;
+ }
+ }
+ }
+
+ [GeneratedRegex(@"^[a-z]+\s+([a-fA-F0-9]{4,64})(\s+.*)?$")]
+ private static partial Regex REG_REBASE_TODO();
}
}
diff --git a/src/Models/Remote.cs b/src/Models/Remote.cs
index 1ef697052..18b57c414 100644
--- a/src/Models/Remote.cs
+++ b/src/Models/Remote.cs
@@ -64,14 +64,9 @@ public bool TryGetVisitURL(out string url)
{
url = null;
- if (URL.StartsWith("http", StringComparison.Ordinal))
+ if (URL.StartsWith("http://", StringComparison.Ordinal) || URL.StartsWith("https://", StringComparison.Ordinal))
{
- var uri = new Uri(URL.EndsWith(".git", StringComparison.Ordinal) ? URL.Substring(0, URL.Length - 4) : URL);
- if (uri.Port != 80 && uri.Port != 443)
- url = $"{uri.Scheme}://{uri.Host}:{uri.Port}{uri.LocalPath}";
- else
- url = $"{uri.Scheme}://{uri.Host}{uri.LocalPath}";
-
+ url = URL.EndsWith(".git", StringComparison.Ordinal) ? URL.Substring(0, URL.Length - 4) : URL;
return true;
}
@@ -97,7 +92,6 @@ public bool TryGetCreatePullRequestURL(out string url, string mergeBranch)
var uri = new Uri(baseURL);
var host = uri.Host;
- var route = uri.AbsolutePath.TrimStart('/');
var encodedBranch = HttpUtility.UrlEncode(mergeBranch);
if (host.Contains("github.com", StringComparison.Ordinal))
diff --git a/src/Models/Stash.cs b/src/Models/Stash.cs
index 4f5ad6922..93439a40a 100644
--- a/src/Models/Stash.cs
+++ b/src/Models/Stash.cs
@@ -10,5 +10,6 @@ public class Stash
public ulong Time { get; set; } = 0;
public string Message { get; set; } = "";
public string Subject => Message.Split('\n', 2)[0].Trim();
+ public string UntrackedParent => EmptyTreeHash.Guess(SHA);
}
}
diff --git a/src/Models/ThemeOverrides.cs b/src/Models/ThemeOverrides.cs
index ccd9f57e8..531cbccdd 100644
--- a/src/Models/ThemeOverrides.cs
+++ b/src/Models/ThemeOverrides.cs
@@ -9,6 +9,7 @@ public class ThemeOverrides
public Dictionary BasicColors { get; set; } = new Dictionary();
public double GraphPenThickness { get; set; } = 2;
public double OpacityForNotMergedCommits { get; set; } = 0.5;
+ public bool UseMicaOnWindows11 { get; set; } = true;
public List GraphColors { get; set; } = new List();
}
}
diff --git a/src/Native/OS.cs b/src/Native/OS.cs
index 159656f67..1044887a2 100644
--- a/src/Native/OS.cs
+++ b/src/Native/OS.cs
@@ -107,6 +107,12 @@ public static string ExternalDiffArgs
set;
} = string.Empty;
+ public static bool UseMicaOnWindows11
+ {
+ get => OperatingSystem.IsWindows() && OperatingSystem.IsWindowsVersionAtLeast(10, 0, 22000) && _enableMicaOnWindows11;
+ set => _enableMicaOnWindows11 = value;
+ }
+
public static bool UseSystemWindowFrame
{
get => OperatingSystem.IsLinux() && _enableSystemWindowFrame;
@@ -294,5 +300,6 @@ private static void UpdateGitVersion()
private static IBackend _backend = null;
private static string _gitExecutable = string.Empty;
private static bool _enableSystemWindowFrame = false;
+ private static bool _enableMicaOnWindows11 = true;
}
}
diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml
index 0866c1a0b..3514fbef6 100644
--- a/src/Resources/Locales/en_US.axaml
+++ b/src/Resources/Locales/en_US.axaml
@@ -24,6 +24,7 @@
Hide SourceGit
Show All
Patch
+ 3-Way Merge
Patch File:
Select .patch file to apply
Ignore whitespace changes
@@ -502,6 +503,7 @@
Commit staged changes
Commit and push staged changes
Stage all changes and commit
+ Create new branch
Fetch, starts directly
Dashboard mode (Default)
Goto child of selected commit
diff --git a/src/Resources/Locales/ru_RU.axaml b/src/Resources/Locales/ru_RU.axaml
index 0a566ac3b..629ac59dd 100644
--- a/src/Resources/Locales/ru_RU.axaml
+++ b/src/Resources/Locales/ru_RU.axaml
@@ -28,6 +28,7 @@
Скрыть SourceGit
Показать все
Исправить
+ Трехстороннее слияние
Файл заплатки:
Выберите файл .patch для применения
Игнорировать изменения пробелов
@@ -138,6 +139,10 @@
Адрес репозитория:
ЗАКРЫТЬ
Редактор
+ Ветки
+ Ветки и метки
+ Пользовательские действия репозитория
+ Ревизия файлов
Переключиться на эту ревизию
Применить эту ревизию (cherry-pick)
Применить несколько ревизий ...
@@ -281,6 +286,7 @@
ПРОДОЛЖИТЬ
Обнаружена пустая ревизия! Вы хотите продолжить (--allow-empty)?
Сформировать всё и зафиксировать ревизию
+ Сформировать выбранные и зафиксировать
Обнаружена пустая ревизия! Вы хотите продолжить (--allow-empty) или отложить всё, а затем зафиксировать ревизию?
Требуется перезапуск
Вы должны перезапустить приложение после применения изменений.
@@ -501,6 +507,7 @@
Зафиксировать сформированные изменения
Зафиксировать и выложить сформированные изменения
Сформировать все изменения и зафиксировать
+ Создать новую ветку
Извлечь (fetch), запускается сразу
Режим доски (по умолчанию)
К дочернему выбранной ревизии
@@ -523,6 +530,8 @@
Сформировать
Расформировать
Создать репозиторий
+ Вы действительно хотите запуститб команду «git init» по этому пути?
+ Не удалось открыть репозиторий. Причина:
Путь:
Выполняется частичный перенос ревизий (cherry-pick).
Обрабтка ревизии.
@@ -646,6 +655,7 @@
Показать наследника в деталях комментария
Показывать метки на графике
Длина темы ревизии
+ 24-часовой
Создать Github-подобный аватар по умолчанию
GIT
Включить автозавершение CRLF
diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml
index 4dc0d07a4..3f1b8c55b 100644
--- a/src/Resources/Locales/zh_CN.axaml
+++ b/src/Resources/Locales/zh_CN.axaml
@@ -28,6 +28,7 @@
隐藏 SourceGit
显示所有窗口
应用补丁(apply)
+ 尝试三路合并
补丁文件 :
选择补丁文件
忽略空白符号
@@ -506,6 +507,7 @@
提交暂存区更改
提交暂存区更改并推送
自动暂存全部变更并提交
+ 新建分支
拉取 (fetch) 远程变更
切换左边栏为分支/标签等显示模式(默认)
前往选中提交的子提交
diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml
index 8d3659b0d..fa4e3d2bd 100644
--- a/src/Resources/Locales/zh_TW.axaml
+++ b/src/Resources/Locales/zh_TW.axaml
@@ -28,6 +28,7 @@
隱藏 SourceGit
顯示所有
套用修補檔 (apply patch)
+ 嘗試三路合併
修補檔:
選擇修補檔
忽略空白符號
@@ -506,6 +507,7 @@
提交暫存區變更
提交暫存區變更並推送
自動暫存全部變更並提交
+ 新增分支
提取 (fetch) 遠端的變更
切換左邊欄為分支/標籤等顯示模式 (預設)
前往所選提交的子提交
diff --git a/src/Resources/Styles.axaml b/src/Resources/Styles.axaml
index 3167a8c26..366325cdc 100644
--- a/src/Resources/Styles.axaml
+++ b/src/Resources/Styles.axaml
@@ -1472,7 +1472,7 @@
Name="PART_searchTextBox"
Width="265" Height="28"
Margin="0,0,0,0"
- CornerRadius="2"
+ CornerRadius="3"
Text="{Binding SearchPattern, RelativeSource={RelativeSource TemplatedParent}}">
diff --git a/src/ViewModels/Apply.cs b/src/ViewModels/Apply.cs
index 3eab5ef7a..3578c12f2 100644
--- a/src/ViewModels/Apply.cs
+++ b/src/ViewModels/Apply.cs
@@ -26,6 +26,12 @@ public Models.ApplyWhiteSpaceMode SelectedWhiteSpaceMode
set;
}
+ public bool ThreeWayMerge
+ {
+ get;
+ set;
+ }
+
public Apply(Repository repo)
{
_repo = repo;
@@ -49,7 +55,8 @@ public override async Task Sure()
var log = _repo.CreateLog("Apply Patch");
Use(log);
- var succ = await new Commands.Apply(_repo.FullPath, _patchFile, _ignoreWhiteSpace, SelectedWhiteSpaceMode.Arg, null)
+ var extra = ThreeWayMerge ? "--3way" : string.Empty;
+ var succ = await new Commands.Apply(_repo.FullPath, _patchFile, _ignoreWhiteSpace, SelectedWhiteSpaceMode.Arg, extra)
.Use(log)
.ExecAsync();
diff --git a/src/ViewModels/Checkout.cs b/src/ViewModels/Checkout.cs
index ee760331f..aca5cb1ef 100644
--- a/src/ViewModels/Checkout.cs
+++ b/src/ViewModels/Checkout.cs
@@ -4,9 +4,9 @@ namespace SourceGit.ViewModels
{
public class Checkout : Popup
{
- public string Branch
+ public string BranchName
{
- get;
+ get => _branch.Name;
}
public bool DiscardLocalChanges
@@ -15,24 +15,20 @@ public bool DiscardLocalChanges
set;
}
- public Checkout(Repository repo, string branch)
+ public Checkout(Repository repo, Models.Branch branch)
{
_repo = repo;
- Branch = branch;
+ _branch = branch;
DiscardLocalChanges = false;
}
- public override bool CanStartDirectly()
- {
- return _repo.LocalChangesCount == 0;
- }
-
public override async Task Sure()
{
using var lockWatcher = _repo.LockWatcher();
- ProgressDescription = $"Checkout '{Branch}' ...";
+ var branchName = BranchName;
+ ProgressDescription = $"Checkout '{branchName}' ...";
- var log = _repo.CreateLog($"Checkout '{Branch}'");
+ var log = _repo.CreateLog($"Checkout '{branchName}'");
Use(log);
if (_repo.CurrentBranch is { IsDetachedHead: true })
@@ -70,7 +66,7 @@ public override async Task Sure()
succ = await new Commands.Checkout(_repo.FullPath)
.Use(log)
- .BranchAsync(Branch, DiscardLocalChanges);
+ .BranchAsync(branchName, DiscardLocalChanges);
if (succ)
{
@@ -80,21 +76,19 @@ public override async Task Sure()
await new Commands.Stash(_repo.FullPath)
.Use(log)
.PopAsync("stash@{0}");
+
+ _repo.RefreshAfterCheckoutBranch(_branch);
+ }
+ else
+ {
+ _repo.MarkWorkingCopyDirtyManually();
}
log.Complete();
-
- var b = _repo.Branches.Find(x => x.IsLocal && x.Name == Branch);
- if (b != null && _repo.HistoryFilterMode == Models.FilterMode.Included)
- _repo.SetBranchFilterMode(b, Models.FilterMode.Included, false, false);
-
- _repo.MarkBranchesDirtyManually();
-
- ProgressDescription = "Waiting for branch updated...";
- await Task.Delay(400);
return succ;
}
private readonly Repository _repo = null;
+ private readonly Models.Branch _branch = null;
}
}
diff --git a/src/ViewModels/CheckoutAndFastForward.cs b/src/ViewModels/CheckoutAndFastForward.cs
index 197701c33..120d6c4ad 100644
--- a/src/ViewModels/CheckoutAndFastForward.cs
+++ b/src/ViewModels/CheckoutAndFastForward.cs
@@ -80,17 +80,19 @@ public override async Task Sure()
await new Commands.Stash(_repo.FullPath)
.Use(log)
.PopAsync("stash@{0}");
- }
-
- log.Complete();
- if (_repo.HistoryFilterMode == Models.FilterMode.Included)
- _repo.SetBranchFilterMode(LocalBranch, Models.FilterMode.Included, false, false);
+ LocalBranch.Behind.Clear();
+ LocalBranch.Head = RemoteBranch.Head;
+ LocalBranch.CommitterDate = RemoteBranch.CommitterDate;
- _repo.MarkBranchesDirtyManually();
+ _repo.RefreshAfterCheckoutBranch(LocalBranch);
+ }
+ else
+ {
+ _repo.MarkWorkingCopyDirtyManually();
+ }
- ProgressDescription = "Waiting for branch updated...";
- await Task.Delay(400);
+ log.Complete();
return succ;
}
diff --git a/src/ViewModels/CommitDetail.cs b/src/ViewModels/CommitDetail.cs
index 8cffb0ae9..6ccfba0ae 100644
--- a/src/ViewModels/CommitDetail.cs
+++ b/src/ViewModels/CommitDetail.cs
@@ -240,8 +240,13 @@ public async Task SaveChangesAsPatchAsync(List changes, string sa
if (_commit == null)
return;
- var baseRevision = _commit.Parents.Count == 0 ? Models.Commit.EmptyTreeSHA1 : _commit.Parents[0];
- var succ = await Commands.SaveChangesAsPatch.ProcessRevisionCompareChangesAsync(_repo.FullPath, changes, baseRevision, _commit.SHA, saveTo);
+ var succ = await Commands.SaveChangesAsPatch.ProcessRevisionCompareChangesAsync(
+ _repo.FullPath,
+ changes,
+ _commit.FirstParentToCompare,
+ _commit.SHA,
+ saveTo);
+
if (succ)
App.SendNotification(_repo.FullPath, App.Text("SaveAsPatchSuccess"));
}
@@ -535,8 +540,7 @@ private void Refresh()
Task.Run(async () =>
{
- var parent = _commit.Parents.Count == 0 ? Models.Commit.EmptyTreeSHA1 : $"{_commit.SHA}^";
- var cmd = new Commands.CompareRevisions(_repo.FullPath, parent, _commit.SHA) { CancellationToken = token };
+ var cmd = new Commands.CompareRevisions(_repo.FullPath, _commit.FirstParentToCompare, _commit.SHA) { CancellationToken = token };
var changes = await cmd.ReadAsync().ConfigureAwait(false);
var visible = changes;
if (!string.IsNullOrWhiteSpace(_searchChangeFilter))
@@ -757,7 +761,7 @@ private async Task SetViewingCommitAsync(Models.Object file)
[GeneratedRegex(@"\b(https?://|ftp://)[\w\d\._/\-~%@()+:?&=#!]*[\w\d/]")]
private static partial Regex REG_URL_FORMAT();
- [GeneratedRegex(@"\b([0-9a-fA-F]{6,40})\b")]
+ [GeneratedRegex(@"\b([0-9a-fA-F]{6,64})\b")]
private static partial Regex REG_SHA_FORMAT();
[GeneratedRegex(@"`.*?`")]
diff --git a/src/ViewModels/CreateBranch.cs b/src/ViewModels/CreateBranch.cs
index b5d4d7125..832f56268 100644
--- a/src/ViewModels/CreateBranch.cs
+++ b/src/ViewModels/CreateBranch.cs
@@ -58,6 +58,8 @@ public CreateBranch(Repository repo, Models.Branch branch)
{
_repo = repo;
_baseOnRevision = branch.Head;
+ _committerDate = branch.CommitterDate;
+ _head = branch.Head;
if (!branch.IsLocal)
Name = branch.Name;
@@ -70,6 +72,8 @@ public CreateBranch(Repository repo, Models.Commit commit)
{
_repo = repo;
_baseOnRevision = commit.SHA;
+ _committerDate = commit.CommitterTime;
+ _head = commit.SHA;
BasedOn = commit;
DiscardLocalChanges = false;
@@ -79,6 +83,8 @@ public CreateBranch(Repository repo, Models.Tag tag)
{
_repo = repo;
_baseOnRevision = tag.SHA;
+ _committerDate = tag.CreatorDate;
+ _head = tag.SHA;
BasedOn = tag;
DiscardLocalChanges = false;
@@ -125,6 +131,15 @@ public override async Task Sure()
}
}
+ Models.Branch created = new()
+ {
+ Name = _name,
+ FullName = $"refs/heads/{_name}",
+ CommitterDate = _committerDate,
+ Head = _head,
+ IsLocal = true,
+ };
+
bool succ;
if (CheckoutAfterCreated && !_repo.IsBare)
{
@@ -168,43 +183,33 @@ public override async Task Sure()
.CreateAsync(_baseOnRevision, _allowOverwrite);
}
- if (succ && BasedOn is Models.Branch { IsLocal: false } basedOn && _name.Equals(basedOn.Name, StringComparison.Ordinal))
+ if (succ)
{
- await new Commands.Branch(_repo.FullPath, _name)
+ if (BasedOn is Models.Branch { IsLocal: false } basedOn && _name.Equals(basedOn.Name, StringComparison.Ordinal))
+ {
+ await new Commands.Branch(_repo.FullPath, _name)
.Use(log)
.SetUpstreamAsync(basedOn);
- }
-
- log.Complete();
-
- if (succ && CheckoutAfterCreated)
- {
- var fake = new Models.Branch() { IsLocal = true, FullName = $"refs/heads/{_name}" };
- if (BasedOn is Models.Branch { IsLocal: false } based)
- fake.Upstream = based.FullName;
- var folderEndIdx = fake.FullName.LastIndexOf('/');
- if (folderEndIdx > 10)
- _repo.UIStates.ExpandedBranchNodesInSideBar.Add(fake.FullName.Substring(0, folderEndIdx));
+ created.Upstream = basedOn.FullName;
+ }
- if (_repo.HistoryFilterMode == Models.FilterMode.Included)
- _repo.SetBranchFilterMode(fake, Models.FilterMode.Included, false, false);
+ _repo.RefreshAfterCreateBranch(created, CheckoutAfterCreated);
}
-
- _repo.MarkBranchesDirtyManually();
-
- if (CheckoutAfterCreated)
+ else
{
- ProgressDescription = "Waiting for branch updated...";
- await Task.Delay(400);
+ _repo.MarkWorkingCopyDirtyManually();
}
+ log.Complete();
return true;
}
private readonly Repository _repo = null;
- private string _name = null;
private readonly string _baseOnRevision = null;
+ private readonly ulong _committerDate = 0;
+ private readonly string _head = string.Empty;
+ private string _name = null;
private bool _allowOverwrite = false;
}
}
diff --git a/src/ViewModels/EditRepositoryNode.cs b/src/ViewModels/EditRepositoryNode.cs
index d7176c786..cb83668e7 100644
--- a/src/ViewModels/EditRepositoryNode.cs
+++ b/src/ViewModels/EditRepositoryNode.cs
@@ -6,17 +6,14 @@ namespace SourceGit.ViewModels
{
public class EditRepositoryNode : Popup
{
- public string Id
+ public string Target
{
- get => _id;
- set => SetProperty(ref _id, value);
+ get;
}
- [Required(ErrorMessage = "Name is required!")]
- public string Name
+ public bool IsRepository
{
- get => _name;
- set => SetProperty(ref _name, value, true);
+ get;
}
public List Bookmarks
@@ -24,26 +21,27 @@ public List Bookmarks
get;
}
- public int Bookmark
+ [Required(ErrorMessage = "Name is required!")]
+ public string Name
{
- get => _bookmark;
- set => SetProperty(ref _bookmark, value);
+ get => _name;
+ set => SetProperty(ref _name, value, true);
}
- public bool IsRepository
+ public int Bookmark
{
- get => _isRepository;
- set => SetProperty(ref _isRepository, value);
+ get => _bookmark;
+ set => SetProperty(ref _bookmark, value);
}
public EditRepositoryNode(RepositoryNode node)
{
_node = node;
- _id = node.Id;
_name = node.Name;
- _isRepository = node.IsRepository;
_bookmark = node.Bookmark;
+ Target = node.IsRepository ? node.Id : node.Name;
+ IsRepository = node.IsRepository;
Bookmarks = new List();
for (var i = 0; i < Models.Bookmarks.Brushes.Length; i++)
Bookmarks.Add(i);
@@ -65,9 +63,7 @@ public override Task Sure()
}
private RepositoryNode _node = null;
- private string _id = null;
private string _name = null;
- private bool _isRepository = false;
private int _bookmark = 0;
}
}
diff --git a/src/ViewModels/FileHistories.cs b/src/ViewModels/FileHistories.cs
index 722e450f4..17d1fc05d 100644
--- a/src/ViewModels/FileHistories.cs
+++ b/src/ViewModels/FileHistories.cs
@@ -2,10 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
-
-using Avalonia.Collections;
using Avalonia.Threading;
-
using CommunityToolkit.Mvvm.ComponentModel;
namespace SourceGit.ViewModels
@@ -17,15 +14,27 @@ public class FileHistoriesRevisionFile(string path, object content = null, bool
public bool CanOpenWithDefaultEditor { get; set; } = canOpenWithDefaultEditor;
}
+ public class FileHistoriesSingleRevisionViewMode
+ {
+ public bool IsDiff
+ {
+ get;
+ set;
+ } = true;
+ }
+
public class FileHistoriesSingleRevision : ObservableObject
{
public bool IsDiffMode
{
- get => _isDiffMode;
+ get => _viewMode.IsDiff;
set
{
- if (SetProperty(ref _isDiffMode, value))
+ if (_viewMode.IsDiff != value)
+ {
+ _viewMode.IsDiff = value;
RefreshViewContent();
+ }
}
}
@@ -35,17 +44,24 @@ public object ViewContent
set => SetProperty(ref _viewContent, value);
}
- public FileHistoriesSingleRevision(string repo, Models.FileVersion revision, bool prevIsDiffMode)
+ public FileHistoriesSingleRevision(string repo, Models.FileVersion revision, FileHistoriesSingleRevisionViewMode viewMode)
{
_repo = repo;
_file = revision.Path;
_revision = revision;
- _isDiffMode = prevIsDiffMode;
+ _viewMode = viewMode;
_viewContent = null;
RefreshViewContent();
}
+ public void SetRevision(Models.FileVersion revision)
+ {
+ _file = revision.Path;
+ _revision = revision;
+ RefreshViewContent();
+ }
+
public async Task ResetToSelectedRevisionAsync()
{
return await new Commands.Checkout(_repo)
@@ -72,7 +88,7 @@ await Commands.SaveRevisionFile
private void RefreshViewContent()
{
- if (_isDiffMode)
+ if (_viewMode.IsDiff)
{
ViewContent = new DiffContext(_repo, new(_revision), _viewContent as DiffContext);
return;
@@ -155,7 +171,7 @@ private async Task
-
+
+
+
diff --git a/src/Views/BranchTree.axaml.cs b/src/Views/BranchTree.axaml.cs
index 651133402..367e54240 100644
--- a/src/Views/BranchTree.axaml.cs
+++ b/src/Views/BranchTree.axaml.cs
@@ -887,37 +887,45 @@ private ContextMenu CreateContextMenuForLocalBranch(ViewModels.Repository repo,
}
}
- var rename = new MenuItem();
- rename.Header = App.Text("BranchCM.Rename", branch.Name);
- rename.Icon = App.CreateMenuIcon("Icons.Rename");
- rename.Click += (_, e) =>
+ if (!branch.IsDetachedHead)
{
- if (repo.CanCreatePopup())
- repo.ShowPopup(new ViewModels.RenameBranch(repo, branch));
- e.Handled = true;
- };
+ var editDescription = new MenuItem();
+ editDescription.Header = App.Text("BranchCM.EditDescription", branch.Name);
+ editDescription.Icon = App.CreateMenuIcon("Icons.Edit");
+ editDescription.Click += async (_, e) =>
+ {
+ var desc = await new Commands.Config(repo.FullPath).GetAsync($"branch.{branch.Name}.description");
+ if (repo.CanCreatePopup())
+ repo.ShowPopup(new ViewModels.EditBranchDescription(repo, branch, desc));
+ e.Handled = true;
+ };
- var editDescription = new MenuItem();
- editDescription.Header = App.Text("BranchCM.EditDescription", branch.Name);
- editDescription.Icon = App.CreateMenuIcon("Icons.Edit");
- editDescription.Click += async (_, e) =>
- {
- var desc = await new Commands.Config(repo.FullPath).GetAsync($"branch.{branch.Name}.description");
- if (repo.CanCreatePopup())
- repo.ShowPopup(new ViewModels.EditBranchDescription(repo, branch, desc));
- e.Handled = true;
- };
+ var rename = new MenuItem();
+ rename.Header = App.Text("BranchCM.Rename", branch.Name);
+ rename.Icon = App.CreateMenuIcon("Icons.Rename");
+ rename.Click += (_, e) =>
+ {
+ if (repo.CanCreatePopup())
+ repo.ShowPopup(new ViewModels.RenameBranch(repo, branch));
+ e.Handled = true;
+ };
- var delete = new MenuItem();
- delete.Header = App.Text("BranchCM.Delete", branch.Name);
- delete.Icon = App.CreateMenuIcon("Icons.Clear");
- delete.IsEnabled = !branch.IsCurrent;
- delete.Click += (_, e) =>
- {
- if (repo.CanCreatePopup())
- repo.ShowPopup(new ViewModels.DeleteBranch(repo, branch));
- e.Handled = true;
- };
+ var delete = new MenuItem();
+ delete.Header = App.Text("BranchCM.Delete", branch.Name);
+ delete.Icon = App.CreateMenuIcon("Icons.Clear");
+ delete.IsEnabled = !branch.IsCurrent;
+ delete.Click += (_, e) =>
+ {
+ if (repo.CanCreatePopup())
+ repo.ShowPopup(new ViewModels.DeleteBranch(repo, branch));
+ e.Handled = true;
+ };
+
+ menu.Items.Add(new MenuItem() { Header = "-" });
+ menu.Items.Add(editDescription);
+ menu.Items.Add(rename);
+ menu.Items.Add(delete);
+ }
var createBranch = new MenuItem();
createBranch.Icon = App.CreateMenuIcon("Icons.Branch.Add");
@@ -939,10 +947,6 @@ private ContextMenu CreateContextMenuForLocalBranch(ViewModels.Repository repo,
e.Handled = true;
};
- menu.Items.Add(new MenuItem() { Header = "-" });
- menu.Items.Add(editDescription);
- menu.Items.Add(rename);
- menu.Items.Add(delete);
menu.Items.Add(new MenuItem() { Header = "-" });
menu.Items.Add(createBranch);
menu.Items.Add(createTag);
diff --git a/src/Views/ChangeSubmoduleUrl.axaml b/src/Views/ChangeSubmoduleUrl.axaml
index a12a04890..a1d6cef02 100644
--- a/src/Views/ChangeSubmoduleUrl.axaml
+++ b/src/Views/ChangeSubmoduleUrl.axaml
@@ -3,6 +3,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:SourceGit.ViewModels"
+ xmlns:v="using:SourceGit.Views"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.ChangeSubmoduleUrl"
x:DataType="vm:ChangeSubmoduleUrl">
@@ -34,9 +35,20 @@
+ Text="{Binding Url, Mode=TwoWay}">
+
+
+
+
+
+
+
+
diff --git a/src/Views/Checkout.axaml b/src/Views/Checkout.axaml
index 0d2f2ecae..26fafe815 100644
--- a/src/Views/Checkout.axaml
+++ b/src/Views/Checkout.axaml
@@ -30,7 +30,7 @@
Text="{DynamicResource Text.Checkout.Target}"/>
-
+
@@ -26,7 +27,18 @@
+ Text="{Binding Remote, Mode=TwoWay}">
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
diff --git a/src/Views/RepositoryToolbar.axaml b/src/Views/RepositoryToolbar.axaml
index f857ffee6..72ebb9dc5 100644
--- a/src/Views/RepositoryToolbar.axaml
+++ b/src/Views/RepositoryToolbar.axaml
@@ -80,11 +80,7 @@
VerticalAlignment="Center"
Fill="{DynamicResource Brush.Border2}"/>
-
-
-
-
-
+
diff --git a/src/Views/SetSubmoduleBranch.axaml b/src/Views/SetSubmoduleBranch.axaml
index 2d5260e76..718fad7fd 100644
--- a/src/Views/SetSubmoduleBranch.axaml
+++ b/src/Views/SetSubmoduleBranch.axaml
@@ -43,7 +43,7 @@
diff --git a/src/Views/StashSubjectPresenter.cs b/src/Views/StashSubjectPresenter.cs
index 8f47a350e..e9c1bac91 100644
--- a/src/Views/StashSubjectPresenter.cs
+++ b/src/Views/StashSubjectPresenter.cs
@@ -127,7 +127,7 @@ protected override Size MeasureOverride(Size availableSize)
[GeneratedRegex(@"^On ([^\s]+)\: ")]
private static partial Regex REG_KEYWORD_ON();
- [GeneratedRegex(@"^WIP on ([^\s]+)\: ([a-f0-9]{6,40}) ")]
+ [GeneratedRegex(@"^WIP on ([^\s]+)\: ([a-f0-9]{6,64}) ")]
private static partial Regex REG_KEYWORD_WIP();
}
}