mirror of
https://github.com/sourcegit-scm/sourcegit.git
synced 2024-12-25 21:07:20 -08:00
Compare commits
7 commits
fdf30aa7cc
...
88cec05e67
Author | SHA1 | Date | |
---|---|---|---|
|
88cec05e67 | ||
|
a715143a16 | ||
|
9cb85081ab | ||
|
c72506d939 | ||
|
d50b2c0298 | ||
|
dc49c1bf76 | ||
|
2e6eca26f7 |
18 changed files with 232 additions and 40 deletions
|
@ -47,7 +47,7 @@
|
|||
|
||||
## Translation Status
|
||||
|
||||
[![en_US](https://img.shields.io/badge/en__US-100%25-brightgreen)](TRANSLATION.md) [![de__DE](https://img.shields.io/badge/de__DE-95.63%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-100.00%25-brightgreen)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-87.34%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-90.39%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-99.56%25-yellow)](TRANSLATION.md) [![zh__CN](https://img.shields.io/badge/zh__CN-100.00%25-brightgreen)](TRANSLATION.md) [![zh__TW](https://img.shields.io/badge/zh__TW-100.00%25-brightgreen)](TRANSLATION.md)
|
||||
[![en_US](https://img.shields.io/badge/en__US-100%25-brightgreen)](TRANSLATION.md) [![de__DE](https://img.shields.io/badge/de__DE-94.94%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-99.28%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-86.71%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-89.74%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-98.84%25-yellow)](TRANSLATION.md) [![zh__CN](https://img.shields.io/badge/zh__CN-100.00%25-brightgreen)](TRANSLATION.md) [![zh__TW](https://img.shields.io/badge/zh__TW-100.00%25-brightgreen)](TRANSLATION.md)
|
||||
|
||||
## How to Use
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
### de_DE.axaml: 95.63%
|
||||
### de_DE.axaml: 94.94%
|
||||
|
||||
|
||||
<details>
|
||||
|
@ -22,9 +22,14 @@
|
|||
- Text.Configure.OpenAI
|
||||
- Text.Configure.OpenAI.Prefered
|
||||
- Text.Configure.OpenAI.Prefered.Tip
|
||||
- Text.Diff.SaveAsPatch
|
||||
- Text.Diff.VisualLines.All
|
||||
- Text.ExecuteCustomAction
|
||||
- Text.ExecuteCustomAction.Name
|
||||
- Text.Hotkeys.Repo.CreateBranchOnCommit
|
||||
- Text.Hotkeys.Repo.Fetch
|
||||
- Text.Hotkeys.Repo.Pull
|
||||
- Text.Hotkeys.Repo.Push
|
||||
- Text.IssueLinkCM.OpenInBrowser
|
||||
- Text.IssueLinkCM.CopyLink
|
||||
- Text.Preference.AI.AnalyzeDiffPrompt
|
||||
|
@ -37,17 +42,21 @@
|
|||
|
||||
</details>
|
||||
|
||||
### es_ES.axaml: 100.00%
|
||||
### es_ES.axaml: 99.28%
|
||||
|
||||
|
||||
<details>
|
||||
<summary>Missing Keys</summary>
|
||||
|
||||
|
||||
- Text.Diff.SaveAsPatch
|
||||
- Text.Hotkeys.Repo.CreateBranchOnCommit
|
||||
- Text.Hotkeys.Repo.Fetch
|
||||
- Text.Hotkeys.Repo.Pull
|
||||
- Text.Hotkeys.Repo.Push
|
||||
|
||||
</details>
|
||||
|
||||
### fr_FR.axaml: 87.34%
|
||||
### fr_FR.axaml: 86.71%
|
||||
|
||||
|
||||
<details>
|
||||
|
@ -92,6 +101,7 @@
|
|||
- Text.ConventionalCommit.ShortDescription
|
||||
- Text.ConventionalCommit.Type
|
||||
- Text.Diff.IgnoreWhitespace
|
||||
- Text.Diff.SaveAsPatch
|
||||
- Text.Diff.VisualLines.All
|
||||
- Text.Discard.IncludeIgnored
|
||||
- Text.ExecuteCustomAction
|
||||
|
@ -103,7 +113,11 @@
|
|||
- Text.Histories.Tips.MacOS
|
||||
- Text.Histories.Tips.Prefix
|
||||
- Text.Hotkeys.Repo.CommitWithAutoStage
|
||||
- Text.Hotkeys.Repo.CreateBranchOnCommit
|
||||
- Text.Hotkeys.Repo.DiscardSelected
|
||||
- Text.Hotkeys.Repo.Fetch
|
||||
- Text.Hotkeys.Repo.Pull
|
||||
- Text.Hotkeys.Repo.Push
|
||||
- Text.IssueLinkCM.OpenInBrowser
|
||||
- Text.IssueLinkCM.CopyLink
|
||||
- Text.MoveRepositoryNode
|
||||
|
@ -143,7 +157,7 @@
|
|||
|
||||
</details>
|
||||
|
||||
### pt_BR.axaml: 90.39%
|
||||
### pt_BR.axaml: 89.74%
|
||||
|
||||
|
||||
<details>
|
||||
|
@ -190,6 +204,7 @@
|
|||
- Text.ConventionalCommit.ShortDescription
|
||||
- Text.ConventionalCommit.Type
|
||||
- Text.CopyAllText
|
||||
- Text.Diff.SaveAsPatch
|
||||
- Text.Diff.VisualLines.All
|
||||
- Text.Discard.IncludeIgnored
|
||||
- Text.ExecuteCustomAction
|
||||
|
@ -197,6 +212,10 @@
|
|||
- Text.FileHistory.FileContent
|
||||
- Text.FileHistory.FileChange
|
||||
- Text.GitLFS.Locks.OnlyMine
|
||||
- Text.Hotkeys.Repo.CreateBranchOnCommit
|
||||
- Text.Hotkeys.Repo.Fetch
|
||||
- Text.Hotkeys.Repo.Pull
|
||||
- Text.Hotkeys.Repo.Push
|
||||
- Text.IssueLinkCM.OpenInBrowser
|
||||
- Text.IssueLinkCM.CopyLink
|
||||
- Text.MoveRepositoryNode
|
||||
|
@ -218,13 +237,18 @@
|
|||
|
||||
</details>
|
||||
|
||||
### ru_RU.axaml: 99.56%
|
||||
### ru_RU.axaml: 98.84%
|
||||
|
||||
|
||||
<details>
|
||||
<summary>Missing Keys</summary>
|
||||
|
||||
- Text.Diff.SaveAsPatch
|
||||
- Text.Diff.VisualLines.All
|
||||
- Text.Hotkeys.Repo.CreateBranchOnCommit
|
||||
- Text.Hotkeys.Repo.Fetch
|
||||
- Text.Hotkeys.Repo.Pull
|
||||
- Text.Hotkeys.Repo.Push
|
||||
- Text.IssueLinkCM.OpenInBrowser
|
||||
- Text.IssueLinkCM.CopyLink
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace SourceGit.Commands
|
|||
{
|
||||
public static class SaveChangesAsPatch
|
||||
{
|
||||
public static bool Exec(string repo, List<Models.Change> changes, bool isUnstaged, string saveTo)
|
||||
public static bool ProcessLocalChanges(string repo, List<Models.Change> changes, bool isUnstaged, string saveTo)
|
||||
{
|
||||
using (var sw = File.Create(saveTo))
|
||||
{
|
||||
|
@ -23,6 +23,20 @@ namespace SourceGit.Commands
|
|||
return true;
|
||||
}
|
||||
|
||||
public static bool ProcessRevisionCompareChanges(string repo, List<Models.Change> changes, string baseRevision, string targetRevision, string saveTo)
|
||||
{
|
||||
using (var sw = File.Create(saveTo))
|
||||
{
|
||||
foreach (var change in changes)
|
||||
{
|
||||
if (!ProcessSingleChange(repo, new Models.DiffOption(baseRevision, targetRevision, change), sw))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool ProcessSingleChange(string repo, Models.DiffOption opt, FileStream writer)
|
||||
{
|
||||
var starter = new ProcessStartInfo();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<ResourceDictionary xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<StreamGeometry x:Key="Icons.Action">M41 512c0-128 46-241 138-333C271 87 384 41 512 41s241 46 333 138c92 92 138 205 138 333s-46 241-138 333c-92 92-205 138-333 138s-241-46-333-138C87 753 41 640 41 512zm87 0c0 108 36 195 113 271s164 113 271 113c108 0 195-36 271-113s113-164 113-271-36-195-113-271c-77-77-164-113-271-113-108 0-195 36-271 113C164 317 128 404 128 512zm256 148V292l195 113L768 512l-195 113-195 113v-77zm148-113-61 36V440l61 36 61 36-61 36z</StreamGeometry>
|
||||
<StreamGeometry x:Key="Icons.AIAssist">M951 419a255 255 0 00-22-209 258 258 0 00-278-124A259 259 0 00213 178a255 255 0 00-171 124 258 258 0 0032 303 255 255 0 0022 210 258 258 0 00278 124A255 255 0 00566 1024a258 258 0 00246-179 256 256 0 00171-124 258 258 0 00-32-302zM566 957a191 191 0 01-123-44l6-3 204-118a34 34 0 0017-29v-287l86 50a3 3 0 012 2v238a192 192 0 01-192 192zM154 781a191 191 0 01-23-129l6 4 204 118a33 33 0 0033 0l249-144v99a3 3 0 01-1 3L416 851a192 192 0 01-262-70zM100 337a191 191 0 01101-84V495a33 33 0 0017 29l248 143-86 50a3 3 0 01-3 0l-206-119A192 192 0 01100 336zm708 164-249-145L645 307a3 3 0 013 0l206 119a192 192 0 01-29 346v-242a34 34 0 00-17-28zm86-129-6-4-204-119a33 33 0 00-33 0L401 394V294a3 3 0 011-3l206-119a192 192 0 01285 199zm-539 176-86-50a3 3 0 01-2-2V259a192 192 0 01315-147l-6 3-204 118a34 34 0 00-17 29zm47-101 111-64 111 64v128l-111 64-111-64z</StreamGeometry>
|
||||
<StreamGeometry x:Key="Icons.AIAssist">M304 464a128 128 0 01128-128c71 0 128 57 128 128v224a32 32 0 01-64 0V592h-128v95a32 32 0 01-64 0v-224zm64 1v64h128v-64a64 64 0 00-64-64c-35 0-64 29-64 64zM688 337c18 0 32 14 32 32v319a32 32 0 01-32 32c-18 0-32-14-32-32v-319a32 32 0 0132-32zM84 911l60-143A446 446 0 0164 512C64 265 265 64 512 64s448 201 448 448-201 448-448 448c-54 0-105-9-153-27l-242 22a32 32 0 01-32-44zm133-150-53 126 203-18 13 5c41 15 85 23 131 23 212 0 384-172 384-384S724 128 512 128 128 300 128 512c0 82 26 157 69 220l20 29z</StreamGeometry>
|
||||
<StreamGeometry x:Key="Icons.Archive">M296 392h64v64h-64zM296 582v160h128V582h-64v-62h-64v62zm80 48v64h-32v-64h32zM360 328h64v64h-64zM296 264h64v64h-64zM360 456h64v64h-64zM360 200h64v64h-64zM855 289 639 73c-6-6-14-9-23-9H192c-18 0-32 14-32 32v832c0 18 14 32 32 32h640c18 0 32-14 32-32V311c0-9-3-17-9-23zM790 326H602V138L790 326zm2 562H232V136h64v64h64v-64h174v216c0 23 19 42 42 42h216v494z</StreamGeometry>
|
||||
<StreamGeometry x:Key="Icons.Binary">M71 1024V0h661L953 219V1024H71zm808-731-220-219H145V951h735V293zM439 512h-220V219h220V512zm-74-219H292v146h74v-146zm0 512h74v73h-220v-73H292v-146H218V585h147v219zm294-366h74V512H512v-73h74v-146H512V219h147v219zm74 439H512V585h220v293zm-74-219h-74v146h74v-146z</StreamGeometry>
|
||||
<StreamGeometry x:Key="Icons.Blame">M128 256h192a64 64 0 110 128H128a64 64 0 110-128zm576 192h192a64 64 0 010 128h-192a64 64 0 010-128zm-576 192h192a64 64 0 010 128H128a64 64 0 010-128zm576 0h192a64 64 0 010 128h-192a64 64 0 010-128zm0-384h192a64 64 0 010 128h-192a64 64 0 010-128zM128 448h192a64 64 0 110 128H128a64 64 0 110-128zm384-320a64 64 0 0164 64v640a64 64 0 01-128 0V192a64 64 0 0164-64z</StreamGeometry>
|
||||
|
|
|
@ -238,6 +238,7 @@
|
|||
<x:String x:Key="Text.Diff.Next" xml:space="preserve">Next Difference</x:String>
|
||||
<x:String x:Key="Text.Diff.NoChange" xml:space="preserve">NO CHANGES OR ONLY EOL CHANGES</x:String>
|
||||
<x:String x:Key="Text.Diff.Prev" xml:space="preserve">Previous Difference</x:String>
|
||||
<x:String x:Key="Text.Diff.SaveAsPatch" xml:space="preserve">Save as Patch</x:String>
|
||||
<x:String x:Key="Text.Diff.ShowHiddenSymbols" xml:space="preserve">Show hidden symbols</x:String>
|
||||
<x:String x:Key="Text.Diff.SideBySide" xml:space="preserve">Side-By-Side Diff</x:String>
|
||||
<x:String x:Key="Text.Diff.Submodule" xml:space="preserve">SUBMODULE</x:String>
|
||||
|
@ -363,8 +364,12 @@
|
|||
<x:String x:Key="Text.Hotkeys.Repo.Commit" xml:space="preserve">Commit staged changes</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.CommitAndPush" xml:space="preserve">Commit and push staged changes</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.CommitWithAutoStage" xml:space="preserve">Stage all changes and commit</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.CreateBranchOnCommit" xml:space="preserve">Creates a new branch based on selected commit</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.DiscardSelected" xml:space="preserve">Discard selected changes</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.Fetch" xml:space="preserve">Fetch, starts directly</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.GoHome" xml:space="preserve">Dashboard mode (Default)</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.Pull" xml:space="preserve">Pull, starts directly</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.Push" xml:space="preserve">Push, starts directly</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.Refresh" xml:space="preserve">Force to reload this repository</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.StageOrUnstageSelected" xml:space="preserve">Stage/Unstage selected changes</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.OpenSearchCommits" xml:space="preserve">Commit search mode</x:String>
|
||||
|
|
|
@ -241,6 +241,7 @@
|
|||
<x:String x:Key="Text.Diff.Next" xml:space="preserve">下一个差异</x:String>
|
||||
<x:String x:Key="Text.Diff.NoChange" xml:space="preserve">没有变更或仅有换行符差异</x:String>
|
||||
<x:String x:Key="Text.Diff.Prev" xml:space="preserve">上一个差异</x:String>
|
||||
<x:String x:Key="Text.Diff.SaveAsPatch" xml:space="preserve">保存为补丁文件</x:String>
|
||||
<x:String x:Key="Text.Diff.ShowHiddenSymbols" xml:space="preserve">显示隐藏符号</x:String>
|
||||
<x:String x:Key="Text.Diff.SideBySide" xml:space="preserve">分列对比</x:String>
|
||||
<x:String x:Key="Text.Diff.Submodule" xml:space="preserve">子模块</x:String>
|
||||
|
@ -366,8 +367,12 @@
|
|||
<x:String x:Key="Text.Hotkeys.Repo.Commit" xml:space="preserve">提交暂存区更改</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.CommitAndPush" xml:space="preserve">提交暂存区更改并推送</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.CommitWithAutoStage" xml:space="preserve">自动暂存全部变更并提交</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.CreateBranchOnCommit" xml:space="preserve">基于选中提交创建新分支</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.DiscardSelected" xml:space="preserve">丢弃选中的更改</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.Fetch" xml:space="preserve">拉取 (fetch) 远程变更</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.GoHome" xml:space="preserve">切换左边栏为分支/标签等显示模式(默认)</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.Pull" xml:space="preserve">拉回 (pull) 远程变更</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.Push" xml:space="preserve">推送本地变更到远程</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.Refresh" xml:space="preserve">重新加载仓库状态</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.StageOrUnstageSelected" xml:space="preserve">将选中的变更暂存或从暂存列表中移除</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.OpenSearchCommits" xml:space="preserve">切换左边栏为提交搜索模式</x:String>
|
||||
|
|
|
@ -241,6 +241,7 @@
|
|||
<x:String x:Key="Text.Diff.Next" xml:space="preserve">下一個差異</x:String>
|
||||
<x:String x:Key="Text.Diff.NoChange" xml:space="preserve">沒有變更或僅有換行字元差異</x:String>
|
||||
<x:String x:Key="Text.Diff.Prev" xml:space="preserve">上一個差異</x:String>
|
||||
<x:String x:Key="Text.Diff.SaveAsPatch" xml:space="preserve">另存為修補檔</x:String>
|
||||
<x:String x:Key="Text.Diff.ShowHiddenSymbols" xml:space="preserve">顯示隱藏符號</x:String>
|
||||
<x:String x:Key="Text.Diff.SideBySide" xml:space="preserve">並排對比</x:String>
|
||||
<x:String x:Key="Text.Diff.Submodule" xml:space="preserve">子模組</x:String>
|
||||
|
@ -366,8 +367,12 @@
|
|||
<x:String x:Key="Text.Hotkeys.Repo.Commit" xml:space="preserve">提交暫存區變更</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.CommitAndPush" xml:space="preserve">提交暫存區變更並推送</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.CommitWithAutoStage" xml:space="preserve">自動暫存全部變更並提交</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.CreateBranchOnCommit" xml:space="preserve">根據選取的提交建立新的分支</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.DiscardSelected" xml:space="preserve">捨棄選取的變更</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.Fetch" xml:space="preserve">提取 (fetch) 遠端的變更</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.GoHome" xml:space="preserve">切換左邊欄為分支/標籤等顯示模式 (預設)</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.Pull" xml:space="preserve">拉取 (pull) 遠端的變更</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.Push" xml:space="preserve">推送 (push) 本地變更到遠端存放庫</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.Refresh" xml:space="preserve">強制重新載入存放庫</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.StageOrUnstageSelected" xml:space="preserve">暫存或取消暫存選取的變更</x:String>
|
||||
<x:String x:Key="Text.Hotkeys.Repo.OpenSearchCommits" xml:space="preserve">切換左邊欄為歷史搜尋模式</x:String>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Platform.Storage;
|
||||
|
@ -258,6 +259,44 @@ namespace SourceGit.ViewModels
|
|||
multipleMenu.Items.Add(new MenuItem() { Header = "-" });
|
||||
}
|
||||
|
||||
var saveToPatchMultiple = new MenuItem();
|
||||
saveToPatchMultiple.Icon = App.CreateMenuIcon("Icons.Diff");
|
||||
saveToPatchMultiple.Header = App.Text("CommitCM.SaveAsPatch");
|
||||
saveToPatchMultiple.Click += async (_, e) =>
|
||||
{
|
||||
var storageProvider = App.GetStorageProvider();
|
||||
if (storageProvider == null)
|
||||
return;
|
||||
|
||||
var options = new FolderPickerOpenOptions() { AllowMultiple = false };
|
||||
try
|
||||
{
|
||||
var picker = await storageProvider.OpenFolderPickerAsync(options);
|
||||
if (picker.Count == 1)
|
||||
{
|
||||
var saveTo = $"{picker[0].Path.LocalPath}/patches";
|
||||
var succ = false;
|
||||
foreach (var c in selected)
|
||||
{
|
||||
succ = await Task.Run(() => new Commands.FormatPatch(_repo.FullPath, c.SHA, saveTo).Exec());
|
||||
if (!succ)
|
||||
break;
|
||||
}
|
||||
|
||||
if (succ)
|
||||
App.SendNotification(_repo.FullPath, App.Text("SaveAsPatchSuccess"));
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
App.RaiseException(_repo.FullPath, $"Failed to save as patch: {exception.Message}");
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
};
|
||||
multipleMenu.Items.Add(saveToPatchMultiple);
|
||||
multipleMenu.Items.Add(new MenuItem() { Header = "-" });
|
||||
|
||||
var copyMultipleSHAs = new MenuItem();
|
||||
copyMultipleSHAs.Header = App.Text("CommitCM.CopySHA");
|
||||
copyMultipleSHAs.Icon = App.CreateMenuIcon("Icons.Copy");
|
||||
|
|
|
@ -24,6 +24,11 @@ namespace SourceGit.ViewModels
|
|||
private set => SetProperty(ref _endPoint, value);
|
||||
}
|
||||
|
||||
public bool CanSaveAsPatch
|
||||
{
|
||||
get => _canSaveAsPatch;
|
||||
}
|
||||
|
||||
public List<Models.Change> VisibleChanges
|
||||
{
|
||||
get => _visibleChanges;
|
||||
|
@ -73,6 +78,7 @@ namespace SourceGit.ViewModels
|
|||
_repo = repo;
|
||||
_startPoint = (object)startPoint ?? new Models.Null();
|
||||
_endPoint = (object)endPoint ?? new Models.Null();
|
||||
_canSaveAsPatch = startPoint != null && endPoint != null;
|
||||
|
||||
Task.Run(Refresh);
|
||||
}
|
||||
|
@ -105,6 +111,16 @@ namespace SourceGit.ViewModels
|
|||
Task.Run(Refresh);
|
||||
}
|
||||
|
||||
public void SaveAsPatch(string saveTo)
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
var succ = Commands.SaveChangesAsPatch.ProcessRevisionCompareChanges(_repo, _changes, GetSHA(_startPoint), GetSHA(_endPoint), saveTo);
|
||||
if (succ)
|
||||
Dispatcher.UIThread.Invoke(() => App.SendNotification(_repo, App.Text("SaveAsPatchSuccess")));
|
||||
});
|
||||
}
|
||||
|
||||
public void ClearSearchFilter()
|
||||
{
|
||||
SearchFilter = string.Empty;
|
||||
|
@ -218,6 +234,7 @@ namespace SourceGit.ViewModels
|
|||
private string _repo;
|
||||
private object _startPoint = null;
|
||||
private object _endPoint = null;
|
||||
private bool _canSaveAsPatch = false;
|
||||
private List<Models.Change> _changes = null;
|
||||
private List<Models.Change> _visibleChanges = null;
|
||||
private List<Models.Change> _selectedChanges = null;
|
||||
|
|
|
@ -539,7 +539,7 @@ namespace SourceGit.ViewModels
|
|||
var storageFile = await storageProvider.SaveFilePickerAsync(options);
|
||||
if (storageFile != null)
|
||||
{
|
||||
var succ = await Task.Run(() => Commands.SaveChangesAsPatch.Exec(_repo.FullPath, _selectedUnstaged, true, storageFile.Path.LocalPath));
|
||||
var succ = await Task.Run(() => Commands.SaveChangesAsPatch.ProcessLocalChanges(_repo.FullPath, _selectedUnstaged, true, storageFile.Path.LocalPath));
|
||||
if (succ)
|
||||
App.SendNotification(_repo.FullPath, App.Text("SaveAsPatchSuccess"));
|
||||
}
|
||||
|
@ -858,7 +858,7 @@ namespace SourceGit.ViewModels
|
|||
var storageFile = await storageProvider.SaveFilePickerAsync(options);
|
||||
if (storageFile != null)
|
||||
{
|
||||
var succ = await Task.Run(() => Commands.SaveChangesAsPatch.Exec(_repo.FullPath, _selectedUnstaged, true, storageFile.Path.LocalPath));
|
||||
var succ = await Task.Run(() => Commands.SaveChangesAsPatch.ProcessLocalChanges(_repo.FullPath, _selectedUnstaged, true, storageFile.Path.LocalPath));
|
||||
if (succ)
|
||||
App.SendNotification(_repo.FullPath, App.Text("SaveAsPatchSuccess"));
|
||||
}
|
||||
|
@ -981,7 +981,7 @@ namespace SourceGit.ViewModels
|
|||
var storageFile = await storageProvider.SaveFilePickerAsync(options);
|
||||
if (storageFile != null)
|
||||
{
|
||||
var succ = await Task.Run(() => Commands.SaveChangesAsPatch.Exec(_repo.FullPath, _selectedStaged, false, storageFile.Path.LocalPath));
|
||||
var succ = await Task.Run(() => Commands.SaveChangesAsPatch.ProcessLocalChanges(_repo.FullPath, _selectedStaged, false, storageFile.Path.LocalPath));
|
||||
if (succ)
|
||||
App.SendNotification(_repo.FullPath, App.Text("SaveAsPatchSuccess"));
|
||||
}
|
||||
|
@ -1156,7 +1156,7 @@ namespace SourceGit.ViewModels
|
|||
var storageFile = await storageProvider.SaveFilePickerAsync(options);
|
||||
if (storageFile != null)
|
||||
{
|
||||
var succ = await Task.Run(() => Commands.SaveChangesAsPatch.Exec(_repo.FullPath, _selectedStaged, false, storageFile.Path.LocalPath));
|
||||
var succ = await Task.Run(() => Commands.SaveChangesAsPatch.ProcessLocalChanges(_repo.FullPath, _selectedStaged, false, storageFile.Path.LocalPath));
|
||||
if (succ)
|
||||
App.SendNotification(_repo.FullPath, App.Text("SaveAsPatchSuccess"));
|
||||
}
|
||||
|
|
|
@ -125,7 +125,7 @@ namespace SourceGit.Views
|
|||
DescriptionEditor.CaretIndex = 0;
|
||||
e.Handled = true;
|
||||
}
|
||||
else if (e.Key == Key.V && ((OperatingSystem.IsMacOS() && e.KeyModifiers == KeyModifiers.Meta) || (!OperatingSystem.IsMacOS() && e.KeyModifiers == KeyModifiers.Control)))
|
||||
else if (e.Key == Key.V && e.KeyModifiers == (OperatingSystem.IsMacOS() ? KeyModifiers.Meta : KeyModifiers.Control))
|
||||
{
|
||||
e.Handled = true;
|
||||
|
||||
|
|
|
@ -722,19 +722,39 @@ namespace SourceGit.Views
|
|||
|
||||
private void OnCommitListKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (sender is ListBox { SelectedItems: { Count: > 0 } selected } &&
|
||||
e.Key == Key.C &&
|
||||
e.KeyModifiers.HasFlag(KeyModifiers.Control))
|
||||
if (!e.KeyModifiers.HasFlag(OperatingSystem.IsMacOS() ? KeyModifiers.Meta : KeyModifiers.Control))
|
||||
return;
|
||||
|
||||
// These shortcuts are not mentioned in the Shortcut Reference window. Is this expected?
|
||||
if (sender is ListBox { SelectedItems: { Count: > 0 } selected })
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
foreach (var item in selected)
|
||||
// CTRL/COMMAND + C -> Copy selected commit SHA and subject.
|
||||
if (e.Key == Key.C)
|
||||
{
|
||||
if (item is Models.Commit commit)
|
||||
builder.AppendLine($"{commit.SHA.Substring(0, 10)} - {commit.Subject}");
|
||||
var builder = new StringBuilder();
|
||||
foreach (var item in selected)
|
||||
{
|
||||
if (item is Models.Commit commit)
|
||||
builder.AppendLine($"{commit.SHA.Substring(0, 10)} - {commit.Subject}");
|
||||
}
|
||||
|
||||
App.CopyText(builder.ToString());
|
||||
e.Handled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
App.CopyText(builder.ToString());
|
||||
e.Handled = true;
|
||||
// CTRL/COMMAND + B -> shows Create Branch pop-up at selected commit.
|
||||
if (e.Key == Key.B)
|
||||
{
|
||||
if (selected.Count == 1 &&
|
||||
selected[0] is Models.Commit commit &&
|
||||
DataContext is ViewModels.Histories histories &&
|
||||
ViewModels.PopupHost.CanCreatePopup())
|
||||
{
|
||||
ViewModels.PopupHost.ShowPopup(new ViewModels.CreateBranch(histories.Repo, commit));
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
FontSize="{Binding Source={x:Static vm:Preference.Instance}, Path=DefaultFontSize, Converter={x:Static c:DoubleConverters.Increase}}"
|
||||
Margin="0,8"/>
|
||||
|
||||
<Grid RowDefinitions="20,20,20,20,20,20,20,20,20,20,20" ColumnDefinitions="150,*">
|
||||
<Grid RowDefinitions="20,20,20,20,20,20,20,20,20,20,20,20,20,20,20" ColumnDefinitions="150,*">
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" Classes="primary bold" Text="{OnPlatform Ctrl+Shift+H, macOS=⌘+⇧+H}"/>
|
||||
<TextBlock Grid.Row="0" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.GoHome}" />
|
||||
|
||||
|
@ -102,8 +102,20 @@
|
|||
<TextBlock Grid.Row="9" Grid.Column="0" Classes="primary bold" Text="{OnPlatform Alt+Enter, macOS=⌥+Enter}"/>
|
||||
<TextBlock Grid.Row="9" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.CommitAndPush}" />
|
||||
|
||||
<TextBlock Grid.Row="10" Grid.Column="0" Classes="primary bold" Text="F5"/>
|
||||
<TextBlock Grid.Row="10" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.Refresh}" />
|
||||
<TextBlock Grid.Row="10" Grid.Column="0" Classes="primary bold" Text="{OnPlatform Ctrl+Down, macOS=⌘+Down}"/>
|
||||
<TextBlock Grid.Row="10" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.Fetch}" />
|
||||
|
||||
<TextBlock Grid.Row="11" Grid.Column="0" Classes="primary bold" Text="{OnPlatform Ctrl+Shift+Down, macOS=⌘+⇧+Down}"/>
|
||||
<TextBlock Grid.Row="11" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.Pull}" />
|
||||
|
||||
<TextBlock Grid.Row="12" Grid.Column="0" Classes="primary bold" Text="{OnPlatform Ctrl+Shift+Up, macOS=⌘+⇧+Up}"/>
|
||||
<TextBlock Grid.Row="12" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.Push}" />
|
||||
|
||||
<TextBlock Grid.Row="13" Grid.Column="0" Classes="primary bold" Text="{OnPlatform Ctrl+B, macOS=⌘+B}"/>
|
||||
<TextBlock Grid.Row="13" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.CreateBranchOnCommit}" />
|
||||
|
||||
<TextBlock Grid.Row="14" Grid.Column="0" Classes="primary bold" Text="F5"/>
|
||||
<TextBlock Grid.Row="14" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.Refresh}" />
|
||||
</Grid>
|
||||
|
||||
<TextBlock Text="{DynamicResource Text.Hotkeys.TextEditor}"
|
||||
|
|
|
@ -115,8 +115,7 @@ namespace SourceGit.Views
|
|||
return;
|
||||
}
|
||||
|
||||
if ((OperatingSystem.IsMacOS() && e.KeyModifiers.HasFlag(KeyModifiers.Meta)) ||
|
||||
(!OperatingSystem.IsMacOS() && e.KeyModifiers.HasFlag(KeyModifiers.Control)))
|
||||
if (e.KeyModifiers.HasFlag(OperatingSystem.IsMacOS() ? KeyModifiers.Meta : KeyModifiers.Control))
|
||||
{
|
||||
if (e.Key == Key.W)
|
||||
{
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Column="1" Orientation="Horizontal">
|
||||
<Button Classes="icon_button" Width="32" Click="Fetch">
|
||||
<Button Classes="icon_button" Width="32" Click="Fetch" HotKey="{OnPlatform Ctrl+Down, macOS=⌘+Down}">
|
||||
<ToolTip.Tip>
|
||||
<StackPanel Orientation="Vertical">
|
||||
<TextBlock Text="{DynamicResource Text.Fetch}"/>
|
||||
|
@ -42,7 +42,7 @@
|
|||
<Path Width="14" Height="14" Data="{StaticResource Icons.Fetch}"/>
|
||||
</Button>
|
||||
|
||||
<Button Classes="icon_button" Width="32" Margin="16,0,0,0" Click="Pull">
|
||||
<Button Classes="icon_button" Width="32" Margin="16,0,0,0" Click="Pull" HotKey="{OnPlatform Ctrl+Shift+Down, macOS=⌘+Shift+Down}">
|
||||
<ToolTip.Tip>
|
||||
<StackPanel Orientation="Vertical">
|
||||
<TextBlock Text="{DynamicResource Text.Pull}"/>
|
||||
|
@ -53,7 +53,7 @@
|
|||
<Path Width="14" Height="14" Data="{StaticResource Icons.Pull}"/>
|
||||
</Button>
|
||||
|
||||
<Button Classes="icon_button" Width="32" Margin="16,0,0,0" Click="Push">
|
||||
<Button Classes="icon_button" Width="32" Margin="16,0,0,0" Click="Push" HotKey="{OnPlatform Ctrl+Shift+Up, macOS=⌘+Shift+Up}">
|
||||
<ToolTip.Tip>
|
||||
<StackPanel Orientation="Vertical">
|
||||
<TextBlock Text="{DynamicResource Text.Push}"/>
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
using System;
|
||||
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
|
@ -45,22 +47,43 @@ namespace SourceGit.Views
|
|||
private void Fetch(object _, RoutedEventArgs e)
|
||||
{
|
||||
var launcher = this.FindAncestorOfType<Launcher>();
|
||||
(DataContext as ViewModels.Repository)?.Fetch(launcher?.HasKeyModifier(KeyModifiers.Control) ?? false);
|
||||
e.Handled = true;
|
||||
if (launcher is not null && DataContext is ViewModels.Repository repo)
|
||||
{
|
||||
var startDirectly = launcher.HasKeyModifier(KeyModifiers.Control);
|
||||
if (!startDirectly && OperatingSystem.IsMacOS())
|
||||
startDirectly = launcher.HasKeyModifier(KeyModifiers.Meta);
|
||||
|
||||
repo.Fetch(startDirectly);
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void Pull(object _, RoutedEventArgs e)
|
||||
{
|
||||
var launcher = this.FindAncestorOfType<Launcher>();
|
||||
(DataContext as ViewModels.Repository)?.Pull(launcher?.HasKeyModifier(KeyModifiers.Control) ?? false);
|
||||
e.Handled = true;
|
||||
if (launcher is not null && DataContext is ViewModels.Repository repo)
|
||||
{
|
||||
var startDirectly = launcher.HasKeyModifier(KeyModifiers.Control);
|
||||
if (!startDirectly && OperatingSystem.IsMacOS())
|
||||
startDirectly = launcher.HasKeyModifier(KeyModifiers.Meta);
|
||||
|
||||
repo.Pull(startDirectly);
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void Push(object _, RoutedEventArgs e)
|
||||
{
|
||||
var launcher = this.FindAncestorOfType<Launcher>();
|
||||
(DataContext as ViewModels.Repository)?.Push(launcher?.HasKeyModifier(KeyModifiers.Control) ?? false);
|
||||
e.Handled = true;
|
||||
if (launcher is not null && DataContext is ViewModels.Repository repo)
|
||||
{
|
||||
var startDirectly = launcher.HasKeyModifier(KeyModifiers.Control);
|
||||
if (!startDirectly && OperatingSystem.IsMacOS())
|
||||
startDirectly = launcher.HasKeyModifier(KeyModifiers.Meta);
|
||||
|
||||
repo.Push(startDirectly);
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void StashAll(object _, RoutedEventArgs e)
|
||||
|
|
|
@ -35,21 +35,26 @@
|
|||
|
||||
<Grid RowDefinitions="50,*" Margin="4">
|
||||
<!-- Compare Revision Info -->
|
||||
<Grid Grid.Row="0" Margin="48,0,48,4" ColumnDefinitions="*,48,*">
|
||||
<Grid Grid.Row="0" Margin="0,0,0,6" ColumnDefinitions="*,32,*,Auto">
|
||||
<!-- Base Revision -->
|
||||
<Border Grid.Column="0" BorderBrush="{DynamicResource Brush.Border2}" BorderThickness="1" Background="{DynamicResource Brush.Contents}" CornerRadius="4" Padding="4">
|
||||
<ContentControl Content="{Binding StartPoint}"/>
|
||||
</Border>
|
||||
|
||||
<!-- Swap Button -->
|
||||
<!-- Swap Buttons -->
|
||||
<Button Grid.Column="1" Classes="icon_button" Command="{Binding Swap}" HorizontalAlignment="Center" ToolTip.Tip="{DynamicResource Text.Diff.SwapCommits}">
|
||||
<Path Width="16" Height="16" Fill="{DynamicResource Brush.FG2}" Data="{DynamicResource Icons.Compare}"/>
|
||||
<Path Width="16" Height="16" Data="{DynamicResource Icons.Compare}"/>
|
||||
</Button>
|
||||
|
||||
<!-- Right Revision -->
|
||||
<Border Grid.Column="2" BorderBrush="{DynamicResource Brush.Border2}" BorderThickness="1" Background="{DynamicResource Brush.Contents}" CornerRadius="4" Padding="4">
|
||||
<ContentControl Content="{Binding EndPoint}"/>
|
||||
</Border>
|
||||
|
||||
<!-- Save As Patch Button -->
|
||||
<Button Grid.Column="3" Classes="icon_button" Width="32" Click="OnSaveAsPatch" IsVisible="{Binding CanSaveAsPatch}" ToolTip.Tip="{DynamicResource Text.Diff.SaveAsPatch}">
|
||||
<Path Width="16" Height="16" Data="{DynamicResource Icons.Diff}"/>
|
||||
</Button>
|
||||
</Grid>
|
||||
|
||||
<!-- Changes View -->
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Platform.Storage;
|
||||
|
||||
namespace SourceGit.Views
|
||||
{
|
||||
|
@ -28,5 +30,27 @@ namespace SourceGit.Views
|
|||
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private async void OnSaveAsPatch(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var topLevel = TopLevel.GetTopLevel(this);
|
||||
if (topLevel == null)
|
||||
return;
|
||||
|
||||
var vm = DataContext as ViewModels.RevisionCompare;
|
||||
if (vm == null)
|
||||
return;
|
||||
|
||||
var options = new FilePickerSaveOptions();
|
||||
options.Title = App.Text("FileCM.SaveAsPatch");
|
||||
options.DefaultExtension = ".patch";
|
||||
options.FileTypeChoices = [new FilePickerFileType("Patch File") { Patterns = ["*.patch"] }];
|
||||
|
||||
var storageFile = await topLevel.StorageProvider.SaveFilePickerAsync(options);
|
||||
if (storageFile != null)
|
||||
vm.SaveAsPatch(storageFile.Path.LocalPath);
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue