Compare commits

...

15 commits

Author SHA1 Message Date
leo
1e148c032d
localization: update English translations
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Localization Check / localization-check (push) Waiting to run
Signed-off-by: leo <longshuang@msn.cn>
2024-11-21 21:10:15 +08:00
leo
13504d1831
ux: make sure Icons.Eye center aligned
Signed-off-by: leo <longshuang@msn.cn>
2024-11-21 21:01:06 +08:00
leo
8a95a17b0e
ux: re-order menu items
Signed-off-by: leo <longshuang@msn.cn>
2024-11-21 20:55:59 +08:00
github-actions[bot]
f545ceeb70 doc: Update translation status and missing keys 2024-11-21 12:51:19 +00:00
leo
8bd5bd864e
feature: add context menu to switch histories filter mode to selected commit
Signed-off-by: leo <longshuang@msn.cn>
2024-11-21 20:50:51 +08:00
leo
e6e1e4e82e
fix: can not type characters with accent (#716)
Leaves the `X11PlatformOptions.EnableIme` unsetted, since Avalonia will auto enable it when `LANG` contains `zh`/`ja`/`vi`/`ko`

Signed-off-by: leo <longshuang@msn.cn>
2024-11-21 19:23:59 +08:00
leo
f0d8285416
enhance: only supports using local bare repository as remote (#706)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-21 14:53:43 +08:00
leo
d98765364d
feature: supports using local repository as remote (#706)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-21 14:49:32 +08:00
leo
b407dd97a1
enhance: reduce repository scanning time (#728)
* skip special folders, such as `node_modules`, `.svn`, `.vs` .etc.
* change max scanning depth to 5

Signed-off-by: leo <longshuang@msn.cn>
2024-11-21 14:18:41 +08:00
leo
069dc255d1
enhance: skip scanning sub folders if current is not a git repository but has .git subfolder/file (#728)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-21 12:56:12 +08:00
leo
d3eca59036
refactor: rewrite the way to make sure scan repositories panel shows at least 0.5s (#728)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-21 12:14:11 +08:00
leo
8342702103
feature: add save as path menu item for commit change (#724)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-21 10:19:00 +08:00
leo
22157a5c98
fix: tooltip of parent SHA textblock is not closed properly (#727)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-21 10:06:16 +08:00
leo
a980cc987d
fix: wired ordering when cherry-pick multiple commits (#726)
Since the items in `ListBox.SelectedItems`  are not ordered by their position in the list, but in the order user selected, it need be sorted before `cherry-pick`

Signed-off-by: leo <longshuang@msn.cn>
2024-11-21 09:57:43 +08:00
leo
142987f73d
enhance: use user instead of system to supports OpenAI's o1-preview and o1-mini model (#725)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-21 09:31:38 +08:00
14 changed files with 197 additions and 22 deletions

View file

@ -47,7 +47,7 @@
## Translation Status ## 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-99.29%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-98.43%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-97.86%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-99.71%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-99.29%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-99.14%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-98.29%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-97.72%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-99.57%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-99.14%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 ## How to Use

View file

@ -1,4 +1,4 @@
### de_DE.axaml: 99.29% ### de_DE.axaml: 99.14%
<details> <details>
@ -6,13 +6,14 @@
- Text.CommitDetail.Info.Children - Text.CommitDetail.Info.Children
- Text.Preference.General.ShowChildren - Text.Preference.General.ShowChildren
- Text.Repository.FilterCommits
- Text.Repository.HistoriesOrder - Text.Repository.HistoriesOrder
- Text.Repository.HistoriesOrder.ByDate - Text.Repository.HistoriesOrder.ByDate
- Text.Repository.HistoriesOrder.Topo - Text.Repository.HistoriesOrder.Topo
</details> </details>
### es_ES.axaml: 98.43% ### es_ES.axaml: 98.29%
<details> <details>
@ -23,6 +24,7 @@
- Text.Preference.Appearance.FontSize.Default - Text.Preference.Appearance.FontSize.Default
- Text.Preference.Appearance.FontSize.Editor - Text.Preference.Appearance.FontSize.Editor
- Text.Preference.General.ShowChildren - Text.Preference.General.ShowChildren
- Text.Repository.FilterCommits
- Text.Repository.FilterCommits.Default - Text.Repository.FilterCommits.Default
- Text.Repository.FilterCommits.Exclude - Text.Repository.FilterCommits.Exclude
- Text.Repository.FilterCommits.Include - Text.Repository.FilterCommits.Include
@ -32,7 +34,7 @@
</details> </details>
### fr_FR.axaml: 97.86% ### fr_FR.axaml: 97.72%
<details> <details>
@ -46,6 +48,7 @@
- Text.Preference.Appearance.FontSize.Editor - Text.Preference.Appearance.FontSize.Editor
- Text.Preference.General.ShowChildren - Text.Preference.General.ShowChildren
- Text.Repository.CustomActions - Text.Repository.CustomActions
- Text.Repository.FilterCommits
- Text.Repository.FilterCommits.Default - Text.Repository.FilterCommits.Default
- Text.Repository.FilterCommits.Exclude - Text.Repository.FilterCommits.Exclude
- Text.Repository.FilterCommits.Include - Text.Repository.FilterCommits.Include
@ -56,7 +59,7 @@
</details> </details>
### pt_BR.axaml: 99.71% ### pt_BR.axaml: 99.57%
<details> <details>
@ -64,10 +67,11 @@
- Text.CommitDetail.Info.Children - Text.CommitDetail.Info.Children
- Text.Preference.General.ShowChildren - Text.Preference.General.ShowChildren
- Text.Repository.FilterCommits
</details> </details>
### ru_RU.axaml: 99.29% ### ru_RU.axaml: 99.14%
<details> <details>
@ -75,6 +79,7 @@
- Text.CommitDetail.Info.Children - Text.CommitDetail.Info.Children
- Text.Preference.General.ShowChildren - Text.Preference.General.ShowChildren
- Text.Repository.FilterCommits
- Text.Repository.HistoriesOrder - Text.Repository.HistoriesOrder
- Text.Repository.HistoriesOrder.ByDate - Text.Repository.HistoriesOrder.ByDate
- Text.Repository.HistoriesOrder.Topo - Text.Repository.HistoriesOrder.Topo

View file

@ -150,7 +150,7 @@ namespace SourceGit.Models
public OpenAIChatResponse Chat(string prompt, string question, CancellationToken cancellation) public OpenAIChatResponse Chat(string prompt, string question, CancellationToken cancellation)
{ {
var chat = new OpenAIChatRequest() { Model = Model }; var chat = new OpenAIChatRequest() { Model = Model };
chat.AddMessage("system", prompt); chat.AddMessage("user", prompt);
chat.AddMessage("user", question); chat.AddMessage("user", question);
var client = new HttpClient() { Timeout = TimeSpan.FromSeconds(60) }; var client = new HttpClient() { Timeout = TimeSpan.FromSeconds(60) };

View file

@ -1,4 +1,5 @@
using System; using System;
using System.IO;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
namespace SourceGit.Models namespace SourceGit.Models
@ -49,7 +50,7 @@ namespace SourceGit.Models
return true; return true;
} }
return false; return url.EndsWith(".git", StringComparison.Ordinal) && Directory.Exists(url);
} }
public bool TryGetVisitURL(out string url) public bool TryGetVisitURL(out string url)

View file

@ -13,10 +13,7 @@ namespace SourceGit.Native
{ {
public void SetupApp(AppBuilder builder) public void SetupApp(AppBuilder builder)
{ {
builder.With(new X11PlatformOptions() builder.With(new X11PlatformOptions());
{
EnableIme = true,
});
} }
public string FindGitExecutable() public string FindGitExecutable()

View file

@ -32,7 +32,7 @@
<StreamGeometry x:Key="Icons.Empty">M469 235V107h85v128h-85zm-162-94 85 85-60 60-85-85 60-60zm469 60-85 85-60-60 85-85 60 60zm-549 183A85 85 0 01302 341H722a85 85 0 0174 42l131 225A85 85 0 01939 652V832a85 85 0 01-85 85H171a85 85 0 01-85-85v-180a85 85 0 0112-43l131-225zM722 427H302l-100 171h255l10 29a59 59 0 002 5c2 4 5 9 9 14 8 9 18 17 34 17 16 0 26-7 34-17a72 72 0 0011-18l0-0 10-29h255l-100-171zM853 683H624a155 155 0 01-12 17C593 722 560 747 512 747c-48 0-81-25-99-47a155 155 0 01-12-17H171v149h683v-149z</StreamGeometry> <StreamGeometry x:Key="Icons.Empty">M469 235V107h85v128h-85zm-162-94 85 85-60 60-85-85 60-60zm469 60-85 85-60-60 85-85 60 60zm-549 183A85 85 0 01302 341H722a85 85 0 0174 42l131 225A85 85 0 01939 652V832a85 85 0 01-85 85H171a85 85 0 01-85-85v-180a85 85 0 0112-43l131-225zM722 427H302l-100 171h255l10 29a59 59 0 002 5c2 4 5 9 9 14 8 9 18 17 34 17 16 0 26-7 34-17a72 72 0 0011-18l0-0 10-29h255l-100-171zM853 683H624a155 155 0 01-12 17C593 722 560 747 512 747c-48 0-81-25-99-47a155 155 0 01-12-17H171v149h683v-149z</StreamGeometry>
<StreamGeometry x:Key="Icons.Error">M576 832C576 867 547 896 512 896 477 896 448 867 448 832 448 797 477 768 512 768 547 768 576 797 576 832ZM512 256C477 256 448 285 448 320L448 640C448 675 477 704 512 704 547 704 576 675 576 640L576 320C576 285 547 256 512 256ZM1024 896C1024 967 967 1024 896 1024L128 1024C57 1024 0 967 0 896 0 875 5 855 14 837L14 837 398 69 398 69C420 28 462 0 512 0 562 0 604 28 626 69L1008 835C1018 853 1024 874 1024 896ZM960 896C960 885 957 875 952 865L952 864 951 863 569 98C557 77 536 64 512 64 488 64 466 77 455 99L452 105 92 825 93 825 71 867C66 876 64 886 64 896 64 931 93 960 128 960L896 960C931 960 960 931 960 896Z</StreamGeometry> <StreamGeometry x:Key="Icons.Error">M576 832C576 867 547 896 512 896 477 896 448 867 448 832 448 797 477 768 512 768 547 768 576 797 576 832ZM512 256C477 256 448 285 448 320L448 640C448 675 477 704 512 704 547 704 576 675 576 640L576 320C576 285 547 256 512 256ZM1024 896C1024 967 967 1024 896 1024L128 1024C57 1024 0 967 0 896 0 875 5 855 14 837L14 837 398 69 398 69C420 28 462 0 512 0 562 0 604 28 626 69L1008 835C1018 853 1024 874 1024 896ZM960 896C960 885 957 875 952 865L952 864 951 863 569 98C557 77 536 64 512 64 488 64 466 77 455 99L452 105 92 825 93 825 71 867C66 876 64 886 64 896 64 931 93 960 128 960L896 960C931 960 960 931 960 896Z</StreamGeometry>
<StreamGeometry x:Key="Icons.Explore">M928 128l-416 0-32-64-352 0-64 128 896 0zM904 704l75 0 45-448-1024 0 64 640 484 0c-105-38-180-138-180-256 0-150 122-272 272-272s272 122 272 272c0 22-3 43-8 64zM1003 914l-198-175c17-29 27-63 27-99 0-106-86-192-192-192s-192 86-192 192 86 192 192 192c36 0 70-10 99-27l175 198c23 27 62 28 87 3l6-6c25-25 23-64-3-87zM640 764c-68 0-124-56-124-124s56-124 124-124 124 56 124 124-56 124-124 124z</StreamGeometry> <StreamGeometry x:Key="Icons.Explore">M928 128l-416 0-32-64-352 0-64 128 896 0zM904 704l75 0 45-448-1024 0 64 640 484 0c-105-38-180-138-180-256 0-150 122-272 272-272s272 122 272 272c0 22-3 43-8 64zM1003 914l-198-175c17-29 27-63 27-99 0-106-86-192-192-192s-192 86-192 192 86 192 192 192c36 0 70-10 99-27l175 198c23 27 62 28 87 3l6-6c25-25 23-64-3-87zM640 764c-68 0-124-56-124-124s56-124 124-124 124 56 124 124-56 124-124 124z</StreamGeometry>
<StreamGeometry x:Key="Icons.Eye">M520 168C291 168 95 311 16 512c79 201 275 344 504 344 229 0 425-143 504-344-79-201-275-344-504-344zm0 573c-126 0-229-103-229-229s103-229 229-229c126 0 229 103 229 229s-103 229-229 229zm0-367c-76 0-137 62-137 137s62 137 137 137S657 588 657 512s-62-137-137-137z</StreamGeometry> <StreamGeometry x:Key="Icons.Eye">M0 512M1024 512M512 0M512 1024M520 168C291 168 95 311 16 512c79 201 275 344 504 344 229 0 425-143 504-344-79-201-275-344-504-344zm0 573c-126 0-229-103-229-229s103-229 229-229c126 0 229 103 229 229s-103 229-229 229zm0-367c-76 0-137 62-137 137s62 137 137 137S657 588 657 512s-62-137-137-137z</StreamGeometry>
<StreamGeometry x:Key="Icons.EyeClose">M734 128c-33-19-74-8-93 25l-41 70c-28-6-58-9-90-9-294 0-445 298-445 298s82 149 231 236l-31 54c-19 33-8 74 25 93 33 19 74 8 93-25L759 222C778 189 767 147 734 128zM305 512c0-115 93-208 207-208 14 0 27 1 40 4l-37 64c-1 0-2 0-2 0-77 0-140 63-140 140 0 26 7 51 20 71l-37 64C324 611 305 564 305 512zM771 301 700 423c13 27 20 57 20 89 0 110-84 200-192 208l-51 89c12 1 24 2 36 2 292 0 446-298 446-298S895 388 771 301z</StreamGeometry> <StreamGeometry x:Key="Icons.EyeClose">M734 128c-33-19-74-8-93 25l-41 70c-28-6-58-9-90-9-294 0-445 298-445 298s82 149 231 236l-31 54c-19 33-8 74 25 93 33 19 74 8 93-25L759 222C778 189 767 147 734 128zM305 512c0-115 93-208 207-208 14 0 27 1 40 4l-37 64c-1 0-2 0-2 0-77 0-140 63-140 140 0 26 7 51 20 71l-37 64C324 611 305 564 305 512zM771 301 700 423c13 27 20 57 20 89 0 110-84 200-192 208l-51 89c12 1 24 2 36 2 292 0 446-298 446-298S895 388 771 301z</StreamGeometry>
<StreamGeometry x:Key="Icons.FastForward">M826 498 538 250c-11-9-26-1-26 14v496c0 15 16 23 26 14L826 526c8-7 8-21 0-28zm-320 0L218 250c-11-9-26-1-26 14v496c0 15 16 23 26 14L506 526c4-4 6-9 6-14 0-5-2-10-6-14z</StreamGeometry> <StreamGeometry x:Key="Icons.FastForward">M826 498 538 250c-11-9-26-1-26 14v496c0 15 16 23 26 14L826 526c8-7 8-21 0-28zm-320 0L218 250c-11-9-26-1-26 14v496c0 15 16 23 26 14L506 526c4-4 6-9 6-14 0-5-2-10-6-14z</StreamGeometry>
<StreamGeometry x:Key="Icons.Fetch">M1024 896v128H0V704h128v192h768V704h128v192zM576 555 811 320 896 405l-384 384-384-384L213 320 448 555V0h128v555z</StreamGeometry> <StreamGeometry x:Key="Icons.Fetch">M1024 896v128H0V704h128v192h768V704h128v192zM576 555 811 320 896 405l-384 384-384-384L213 320 448 555V0h128v555z</StreamGeometry>

View file

@ -115,7 +115,7 @@
<x:String x:Key="Text.CommitCM.Revert" xml:space="preserve">Revert Commit</x:String> <x:String x:Key="Text.CommitCM.Revert" xml:space="preserve">Revert Commit</x:String>
<x:String x:Key="Text.CommitCM.Reword" xml:space="preserve">Reword</x:String> <x:String x:Key="Text.CommitCM.Reword" xml:space="preserve">Reword</x:String>
<x:String x:Key="Text.CommitCM.SaveAsPatch" xml:space="preserve">Save as Patch...</x:String> <x:String x:Key="Text.CommitCM.SaveAsPatch" xml:space="preserve">Save as Patch...</x:String>
<x:String x:Key="Text.CommitCM.Squash" xml:space="preserve">Squash Into Parent</x:String> <x:String x:Key="Text.CommitCM.Squash" xml:space="preserve">Squash into Parent</x:String>
<x:String x:Key="Text.CommitCM.SquashCommitsSinceThis" xml:space="preserve">Squash Child Commits to Here</x:String> <x:String x:Key="Text.CommitCM.SquashCommitsSinceThis" xml:space="preserve">Squash Child Commits to Here</x:String>
<x:String x:Key="Text.CommitDetail.Changes" xml:space="preserve">CHANGES</x:String> <x:String x:Key="Text.CommitDetail.Changes" xml:space="preserve">CHANGES</x:String>
<x:String x:Key="Text.CommitDetail.Changes.Search" xml:space="preserve">Search Changes...</x:String> <x:String x:Key="Text.CommitDetail.Changes.Search" xml:space="preserve">Search Changes...</x:String>
@ -542,6 +542,7 @@
<x:String x:Key="Text.Repository.EnableReflog" xml:space="preserve">Enable '--reflog' Option</x:String> <x:String x:Key="Text.Repository.EnableReflog" xml:space="preserve">Enable '--reflog' Option</x:String>
<x:String x:Key="Text.Repository.Explore" xml:space="preserve">Open in File Browser</x:String> <x:String x:Key="Text.Repository.Explore" xml:space="preserve">Open in File Browser</x:String>
<x:String x:Key="Text.Repository.Filter" xml:space="preserve">Search Branches/Tags/Submodules</x:String> <x:String x:Key="Text.Repository.Filter" xml:space="preserve">Search Branches/Tags/Submodules</x:String>
<x:String x:Key="Text.Repository.FilterCommits" xml:space="preserve">Visibility in Graph</x:String>
<x:String x:Key="Text.Repository.FilterCommits.Default" xml:space="preserve">Unset</x:String> <x:String x:Key="Text.Repository.FilterCommits.Default" xml:space="preserve">Unset</x:String>
<x:String x:Key="Text.Repository.FilterCommits.Exclude" xml:space="preserve">Hide in commit graph</x:String> <x:String x:Key="Text.Repository.FilterCommits.Exclude" xml:space="preserve">Hide in commit graph</x:String>
<x:String x:Key="Text.Repository.FilterCommits.Include" xml:space="preserve">Filter in commit graph</x:String> <x:String x:Key="Text.Repository.FilterCommits.Include" xml:space="preserve">Filter in commit graph</x:String>

View file

@ -546,6 +546,7 @@
<x:String x:Key="Text.Repository.EnableReflog" xml:space="preserve">启用 --reflog 选项</x:String> <x:String x:Key="Text.Repository.EnableReflog" xml:space="preserve">启用 --reflog 选项</x:String>
<x:String x:Key="Text.Repository.Explore" xml:space="preserve">在文件浏览器中打开</x:String> <x:String x:Key="Text.Repository.Explore" xml:space="preserve">在文件浏览器中打开</x:String>
<x:String x:Key="Text.Repository.Filter" xml:space="preserve">快速查找分支/标签/子模块</x:String> <x:String x:Key="Text.Repository.Filter" xml:space="preserve">快速查找分支/标签/子模块</x:String>
<x:String x:Key="Text.Repository.FilterCommits" xml:space="preserve">设置在列表中的可见性</x:String>
<x:String x:Key="Text.Repository.FilterCommits.Default" xml:space="preserve">不指定</x:String> <x:String x:Key="Text.Repository.FilterCommits.Default" xml:space="preserve">不指定</x:String>
<x:String x:Key="Text.Repository.FilterCommits.Exclude" xml:space="preserve">在提交列表中隐藏</x:String> <x:String x:Key="Text.Repository.FilterCommits.Exclude" xml:space="preserve">在提交列表中隐藏</x:String>
<x:String x:Key="Text.Repository.FilterCommits.Include" xml:space="preserve">使用其对提交列表过滤</x:String> <x:String x:Key="Text.Repository.FilterCommits.Include" xml:space="preserve">使用其对提交列表过滤</x:String>

View file

@ -545,6 +545,7 @@
<x:String x:Key="Text.Repository.EnableReflog" xml:space="preserve">啟用 [--reflog] 選項</x:String> <x:String x:Key="Text.Repository.EnableReflog" xml:space="preserve">啟用 [--reflog] 選項</x:String>
<x:String x:Key="Text.Repository.Explore" xml:space="preserve">在檔案瀏覽器中開啟</x:String> <x:String x:Key="Text.Repository.Explore" xml:space="preserve">在檔案瀏覽器中開啟</x:String>
<x:String x:Key="Text.Repository.Filter" xml:space="preserve">快速搜尋分支/標籤/子模組</x:String> <x:String x:Key="Text.Repository.Filter" xml:space="preserve">快速搜尋分支/標籤/子模組</x:String>
<x:String x:Key="Text.Repository.FilterCommits" xml:space="preserve">設定在列表中的可視性</x:String>
<x:String x:Key="Text.Repository.FilterCommits.Default" xml:space="preserve">不指定</x:String> <x:String x:Key="Text.Repository.FilterCommits.Default" xml:space="preserve">不指定</x:String>
<x:String x:Key="Text.Repository.FilterCommits.Exclude" xml:space="preserve">在提交清單中隱藏</x:String> <x:String x:Key="Text.Repository.FilterCommits.Exclude" xml:space="preserve">在提交清單中隱藏</x:String>
<x:String x:Key="Text.Repository.FilterCommits.Include" xml:space="preserve">使用其來篩選提交清單</x:String> <x:String x:Key="Text.Repository.FilterCommits.Include" xml:space="preserve">使用其來篩選提交清單</x:String>

View file

@ -315,12 +315,40 @@ namespace SourceGit.ViewModels
ev.Handled = true; ev.Handled = true;
}; };
var patch = new MenuItem();
patch.Header = App.Text("FileCM.SaveAsPatch");
patch.Icon = App.CreateMenuIcon("Icons.Diff");
patch.Click += async (_, e) =>
{
var storageProvider = App.GetStorageProvider();
if (storageProvider == null)
return;
var options = new FilePickerSaveOptions();
options.Title = App.Text("FileCM.SaveAsPatch");
options.DefaultExtension = ".patch";
options.FileTypeChoices = [new FilePickerFileType("Patch File") { Patterns = ["*.patch"] }];
var baseRevision = _commit.Parents.Count == 0 ? "4b825dc642cb6eb9a060e54bf8d69288fbee4904" : _commit.Parents[0];
var storageFile = await storageProvider.SaveFilePickerAsync(options);
if (storageFile != null)
{
var saveTo = storageFile.Path.LocalPath;
var succ = await Task.Run(() => Commands.SaveChangesAsPatch.ProcessRevisionCompareChanges(_repo.FullPath, [change], baseRevision, _commit.SHA, saveTo));
if (succ)
App.SendNotification(_repo.FullPath, App.Text("SaveAsPatchSuccess"));
}
e.Handled = true;
};
var menu = new ContextMenu(); var menu = new ContextMenu();
menu.Items.Add(diffWithMerger); menu.Items.Add(diffWithMerger);
menu.Items.Add(explore); menu.Items.Add(explore);
menu.Items.Add(new MenuItem { Header = "-" }); menu.Items.Add(new MenuItem { Header = "-" });
menu.Items.Add(history); menu.Items.Add(history);
menu.Items.Add(blame); menu.Items.Add(blame);
menu.Items.Add(patch);
menu.Items.Add(new MenuItem { Header = "-" }); menu.Items.Add(new MenuItem { Header = "-" });
var resetToThisRevision = new MenuItem(); var resetToThisRevision = new MenuItem();

View file

@ -243,6 +243,12 @@ namespace SourceGit.ViewModels
if (canCherryPick) if (canCherryPick)
{ {
// Sort selected commits in order.
selected.Sort((l, r) =>
{
return _commits.IndexOf(r) - _commits.IndexOf(l);
});
var cherryPickMultiple = new MenuItem(); var cherryPickMultiple = new MenuItem();
cherryPickMultiple.Header = App.Text("CommitCM.CherryPickMultiple"); cherryPickMultiple.Header = App.Text("CommitCM.CherryPickMultiple");
cherryPickMultiple.Icon = App.CreateMenuIcon("Icons.CherryPick"); cherryPickMultiple.Icon = App.CreateMenuIcon("Icons.CherryPick");
@ -697,6 +703,109 @@ namespace SourceGit.ViewModels
return menu; return menu;
} }
private Models.FilterMode GetFilterMode(string pattern)
{
foreach (var filter in _repo.Settings.HistoriesFilters)
{
if (filter.Pattern.Equals(pattern, StringComparison.Ordinal))
return filter.Mode;
}
return Models.FilterMode.None;
}
private void FillBranchVisibilityMenu(MenuItem submenu, Models.Branch branch)
{
var visibility = new MenuItem();
visibility.Icon = App.CreateMenuIcon("Icons.Eye");
visibility.Header = App.Text("Repository.FilterCommits");
var exclude = new MenuItem();
exclude.Icon = App.CreateMenuIcon("Icons.EyeClose");
exclude.Header = App.Text("Repository.FilterCommits.Exclude");
exclude.Click += (_, e) =>
{
_repo.SetBranchFilterMode(branch, Models.FilterMode.Excluded);
e.Handled = true;
};
var filterMode = GetFilterMode(branch.FullName);
if (filterMode == Models.FilterMode.None)
{
var include = new MenuItem();
include.Icon = App.CreateMenuIcon("Icons.Filter");
include.Header = App.Text("Repository.FilterCommits.Include");
include.Click += (_, e) =>
{
_repo.SetBranchFilterMode(branch, Models.FilterMode.Included);
e.Handled = true;
};
visibility.Items.Add(include);
visibility.Items.Add(exclude);
}
else
{
var unset = new MenuItem();
unset.Header = App.Text("Repository.FilterCommits.Default");
unset.Click += (_, e) =>
{
_repo.SetBranchFilterMode(branch, Models.FilterMode.None);
e.Handled = true;
};
visibility.Items.Add(exclude);
visibility.Items.Add(unset);
}
submenu.Items.Add(visibility);
submenu.Items.Add(new MenuItem() { Header = "-" });
}
private void FillTagVisibilityMenu(MenuItem submenu, Models.Tag tag)
{
var visibility = new MenuItem();
visibility.Icon = App.CreateMenuIcon("Icons.Eye");
visibility.Header = App.Text("Repository.FilterCommits");
var exclude = new MenuItem();
exclude.Icon = App.CreateMenuIcon("Icons.EyeClose");
exclude.Header = App.Text("Repository.FilterCommits.Exclude");
exclude.Click += (_, e) =>
{
_repo.SetTagFilterMode(tag, Models.FilterMode.Excluded);
e.Handled = true;
};
var filterMode = GetFilterMode(tag.Name);
if (filterMode == Models.FilterMode.None)
{
var include = new MenuItem();
include.Icon = App.CreateMenuIcon("Icons.Filter");
include.Header = App.Text("Repository.FilterCommits.Include");
include.Click += (_, e) =>
{
_repo.SetTagFilterMode(tag, Models.FilterMode.Included);
e.Handled = true;
};
visibility.Items.Add(include);
visibility.Items.Add(exclude);
}
else
{
var unset = new MenuItem();
unset.Header = App.Text("Repository.FilterCommits.Default");
unset.Click += (_, e) =>
{
_repo.SetTagFilterMode(tag, Models.FilterMode.None);
e.Handled = true;
};
visibility.Items.Add(exclude);
visibility.Items.Add(unset);
}
submenu.Items.Add(visibility);
submenu.Items.Add(new MenuItem() { Header = "-" });
}
private void FillCurrentBranchMenu(ContextMenu menu, Models.Branch current) private void FillCurrentBranchMenu(ContextMenu menu, Models.Branch current)
{ {
var submenu = new MenuItem(); var submenu = new MenuItem();
@ -760,6 +869,8 @@ namespace SourceGit.ViewModels
submenu.Items.Add(new MenuItem() { Header = "-" }); submenu.Items.Add(new MenuItem() { Header = "-" });
} }
FillBranchVisibilityMenu(submenu, current);
var rename = new MenuItem(); var rename = new MenuItem();
rename.Header = new Views.NameHighlightedTextBlock("BranchCM.Rename", current.Name); rename.Header = new Views.NameHighlightedTextBlock("BranchCM.Rename", current.Name);
rename.Icon = App.CreateMenuIcon("Icons.Rename"); rename.Icon = App.CreateMenuIcon("Icons.Rename");
@ -819,6 +930,8 @@ namespace SourceGit.ViewModels
submenu.Items.Add(new MenuItem() { Header = "-" }); submenu.Items.Add(new MenuItem() { Header = "-" });
} }
FillBranchVisibilityMenu(submenu, branch);
var rename = new MenuItem(); var rename = new MenuItem();
rename.Header = new Views.NameHighlightedTextBlock("BranchCM.Rename", branch.Name); rename.Header = new Views.NameHighlightedTextBlock("BranchCM.Rename", branch.Name);
rename.Icon = App.CreateMenuIcon("Icons.Rename"); rename.Icon = App.CreateMenuIcon("Icons.Rename");
@ -876,6 +989,8 @@ namespace SourceGit.ViewModels
submenu.Items.Add(merge); submenu.Items.Add(merge);
submenu.Items.Add(new MenuItem() { Header = "-" }); submenu.Items.Add(new MenuItem() { Header = "-" });
FillBranchVisibilityMenu(submenu, branch);
var delete = new MenuItem(); var delete = new MenuItem();
delete.Header = new Views.NameHighlightedTextBlock("BranchCM.Delete", name); delete.Header = new Views.NameHighlightedTextBlock("BranchCM.Delete", name);
delete.Icon = App.CreateMenuIcon("Icons.Clear"); delete.Icon = App.CreateMenuIcon("Icons.Clear");
@ -922,6 +1037,8 @@ namespace SourceGit.ViewModels
submenu.Items.Add(merge); submenu.Items.Add(merge);
submenu.Items.Add(new MenuItem() { Header = "-" }); submenu.Items.Add(new MenuItem() { Header = "-" });
FillTagVisibilityMenu(submenu, tag);
var delete = new MenuItem(); var delete = new MenuItem();
delete.Header = new Views.NameHighlightedTextBlock("TagCM.Delete", tag.Name); delete.Header = new Views.NameHighlightedTextBlock("TagCM.Delete", tag.Name);
delete.Icon = App.CreateMenuIcon("Icons.Clear"); delete.Icon = App.CreateMenuIcon("Icons.Clear");

View file

@ -707,6 +707,13 @@ namespace SourceGit.ViewModels
RefreshHistoriesFilters(); RefreshHistoriesFilters();
} }
public void SetBranchFilterMode(Models.Branch branch, Models.FilterMode mode)
{
var node = FindBranchNode(branch.IsLocal ? _localBranchTrees : _remoteBranchTrees, branch.FullName);
if (node != null)
SetBranchFilterMode(node, mode);
}
public void SetBranchFilterMode(BranchTreeNode node, Models.FilterMode mode) public void SetBranchFilterMode(BranchTreeNode node, Models.FilterMode mode)
{ {
var isLocal = node.Path.StartsWith("refs/heads/", StringComparison.Ordinal); var isLocal = node.Path.StartsWith("refs/heads/", StringComparison.Ordinal);

View file

@ -1,7 +1,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using Avalonia.Threading; using Avalonia.Threading;
namespace SourceGit.ViewModels namespace SourceGit.ViewModels
@ -28,8 +30,8 @@ namespace SourceGit.ViewModels
return Task.Run(() => return Task.Run(() =>
{ {
// If it is too fast, the panel will disappear very quickly, then we'll have a bad experience. var watch = new Stopwatch();
Task.Delay(500).Wait(); watch.Start();
var rootDir = new DirectoryInfo(RootDir); var rootDir = new DirectoryInfo(RootDir);
var founded = new List<string>(); var founded = new List<string>();
@ -62,6 +64,12 @@ namespace SourceGit.ViewModels
Welcome.Instance.Refresh(); Welcome.Instance.Refresh();
}); });
// Make sure this task takes at least 0.5s to avoid that the popup panel do not disappear very quickly.
var remain = 500 - (int)watch.Elapsed.TotalMilliseconds;
watch.Stop();
if (remain > 0)
Task.Delay(remain).Wait();
return true; return true;
}); });
} }
@ -82,6 +90,13 @@ namespace SourceGit.ViewModels
var subdirs = dir.GetDirectories("*", opts); var subdirs = dir.GetDirectories("*", opts);
foreach (var subdir in subdirs) foreach (var subdir in subdirs)
{ {
if (subdir.Name.Equals("node_modules", StringComparison.Ordinal) ||
subdir.Name.Equals(".svn", StringComparison.Ordinal) ||
subdir.Name.Equals(".vs", StringComparison.Ordinal) ||
subdir.Name.Equals(".vscode", StringComparison.Ordinal) ||
subdir.Name.Equals(".idea", StringComparison.Ordinal))
continue;
SetProgressDescription($"Scanning {subdir.FullName}..."); SetProgressDescription($"Scanning {subdir.FullName}...");
var normalizedSelf = subdir.FullName.Replace("\\", "/"); var normalizedSelf = subdir.FullName.Replace("\\", "/");
@ -95,14 +110,14 @@ namespace SourceGit.ViewModels
if (test.IsSuccess && !string.IsNullOrEmpty(test.StdOut)) if (test.IsSuccess && !string.IsNullOrEmpty(test.StdOut))
{ {
var normalized = test.StdOut.Trim().Replace("\\", "/"); var normalized = test.StdOut.Trim().Replace("\\", "/");
if (!_managed.Contains(normalizedSelf)) if (!_managed.Contains(normalized))
outs.Add(normalized); outs.Add(normalized);
continue;
} }
continue;
} }
if (depth < 8) if (depth < 5)
GetUnmanagedRepositories(subdir, outs, opts, depth + 1); GetUnmanagedRepositories(subdir, outs, opts, depth + 1);
} }
} }

View file

@ -136,10 +136,12 @@ namespace SourceGit.Views
else else
{ {
var c = await Task.Run(() => detail.GetParent(sha)); var c = await Task.Run(() => detail.GetParent(sha));
if (c != null) if (c != null && ctl.IsVisible && ctl.DataContext is string newSHA && newSHA == sha)
{ {
ToolTip.SetTip(ctl, c); ToolTip.SetTip(ctl, c);
ToolTip.SetIsOpen(ctl, ctl.IsPointerOver);
if (ctl.IsPointerOver)
ToolTip.SetIsOpen(ctl, true);
} }
} }
} }