Merge branch 'release/v2025.07'

This commit is contained in:
leo 2025-03-03 09:27:04 +08:00
commit 4418214d38
No known key found for this signature in database
42 changed files with 238 additions and 134 deletions

View file

@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2024 sourcegit
Copyright (c) 2025 sourcegit
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
@ -17,4 +17,4 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View file

@ -20,7 +20,7 @@
* Clone/Fetch/Pull/Push...
* Merge/Rebase/Reset/Revert/Amend/Cherry-pick...
* Amend/Reword
* Interactive rebase (Basic)
* Interactive rebase
* Branches
* Remotes
* Tags
@ -47,7 +47,7 @@
## Translation Status
[![en_US](https://img.shields.io/badge/en__US-%E2%88%9A-brightgreen)](TRANSLATION.md) [![de__DE](https://img.shields.io/badge/de__DE-99.34%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-99.74%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-91.93%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-97.35%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-91.67%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-99.21%25-yellow)](TRANSLATION.md) [![zh__CN](https://img.shields.io/badge/zh__CN-%E2%88%9A-brightgreen)](TRANSLATION.md) [![zh__TW](https://img.shields.io/badge/zh__TW-%E2%88%9A-brightgreen)](TRANSLATION.md)
[![en_US](https://img.shields.io/badge/en__US-%E2%88%9A-brightgreen)](TRANSLATION.md) [![de__DE](https://img.shields.io/badge/de__DE-99.21%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-99.87%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-91.80%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-%E2%88%9A-brightgreen)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-91.53%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-99.07%25-yellow)](TRANSLATION.md) [![zh__CN](https://img.shields.io/badge/zh__CN-%E2%88%9A-brightgreen)](TRANSLATION.md) [![zh__TW](https://img.shields.io/badge/zh__TW-%E2%88%9A-brightgreen)](TRANSLATION.md)
> [!NOTE]
> You can find the missing keys in [TRANSLATION.md](TRANSLATION.md)

View file

@ -1,4 +1,4 @@
### de_DE.axaml: 99.34%
### de_DE.axaml: 99.21%
<details>
@ -9,21 +9,21 @@
- Text.Diff.First
- Text.Diff.Last
- Text.Preferences.AI.Streaming
- Text.StashCM.SaveAsPatch
</details>
### es_ES.axaml: 99.74%
### es_ES.axaml: 99.87%
<details>
<summary>Missing Keys</summary>
- Text.Diff.First
- Text.Diff.Last
- Text.StashCM.SaveAsPatch
</details>
### fr_FR.axaml: 91.93%
### fr_FR.axaml: 91.80%
<details>
@ -88,41 +88,23 @@
- Text.SHALinkCM.NavigateTo
- Text.Stash.AutoRestore
- Text.Stash.AutoRestore.Tip
- Text.StashCM.SaveAsPatch
- Text.WorkingCopy.CommitToEdit
- Text.WorkingCopy.SignOff
</details>
### it_IT.axaml: 97.35%
### it_IT.axaml: 100.00%
<details>
<summary>Missing Keys</summary>
- Text.AIAssistant.Regen
- Text.AIAssistant.Use
- Text.ApplyStash
- Text.ApplyStash.DropAfterApply
- Text.ApplyStash.RestoreIndex
- Text.ApplyStash.Stash
- Text.BranchCM.CustomAction
- Text.BranchUpstreamInvalid
- Text.Clone.RecurseSubmodules
- Text.Configure.CustomAction.Scope.Branch
- Text.Configure.CustomAction.WaitForExit
- Text.DeleteRepositoryNode.Path
- Text.DeleteRepositoryNode.TipForGroup
- Text.DeleteRepositoryNode.TipForRepository
- Text.Diff.First
- Text.Diff.Last
- Text.Preferences.AI.Streaming
- Text.Repository.Notifications.Clear
- Text.Stash.AutoRestore
- Text.Stash.AutoRestore.Tip
</details>
### pt_BR.axaml: 91.67%
### pt_BR.axaml: 91.53%
<details>
@ -189,12 +171,13 @@
- Text.SHALinkCM.NavigateTo
- Text.Stash.AutoRestore
- Text.Stash.AutoRestore.Tip
- Text.StashCM.SaveAsPatch
- Text.WorkingCopy.CommitToEdit
- Text.WorkingCopy.SignOff
</details>
### ru_RU.axaml: 99.21%
### ru_RU.axaml: 99.07%
<details>
@ -206,6 +189,7 @@
- Text.Diff.First
- Text.Diff.Last
- Text.Preferences.AI.Streaming
- Text.StashCM.SaveAsPatch
</details>

View file

@ -1 +1 @@
2025.06
2025.07

View file

@ -31,10 +31,7 @@ namespace SourceGit.Commands
}
catch (Exception e)
{
Dispatcher.UIThread.Invoke(() =>
{
App.RaiseException(repo, e.Message);
});
Dispatcher.UIThread.Invoke(() => App.RaiseException(repo, e.Message));
}
}
@ -87,19 +84,14 @@ namespace SourceGit.Commands
var exitCode = proc.ExitCode;
if (exitCode != 0)
{
var errMsg = builder.ToString();
Dispatcher.UIThread.Invoke(() =>
{
App.RaiseException(repo, errMsg);
});
var errMsg = builder.ToString().Trim();
if (!string.IsNullOrEmpty(errMsg))
Dispatcher.UIThread.Invoke(() => App.RaiseException(repo, errMsg));
}
}
catch (Exception e)
{
Dispatcher.UIThread.Invoke(() =>
{
App.RaiseException(repo, e.Message);
});
Dispatcher.UIThread.Invoke(() => App.RaiseException(repo, e.Message));
}
proc.Close();

View file

@ -37,6 +37,19 @@ namespace SourceGit.Commands
return true;
}
public static bool ProcessStashChanges(string repo, List<Models.DiffOption> opts, string saveTo)
{
using (var sw = File.Create(saveTo))
{
foreach (var opt in opts)
{
if (!ProcessSingleChange(repo, opt, sw))
return false;
}
}
return true;
}
private static bool ProcessSingleChange(string repo, Models.DiffOption opt, FileStream writer)
{
var starter = new ProcessStartInfo();

View file

@ -36,7 +36,7 @@ namespace SourceGit.Models
{
if (startIdx > 0)
OnReceive(buffer.Substring(0, startIdx));
var endIdx = buffer.IndexOf(">", startIdx + 1, StringComparison.Ordinal);
if (endIdx <= startIdx)
{

View file

@ -8,9 +8,9 @@ namespace SourceGit.Models
{
[GeneratedRegex(@"^https?://([-a-zA-Z0-9:%._\+~#=]+@)?[-a-zA-Z0-9:%._\+~#=]{1,256}(\.[a-zA-Z0-9()]{1,6})?(:[0-9]{1,5})?\b(/[-a-zA-Z0-9()@:%_\+.~#?&=]+)+(\.git)?$")]
private static partial Regex REG_HTTPS();
[GeneratedRegex(@"^[\w\-]+@[\w\.\-]+(\:[0-9]+)?:[\w\-/~%]+/[\w\-\.%]+(\.git)?$")]
[GeneratedRegex(@"^[\w\-]+@[\w\.\-]+(\:[0-9]+)?:([a-zA-z0-9~%][\w\-\./~%]*)?[a-zA-Z0-9](\.git)?$")]
private static partial Regex REG_SSH1();
[GeneratedRegex(@"^ssh://([\w\-]+@)?[\w\.\-]+(\:[0-9]+)?/[\w\-/~%]+/[\w\-\.%]+(\.git)?$")]
[GeneratedRegex(@"^ssh://([\w\-]+@)?[\w\.\-]+(\:[0-9]+)?/([a-zA-z0-9~%][\w\-\./~%]*)?[a-zA-Z0-9](\.git)?$")]
private static partial Regex REG_SSH2();
[GeneratedRegex(@"^git@([\w\.\-]+):([\w\-/~%]+/[\w\-\.%]+)\.git$")]

View file

@ -50,12 +50,6 @@ namespace SourceGit.Models
set;
} = true;
public DealWithLocalChanges DealWithLocalChangesOnCheckoutBranch
{
get;
set;
} = DealWithLocalChanges.DoNothing;
public bool EnableForceOnFetch
{
get;
@ -68,12 +62,6 @@ namespace SourceGit.Models
set;
} = false;
public DealWithLocalChanges DealWithLocalChangesOnPull
{
get;
set;
} = DealWithLocalChanges.DoNothing;
public bool PreferRebaseInsteadOfMerge
{
get;
@ -116,12 +104,6 @@ namespace SourceGit.Models
set;
} = false;
public DealWithLocalChanges DealWithLocalChangesOnCreateBranch
{
get;
set;
} = DealWithLocalChanges.DoNothing;
public bool CheckoutBranchOnCreateBranch
{
get;

View file

@ -65,13 +65,16 @@ namespace SourceGit.Native
{
var home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
var cwd = string.IsNullOrEmpty(workdir) ? home : workdir;
var terminal = OS.ShellOrTerminal;
var startInfo = new ProcessStartInfo();
startInfo.WorkingDirectory = cwd;
startInfo.FileName = OS.ShellOrTerminal;
startInfo.FileName = terminal;
if (OS.ShellOrTerminal.EndsWith("wezterm", StringComparison.OrdinalIgnoreCase))
if (terminal.EndsWith("wezterm", StringComparison.OrdinalIgnoreCase))
startInfo.Arguments = $"start --cwd \"{cwd}\"";
else if (terminal.EndsWith("ptyxis", StringComparison.OrdinalIgnoreCase))
startInfo.Arguments = $"--new-window --working-directory=\"{cwd}\"";
try
{

View file

@ -6,7 +6,6 @@
<x:String x:Key="Text.About.Menu" xml:space="preserve">Über SourceGit</x:String>
<x:String x:Key="Text.About.BuildWith" xml:space="preserve">• Erstellt mit </x:String>
<x:String x:Key="Text.About.Chart" xml:space="preserve">• Grafik gerendert durch </x:String>
<x:String x:Key="Text.About.Copyright" xml:space="preserve">© 2024 sourcegit-scm</x:String>
<x:String x:Key="Text.About.Editor" xml:space="preserve">• Texteditor von </x:String>
<x:String x:Key="Text.About.Fonts" xml:space="preserve">• Monospace-Schriftarten von </x:String>
<x:String x:Key="Text.About.SourceCode" xml:space="preserve">• Quelltext findest du auf </x:String>

View file

@ -3,7 +3,6 @@
<x:String x:Key="Text.About.Menu" xml:space="preserve">About SourceGit</x:String>
<x:String x:Key="Text.About.BuildWith" xml:space="preserve">• Build with </x:String>
<x:String x:Key="Text.About.Chart" xml:space="preserve">• Chart is rendered by </x:String>
<x:String x:Key="Text.About.Copyright" xml:space="preserve">© 2024 sourcegit-scm</x:String>
<x:String x:Key="Text.About.Editor" xml:space="preserve">• TextEditor from </x:String>
<x:String x:Key="Text.About.Fonts" xml:space="preserve">• Monospace fonts come from </x:String>
<x:String x:Key="Text.About.SourceCode" xml:space="preserve">• Source code can be found at </x:String>
@ -669,6 +668,7 @@
<x:String x:Key="Text.StashCM.Apply" xml:space="preserve">Apply</x:String>
<x:String x:Key="Text.StashCM.Drop" xml:space="preserve">Drop</x:String>
<x:String x:Key="Text.StashCM.Pop" xml:space="preserve">Pop</x:String>
<x:String x:Key="Text.StashCM.SaveAsPatch" xml:space="preserve">Save as Patch...</x:String>
<x:String x:Key="Text.StashDropConfirm" xml:space="preserve">Drop Stash</x:String>
<x:String x:Key="Text.StashDropConfirm.Label" xml:space="preserve">Drop:</x:String>
<x:String x:Key="Text.Stashes" xml:space="preserve">STASHES</x:String>

View file

@ -6,7 +6,6 @@
<x:String x:Key="Text.About.Menu" xml:space="preserve">Acerca de SourceGit</x:String>
<x:String x:Key="Text.About.BuildWith" xml:space="preserve">• Construido con </x:String>
<x:String x:Key="Text.About.Chart" xml:space="preserve">• El gráfico es renderizado por </x:String>
<x:String x:Key="Text.About.Copyright" xml:space="preserve">© 2024 sourcegit-scm</x:String>
<x:String x:Key="Text.About.Editor" xml:space="preserve">• Editor de texto de </x:String>
<x:String x:Key="Text.About.Fonts" xml:space="preserve">• Las fuentes monoespaciadas provienen de </x:String>
<x:String x:Key="Text.About.SourceCode" xml:space="preserve">• El código fuente se puede encontrar en </x:String>
@ -253,7 +252,9 @@
<x:String x:Key="Text.Diff.Binary.Old" xml:space="preserve">ANTIGUO</x:String>
<x:String x:Key="Text.Diff.Copy" xml:space="preserve">Copiar</x:String>
<x:String x:Key="Text.Diff.FileModeChanged" xml:space="preserve">Modo de Archivo Cambiado</x:String>
<x:String x:Key="Text.Diff.First" xml:space="preserve">Primera Diferencia</x:String>
<x:String x:Key="Text.Diff.IgnoreWhitespace" xml:space="preserve">Ignorar Cambio de Espacios en Blanco</x:String>
<x:String x:Key="Text.Diff.Last" xml:space="preserve">Última Diferencia</x:String>
<x:String x:Key="Text.Diff.LFS" xml:space="preserve">CAMBIO DE OBJETO LFS</x:String>
<x:String x:Key="Text.Diff.Next" xml:space="preserve">Siguiente Diferencia</x:String>
<x:String x:Key="Text.Diff.NoChange" xml:space="preserve">SIN CAMBIOS O SOLO CAMBIOS DE EOL</x:String>

View file

@ -6,7 +6,6 @@
<x:String x:Key="Text.About.Menu" xml:space="preserve">À propos de SourceGit</x:String>
<x:String x:Key="Text.About.BuildWith" xml:space="preserve">• Compilé avec </x:String>
<x:String x:Key="Text.About.Chart" xml:space="preserve">• Le graphique est rendu par </x:String>
<x:String x:Key="Text.About.Copyright" xml:space="preserve">© 2024 sourcegit-scm</x:String>
<x:String x:Key="Text.About.Editor" xml:space="preserve">• TextEditor de </x:String>
<x:String x:Key="Text.About.Fonts" xml:space="preserve">• Les polices Monospace proviennent de </x:String>
<x:String x:Key="Text.About.SourceCode" xml:space="preserve">• Le code source est disponible sur </x:String>

View file

@ -6,7 +6,6 @@
<x:String x:Key="Text.About.Menu" xml:space="preserve">Informazioni su SourceGit</x:String>
<x:String x:Key="Text.About.BuildWith" xml:space="preserve">• Creato con </x:String>
<x:String x:Key="Text.About.Chart" xml:space="preserve">• Il grafico è reso da </x:String>
<x:String x:Key="Text.About.Copyright" xml:space="preserve">© 2024 sourcegit-scm</x:String>
<x:String x:Key="Text.About.Editor" xml:space="preserve">• Editor di testo da </x:String>
<x:String x:Key="Text.About.Fonts" xml:space="preserve">• I font monospaziati provengono da </x:String>
<x:String x:Key="Text.About.SourceCode" xml:space="preserve">• Il codice sorgente è disponibile su </x:String>
@ -22,7 +21,9 @@
<x:String x:Key="Text.AddWorktree.Tracking" xml:space="preserve">Traccia Branch:</x:String>
<x:String x:Key="Text.AddWorktree.Tracking.Toggle" xml:space="preserve">Traccia branch remoto</x:String>
<x:String x:Key="Text.AIAssistant" xml:space="preserve">Assistente AI</x:String>
<x:String x:Key="Text.AIAssistant.Regen" xml:space="preserve">RIGENERA</x:String>
<x:String x:Key="Text.AIAssistant.Tip" xml:space="preserve">Usa AI per generare il messaggio di commit</x:String>
<x:String x:Key="Text.AIAssistant.Use" xml:space="preserve">APPLICA COME MESSAGGIO DI COMMIT</x:String>
<x:String x:Key="Text.Apply" xml:space="preserve">Applica</x:String>
<x:String x:Key="Text.Apply.Error" xml:space="preserve">Errore</x:String>
<x:String x:Key="Text.Apply.Error.Desc" xml:space="preserve">Genera errori e si rifiuta di applicare la patch</x:String>
@ -37,6 +38,10 @@
<x:String x:Key="Text.Apply.Warn" xml:space="preserve">Avviso</x:String>
<x:String x:Key="Text.Apply.Warn.Desc" xml:space="preserve">Mostra avvisi per alcuni errori, ma applica comunque</x:String>
<x:String x:Key="Text.Apply.WS" xml:space="preserve">Spazi:</x:String>
<x:String x:Key="Text.ApplyStash" xml:space="preserve">Applica lo stash</x:String>
<x:String x:Key="Text.ApplyStash.DropAfterApply" xml:space="preserve">Rimuovi dopo aver applicato</x:String>
<x:String x:Key="Text.ApplyStash.RestoreIndex" xml:space="preserve">Ripristina le modifiche all'indice</x:String>
<x:String x:Key="Text.ApplyStash.Stash" xml:space="preserve">Stash:</x:String>
<x:String x:Key="Text.Archive" xml:space="preserve">Archivia...</x:String>
<x:String x:Key="Text.Archive.File" xml:space="preserve">Salva Archivio In:</x:String>
<x:String x:Key="Text.Archive.File.Placeholder" xml:space="preserve">Seleziona il percorso del file archivio</x:String>
@ -53,6 +58,7 @@
<x:String x:Key="Text.BranchCM.CompareWithHead" xml:space="preserve">Confronta con HEAD</x:String>
<x:String x:Key="Text.BranchCM.CompareWithWorktree" xml:space="preserve">Confronta con Worktree</x:String>
<x:String x:Key="Text.BranchCM.CopyName" xml:space="preserve">Copia Nome Branch</x:String>
<x:String x:Key="Text.BranchCM.CustomAction" xml:space="preserve">Azione personalizzata</x:String>
<x:String x:Key="Text.BranchCM.Delete" xml:space="preserve">Elimina ${0}$...</x:String>
<x:String x:Key="Text.BranchCM.DeleteMultiBranches" xml:space="preserve">Elimina i {0} branch selezionati</x:String>
<x:String x:Key="Text.BranchCM.DiscardAll" xml:space="preserve">Scarta tutte le modifiche</x:String>
@ -68,6 +74,7 @@
<x:String x:Key="Text.BranchCM.Rename" xml:space="preserve">Rinomina ${0}$...</x:String>
<x:String x:Key="Text.BranchCM.Tracking" xml:space="preserve">Imposta Branch di Tracciamento...</x:String>
<x:String x:Key="Text.BranchCompare" xml:space="preserve">Confronto Branch</x:String>
<x:String x:Key="Text.BranchUpstreamInvalid" xml:space="preserve">Upstream non valido</x:String>
<x:String x:Key="Text.Bytes" xml:space="preserve">Byte</x:String>
<x:String x:Key="Text.Cancel" xml:space="preserve">ANNULLA</x:String>
<x:String x:Key="Text.ChangeCM.CheckoutThisRevision" xml:space="preserve">Ripristina Questa Revisione</x:String>
@ -100,6 +107,7 @@
<x:String x:Key="Text.Clone.LocalName" xml:space="preserve">Nome Locale:</x:String>
<x:String x:Key="Text.Clone.LocalName.Placeholder" xml:space="preserve">Nome del repository. Facoltativo.</x:String>
<x:String x:Key="Text.Clone.ParentFolder" xml:space="preserve">Cartella Principale:</x:String>
<x:String x:Key="Text.Clone.RecurseSubmodules" xml:space="preserve">Inizializza e aggiorna i sottomoduli</x:String>
<x:String x:Key="Text.Clone.RemoteURL" xml:space="preserve">URL del Repository:</x:String>
<x:String x:Key="Text.Close" xml:space="preserve">CHIUDI</x:String>
<x:String x:Key="Text.CodeEditor" xml:space="preserve">Editor</x:String>
@ -152,8 +160,10 @@
<x:String x:Key="Text.Configure.CustomAction.Executable" xml:space="preserve">File Eseguibile:</x:String>
<x:String x:Key="Text.Configure.CustomAction.Name" xml:space="preserve">Nome:</x:String>
<x:String x:Key="Text.Configure.CustomAction.Scope" xml:space="preserve">Ambito:</x:String>
<x:String x:Key="Text.Configure.CustomAction.Scope.Branch" xml:space="preserve">Branch</x:String>
<x:String x:Key="Text.Configure.CustomAction.Scope.Commit" xml:space="preserve">Commit</x:String>
<x:String x:Key="Text.Configure.CustomAction.Scope.Repository" xml:space="preserve">Repository</x:String>
<x:String x:Key="Text.Configure.CustomAction.WaitForExit" xml:space="preserve">Attendi la fine dell'azione</x:String>
<x:String x:Key="Text.Configure.Email" xml:space="preserve">Indirizzo Email</x:String>
<x:String x:Key="Text.Configure.Email.Placeholder" xml:space="preserve">Indirizzo email</x:String>
<x:String x:Key="Text.Configure.Git" xml:space="preserve">GIT</x:String>
@ -226,7 +236,10 @@
<x:String x:Key="Text.DeleteMultiBranch.Tip" xml:space="preserve">Stai per eliminare più branch contemporaneamente. Controlla attentamente prima di procedere!</x:String>
<x:String x:Key="Text.DeleteRemote" xml:space="preserve">Elimina Remoto</x:String>
<x:String x:Key="Text.DeleteRemote.Remote" xml:space="preserve">Remoto:</x:String>
<x:String x:Key="Text.DeleteRepositoryNode.Path" xml:space="preserve">Percorso:</x:String>
<x:String x:Key="Text.DeleteRepositoryNode.Target" xml:space="preserve">Destinazione:</x:String>
<x:String x:Key="Text.DeleteRepositoryNode.TipForGroup" xml:space="preserve">Tutti i figli verranno rimossi dalla lista.</x:String>
<x:String x:Key="Text.DeleteRepositoryNode.TipForRepository" xml:space="preserve">Lo rimuoverà solamente dalla lista, non dal disco!</x:String>
<x:String x:Key="Text.DeleteRepositoryNode.TitleForGroup" xml:space="preserve">Conferma Eliminazione Gruppo</x:String>
<x:String x:Key="Text.DeleteRepositoryNode.TitleForRepository" xml:space="preserve">Conferma Eliminazione Repository</x:String>
<x:String x:Key="Text.DeleteSubmodule" xml:space="preserve">Elimina Sottomodulo</x:String>
@ -239,7 +252,9 @@
<x:String x:Key="Text.Diff.Binary.Old" xml:space="preserve">VECCHIO</x:String>
<x:String x:Key="Text.Diff.Copy" xml:space="preserve">Copia</x:String>
<x:String x:Key="Text.Diff.FileModeChanged" xml:space="preserve">Modalità File Modificata</x:String>
<x:String x:Key="Text.Diff.First" xml:space="preserve">Prima differenza</x:String>
<x:String x:Key="Text.Diff.IgnoreWhitespace" xml:space="preserve">Ignora Modifiche agli Spazi</x:String>
<x:String x:Key="Text.Diff.Last" xml:space="preserve">Ultima differenza</x:String>
<x:String x:Key="Text.Diff.LFS" xml:space="preserve">MODIFICA OGGETTO LFS</x:String>
<x:String x:Key="Text.Diff.Next" xml:space="preserve">Differenza Successiva</x:String>
<x:String x:Key="Text.Diff.NoChange" xml:space="preserve">NESSUNA MODIFICA O SOLO CAMBIAMENTI DI FINE LINEA</x:String>
@ -450,6 +465,7 @@
<x:String x:Key="Text.Preferences.AI.Model" xml:space="preserve">Modello</x:String>
<x:String x:Key="Text.Preferences.AI.Name" xml:space="preserve">Nome</x:String>
<x:String x:Key="Text.Preferences.AI.Server" xml:space="preserve">Server</x:String>
<x:String x:Key="Text.Preferences.AI.Streaming" xml:space="preserve">Abilita streaming</x:String>
<x:String x:Key="Text.Preferences.Appearance" xml:space="preserve">ASPETTO</x:String>
<x:String x:Key="Text.Preferences.Appearance.DefaultFont" xml:space="preserve">Font Predefinito</x:String>
<x:String x:Key="Text.Preferences.Appearance.FontSize" xml:space="preserve">Font Size</x:String>
@ -578,6 +594,7 @@
<x:String x:Key="Text.Repository.LocalBranches" xml:space="preserve">BRANCH LOCALI</x:String>
<x:String x:Key="Text.Repository.NavigateToCurrentHead" xml:space="preserve">Vai a HEAD</x:String>
<x:String x:Key="Text.Repository.NewBranch" xml:space="preserve">Crea Branch</x:String>
<x:String x:Key="Text.Repository.Notifications.Clear" xml:space="preserve">CANCELLA LE NOTIFICHE</x:String>
<x:String x:Key="Text.Repository.OnlyHighlightCurrentBranchInHistories" xml:space="preserve">Evidenzia nel grafico solo il branch corrente</x:String>
<x:String x:Key="Text.Repository.OpenIn" xml:space="preserve">Apri in {0}</x:String>
<x:String x:Key="Text.Repository.OpenWithExternalTools" xml:space="preserve">Apri in Strumenti Esterni</x:String>
@ -644,6 +661,8 @@
<x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">Percorso per la chiave SSH privata</x:String>
<x:String x:Key="Text.Start" xml:space="preserve">AVVIA</x:String>
<x:String x:Key="Text.Stash" xml:space="preserve">Stasha</x:String>
<x:String x:Key="Text.Stash.AutoRestore" xml:space="preserve">Auto-ripristino dopo lo stash</x:String>
<x:String x:Key="Text.Stash.AutoRestore.Tip" xml:space="preserve">I tuoi file di lavoro rimangono inalterati, ma viene salvato uno stash.</x:String>
<x:String x:Key="Text.Stash.IncludeUntracked" xml:space="preserve">Includi file non tracciati</x:String>
<x:String x:Key="Text.Stash.KeepIndex" xml:space="preserve">Mantieni file in stage</x:String>
<x:String x:Key="Text.Stash.Message" xml:space="preserve">Messaggio:</x:String>
@ -654,6 +673,7 @@
<x:String x:Key="Text.StashCM.Apply" xml:space="preserve">Applica</x:String>
<x:String x:Key="Text.StashCM.Drop" xml:space="preserve">Elimina</x:String>
<x:String x:Key="Text.StashCM.Pop" xml:space="preserve">Estrai</x:String>
<x:String x:Key="Text.StashCM.SaveAsPatch" xml:space="preserve">Salva come Patch...</x:String>
<x:String x:Key="Text.StashDropConfirm" xml:space="preserve">Elimina Stash</x:String>
<x:String x:Key="Text.StashDropConfirm.Label" xml:space="preserve">Elimina:</x:String>
<x:String x:Key="Text.Stashes" xml:space="preserve">STASH</x:String>

View file

@ -31,7 +31,6 @@
<x:String x:Key="Text.About.Menu" xml:space="preserve">Sobre o SourceGit</x:String>
<x:String x:Key="Text.About.BuildWith" xml:space="preserve">• Construído com </x:String>
<x:String x:Key="Text.About.Chart" xml:space="preserve">• Gráfico desenhado por </x:String>
<x:String x:Key="Text.About.Copyright" xml:space="preserve">© 2024 sourcegit-scm</x:String>
<x:String x:Key="Text.About.Editor" xml:space="preserve">• Editor de Texto de </x:String>
<x:String x:Key="Text.About.Fonts" xml:space="preserve">• Fontes monoespaçadas de </x:String>
<x:String x:Key="Text.About.SourceCode" xml:space="preserve">• Código-fonte pode ser encontrado em </x:String>

View file

@ -6,7 +6,6 @@
<x:String x:Key="Text.About.Menu" xml:space="preserve">О SourceGit</x:String>
<x:String x:Key="Text.About.BuildWith" xml:space="preserve">• Сборка с </x:String>
<x:String x:Key="Text.About.Chart" xml:space="preserve">• Диаграмма отображается с помощью</x:String>
<x:String x:Key="Text.About.Copyright" xml:space="preserve">© 2024 sourcegit-scm</x:String>
<x:String x:Key="Text.About.Editor" xml:space="preserve">• Текстовый редактор от </x:String>
<x:String x:Key="Text.About.Fonts" xml:space="preserve">• Моноширинные шрифты взяты из </x:String>
<x:String x:Key="Text.About.SourceCode" xml:space="preserve">• Исходный код можно найти по адресу </x:String>

View file

@ -6,7 +6,6 @@
<x:String x:Key="Text.About.Menu" xml:space="preserve">关于本软件</x:String>
<x:String x:Key="Text.About.BuildWith" xml:space="preserve">• 项目依赖于 </x:String>
<x:String x:Key="Text.About.Chart" xml:space="preserve">• 图表绘制组件来自 </x:String>
<x:String x:Key="Text.About.Copyright" xml:space="preserve">© 2024 sourcegit-scm</x:String>
<x:String x:Key="Text.About.Editor" xml:space="preserve">• 文本编辑器使用 </x:String>
<x:String x:Key="Text.About.Fonts" xml:space="preserve">• 等宽字体来自于 </x:String>
<x:String x:Key="Text.About.SourceCode" xml:space="preserve">• 项目源代码地址 </x:String>
@ -673,6 +672,7 @@
<x:String x:Key="Text.StashCM.Apply" xml:space="preserve">应用(apply)</x:String>
<x:String x:Key="Text.StashCM.Drop" xml:space="preserve">删除(drop)</x:String>
<x:String x:Key="Text.StashCM.Pop" xml:space="preserve">应用并删除(pop)</x:String>
<x:String x:Key="Text.StashCM.SaveAsPatch" xml:space="preserve">另存为补丁...</x:String>
<x:String x:Key="Text.StashDropConfirm" xml:space="preserve">丢弃贮藏确认</x:String>
<x:String x:Key="Text.StashDropConfirm.Label" xml:space="preserve">丢弃贮藏 </x:String>
<x:String x:Key="Text.Stashes" xml:space="preserve">贮藏列表</x:String>

View file

@ -6,7 +6,6 @@
<x:String x:Key="Text.About.Menu" xml:space="preserve">關於 SourceGit</x:String>
<x:String x:Key="Text.About.BuildWith" xml:space="preserve">• 專案依賴於 </x:String>
<x:String x:Key="Text.About.Chart" xml:space="preserve">• 圖表繪製元件來自 </x:String>
<x:String x:Key="Text.About.Copyright" xml:space="preserve">© 2024 sourcegit-scm</x:String>
<x:String x:Key="Text.About.Editor" xml:space="preserve">• 文字編輯器使用 </x:String>
<x:String x:Key="Text.About.Fonts" xml:space="preserve">• 等寬字型來自於 </x:String>
<x:String x:Key="Text.About.SourceCode" xml:space="preserve">• 專案原始碼網址 </x:String>
@ -672,6 +671,7 @@
<x:String x:Key="Text.StashCM.Apply" xml:space="preserve">套用 (apply)</x:String>
<x:String x:Key="Text.StashCM.Drop" xml:space="preserve">刪除 (drop)</x:String>
<x:String x:Key="Text.StashCM.Pop" xml:space="preserve">套用並刪除 (pop)</x:String>
<x:String x:Key="Text.StashCM.SaveAsPatch" xml:space="preserve">另存為修補檔 (patch)...</x:String>
<x:String x:Key="Text.StashDropConfirm" xml:space="preserve">捨棄擱置變更確認</x:String>
<x:String x:Key="Text.StashDropConfirm.Label" xml:space="preserve">捨棄擱置變更:</x:String>
<x:String x:Key="Text.Stashes" xml:space="preserve">擱置變更</x:String>

View file

@ -13,7 +13,7 @@
<Product>SourceGit</Product>
<Description>OpenSource GIT client</Description>
<Company>sourcegit-scm</Company>
<Copyright>Copyright © 2024 sourcegit-scm.</Copyright>
<Copyright>Copyright © $([System.DateTime]::Now.Year) sourcegit-scm.</Copyright>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/sourcegit-scm/sourcegit.git</PackageProjectUrl>
<RepositoryUrl>https://github.com/sourcegit-scm/sourcegit.git</RepositoryUrl>
@ -41,15 +41,15 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Avalonia" Version="11.2.4" />
<PackageReference Include="Avalonia.Desktop" Version="11.2.4" />
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.2.4" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.2.4" />
<PackageReference Include="Avalonia.Diagnostics" Version="11.2.4" Condition="'$(Configuration)' == 'Debug'" />
<PackageReference Include="Avalonia" Version="11.2.5" />
<PackageReference Include="Avalonia.Desktop" Version="11.2.5" />
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.2.5" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.2.5" />
<PackageReference Include="Avalonia.Diagnostics" Version="11.2.5" Condition="'$(Configuration)' == 'Debug'" />
<PackageReference Include="Avalonia.AvaloniaEdit" Version="11.1.0" />
<PackageReference Include="AvaloniaEdit.TextMate" Version="11.1.0" />
<PackageReference Include="Azure.AI.OpenAI" Version="2.2.0-beta.2" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.3.2" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageReference Include="LiveChartsCore.SkiaSharpView.Avalonia" Version="2.0.0-rc5.4" />
<PackageReference Include="OpenAI" Version="2.2.0-beta.2" />
<PackageReference Include="TextMateSharp" Version="1.0.66" />

View file

@ -11,9 +11,9 @@ namespace SourceGit.ViewModels
public Models.DealWithLocalChanges PreAction
{
get => _repo.Settings.DealWithLocalChangesOnCheckoutBranch;
set => _repo.Settings.DealWithLocalChangesOnCheckoutBranch = value;
}
get;
set;
} = Models.DealWithLocalChanges.DoNothing;
public Checkout(Repository repo, string branch)
{

View file

@ -25,8 +25,15 @@ namespace SourceGit.ViewModels
public int ActivePageIndex
{
get => _activePageIndex;
set => SetProperty(ref _activePageIndex, value);
get => _repo.CommitDetailActivePageIndex;
set
{
if (_repo.CommitDetailActivePageIndex != value)
{
_repo.CommitDetailActivePageIndex = value;
OnPropertyChanged();
}
}
}
public Models.Commit Commit
@ -617,11 +624,7 @@ namespace SourceGit.ViewModels
_changes = null;
_revisionFiles.Clear();
FullMessage = string.Empty;
SignInfo = null;
Changes = [];
VisibleChanges = null;
SelectedChanges = null;
ViewRevisionFileContent = null;
Children.Clear();
RevisionFileSearchFilter = string.Empty;
@ -683,6 +686,9 @@ namespace SourceGit.ViewModels
{
Changes = changes;
VisibleChanges = visible;
if (visible.Count == 0)
SelectedChanges = null;
});
}
});
@ -821,7 +827,6 @@ namespace SourceGit.ViewModels
};
private Repository _repo = null;
private int _activePageIndex = 0;
private Models.Commit _commit = null;
private string _fullMessage = string.Empty;
private Models.CommitSignInfo _signInfo = null;

View file

@ -21,9 +21,9 @@ namespace SourceGit.ViewModels
public Models.DealWithLocalChanges PreAction
{
get => _repo.Settings.DealWithLocalChangesOnCreateBranch;
set => _repo.Settings.DealWithLocalChangesOnCreateBranch = value;
}
get;
set;
} = Models.DealWithLocalChanges.DoNothing;
public bool CheckoutAfterCreated
{

View file

@ -561,13 +561,7 @@ namespace SourceGit.ViewModels
_repo.ShowPopup(new CheckoutCommit(_repo, commit));
e.Handled = true;
};
menu.Items.Add(checkoutCommit);
}
menu.Items.Add(new MenuItem() { Header = "-" });
if (commit.IsMerged && current.Head != commit.SHA)
{
var interactiveRebase = new MenuItem();
interactiveRebase.Header = new Views.NameHighlightedTextBlock("CommitCM.InteractiveRebase", current.Name);
interactiveRebase.Icon = App.CreateMenuIcon("Icons.InteractiveRebase");
@ -586,9 +580,13 @@ namespace SourceGit.ViewModels
e.Handled = true;
};
menu.Items.Add(interactiveRebase);
menu.Items.Add(checkoutCommit);
menu.Items.Add(new MenuItem() { Header = "-" });
menu.Items.Add(interactiveRebase);
}
menu.Items.Add(new MenuItem() { Header = "-" });
}
if (current.Head != commit.SHA)

View file

@ -118,7 +118,7 @@ namespace SourceGit.ViewModels
Task.Run(() =>
{
var commits = new Commands.QueryCommitsWithFullMessage(repoPath, $"{on.SHA}...HEAD").Result();
var commits = new Commands.QueryCommitsWithFullMessage(repoPath, $"{on.SHA}..HEAD").Result();
var list = new List<InteractiveRebaseItem>();
foreach (var c in commits)

View file

@ -71,7 +71,7 @@ namespace SourceGit.ViewModels
public async void ProcessPopup()
{
if (_popup != null)
if (_popup is { InProgress: false })
{
if (!_popup.Check())
return;

View file

@ -40,9 +40,9 @@ namespace SourceGit.ViewModels
public Models.DealWithLocalChanges PreAction
{
get => _repo.Settings.DealWithLocalChangesOnPull;
set => _repo.Settings.DealWithLocalChangesOnPull = value;
}
get;
set;
} = Models.DealWithLocalChanges.DoNothing;
public bool UseRebase
{

View file

@ -453,6 +453,12 @@ namespace SourceGit.ViewModels
private set => SetProperty(ref _isAutoFetching, value);
}
public int CommitDetailActivePageIndex
{
get;
set;
} = 0;
public Repository(bool isBare, string path, string gitDir)
{
IsBare = isBare;
@ -657,6 +663,12 @@ namespace SourceGit.ViewModels
return;
}
if (_currentBranch == null)
{
App.RaiseException(_fullpath, "Can NOT found current branch!!!");
return;
}
var pull = new Pull(this, null);
if (autoStart && pull.SelectedBranch != null)
ShowAndStartPopup(pull);

View file

@ -4,6 +4,7 @@ using System.IO;
using System.Threading.Tasks;
using Avalonia.Controls;
using Avalonia.Platform.Storage;
using Avalonia.Threading;
using CommunityToolkit.Mvvm.ComponentModel;
@ -88,7 +89,7 @@ namespace SourceGit.ViewModels
private set
{
if (SetProperty(ref _changes, value))
SelectedChange = null;
SelectedChange = value is { Count: > 0 } ? value[0] : null;
}
}
@ -157,9 +158,45 @@ namespace SourceGit.ViewModels
ev.Handled = true;
};
var patch = new MenuItem();
patch.Header = App.Text("StashCM.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("StashCM.SaveAsPatch");
options.DefaultExtension = ".patch";
options.FileTypeChoices = [new FilePickerFileType("Patch File") { Patterns = ["*.patch"] }];
var storageFile = await storageProvider.SaveFilePickerAsync(options);
if (storageFile != null)
{
var opts = new List<Models.DiffOption>();
foreach (var c in _changes)
{
if (_untrackedChanges.Contains(c.Path))
opts.Add(new Models.DiffOption("4b825dc642cb6eb9a060e54bf8d69288fbee4904", _selectedStash.Parents[2], c));
else
opts.Add(new Models.DiffOption(_selectedStash.Parents[0], _selectedStash.SHA, c));
}
var succ = await Task.Run(() => Commands.SaveChangesAsPatch.ProcessStashChanges(_repo.FullPath, opts, storageFile.Path.LocalPath));
if (succ)
App.SendNotification(_repo.FullPath, App.Text("SaveAsPatchSuccess"));
}
e.Handled = true;
};
var menu = new ContextMenu();
menu.Items.Add(apply);
menu.Items.Add(drop);
menu.Items.Add(new MenuItem { Header = "-" });
menu.Items.Add(patch);
return menu;
}

View file

@ -445,6 +445,10 @@ namespace SourceGit.ViewModels
_repo.SetWatcherEnabled(false);
Task.Run(() =>
{
var mergeMsgFile = Path.Combine(_repo.GitDir, "MERGE_MSG");
if (File.Exists(mergeMsgFile) && !string.IsNullOrWhiteSpace(_commitMessage))
File.WriteAllText(mergeMsgFile, _commitMessage);
var succ = _inProgressContext.Continue();
Dispatcher.UIThread.Invoke(() =>
{
@ -725,8 +729,8 @@ namespace SourceGit.ViewModels
byParentFolder.IsVisible = !isRooted;
byParentFolder.Click += (_, e) =>
{
var path = Path.GetDirectoryName(change.Path).Replace("\\", "/");
Commands.GitIgnore.Add(_repo.FullPath, path + "/");
var dir = Path.GetDirectoryName(change.Path).Replace("\\", "/");
Commands.GitIgnore.Add(_repo.FullPath, dir + "/");
e.Handled = true;
};
addToIgnore.Items.Add(byParentFolder);
@ -747,8 +751,8 @@ namespace SourceGit.ViewModels
byExtensionInSameFolder.IsVisible = !isRooted;
byExtensionInSameFolder.Click += (_, e) =>
{
var path = Path.GetDirectoryName(change.Path).Replace("\\", "/");
Commands.GitIgnore.Add(_repo.FullPath, path + "/*" + extension);
var dir = Path.GetDirectoryName(change.Path).Replace("\\", "/");
Commands.GitIgnore.Add(_repo.FullPath, dir + "/*" + extension);
e.Handled = true;
};
addToIgnore.Items.Add(byExtensionInSameFolder);
@ -1466,7 +1470,7 @@ namespace SourceGit.ViewModels
return unstaged;
var visible = new List<Models.Change>();
foreach (var c in unstaged)
{
if (c.Path.Contains(_unstagedFilter, StringComparison.OrdinalIgnoreCase))

View file

@ -52,7 +52,7 @@
<TextBlock Margin="2,0,0,0" Text="{DynamicResource Text.About.SubTitle}" FontSize="16"/>
<TextBlock Margin="2,8,0,0" Text="{DynamicResource Text.About.Copyright}" Foreground="{DynamicResource Brush.FG2}"/>
<TextBlock Margin="2,8,0,0" Text="{Binding Copyright}" Foreground="{DynamicResource Brush.FG2}"/>
<StackPanel Orientation="Vertical" Margin="0,24,0,0">
<StackPanel Orientation="Horizontal" Height="18">

View file

@ -11,11 +11,21 @@ namespace SourceGit.Views
private set;
}
public string Copyright
{
get;
private set;
}
public About()
{
var ver = Assembly.GetExecutingAssembly().GetName().Version;
if (ver != null)
Version = $"{ver.Major}.{ver.Minor}";
var attributes = Assembly.GetExecutingAssembly()
.GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);
if (attributes.Length > 0)
Copyright = ((AssemblyCopyrightAttribute)attributes[0]).Copyright;
DataContext = this;
InitializeComponent();

View file

@ -134,6 +134,7 @@
<v:ChangeCollectionView ViewMode="{Binding Source={x:Static vm:Preferences.Instance}, Path=CommitChangeViewMode}"
Changes="{Binding VisibleChanges}"
SelectedChanges="{Binding SelectedChanges, Mode=TwoWay}"
AutoSelectFirstChange="True"
ContextRequested="OnChangeContextRequested"/>
</Border>
</Grid>

View file

@ -85,6 +85,15 @@ namespace SourceGit.Views
set => SetValue(ChangesProperty, value);
}
public static readonly StyledProperty<bool> AutoSelectFirstChangeProperty =
AvaloniaProperty.Register<ChangeCollectionView, bool>(nameof(AutoSelectFirstChange), false);
public bool AutoSelectFirstChange
{
get => GetValue(AutoSelectFirstChangeProperty);
set => SetValue(AutoSelectFirstChangeProperty, value);
}
public static readonly StyledProperty<List<Models.Change>> SelectedChangesProperty =
AvaloniaProperty.Register<ChangeCollectionView, List<Models.Change>>(nameof(SelectedChanges));
@ -205,9 +214,9 @@ namespace SourceGit.Views
base.OnPropertyChanged(change);
if (change.Property == ViewModeProperty)
UpdateDataSource(false);
else if (change.Property == ChangesProperty)
UpdateDataSource(true);
else if (change.Property == ChangesProperty)
UpdateDataSource(false);
else if (change.Property == SelectedChangesProperty)
UpdateSelection();
}
@ -292,9 +301,9 @@ namespace SourceGit.Views
}
}
private void UpdateDataSource(bool disableEvents)
private void UpdateDataSource(bool onlyViewModeChange)
{
_disableSelectionChangingEvent = disableEvents;
_disableSelectionChangingEvent = !onlyViewModeChange;
var changes = Changes;
if (changes == null || changes.Count == 0)
@ -324,7 +333,19 @@ namespace SourceGit.Views
MakeTreeRows(rows, tree.Tree);
tree.Rows.AddRange(rows);
if (selected.Count > 0)
if (!onlyViewModeChange && AutoSelectFirstChange)
{
foreach (var row in tree.Rows)
{
if (row.Change != null)
{
tree.SelectedRows.Add(row);
SetCurrentValue(SelectedChangesProperty, [row.Change]);
break;
}
}
}
else if (selected.Count > 0)
{
var sets = new HashSet<Models.Change>();
foreach (var c in selected)
@ -346,16 +367,34 @@ namespace SourceGit.Views
{
var grid = new ViewModels.ChangeCollectionAsGrid();
grid.Changes.AddRange(changes);
if (selected.Count > 0)
if (!onlyViewModeChange && AutoSelectFirstChange)
{
grid.SelectedChanges.Add(changes[0]);
SetCurrentValue(SelectedChangesProperty, [changes[0]]);
}
else if (selected.Count > 0)
{
grid.SelectedChanges.AddRange(selected);
}
Content = grid;
}
else
{
var list = new ViewModels.ChangeCollectionAsList();
list.Changes.AddRange(changes);
if (selected.Count > 0)
if (!onlyViewModeChange && AutoSelectFirstChange)
{
list.SelectedChanges.Add(changes[0]);
SetCurrentValue(SelectedChangesProperty, [changes[0]]);
}
else if (selected.Count > 0)
{
list.SelectedChanges.AddRange(selected);
}
Content = list;
}

View file

@ -49,6 +49,7 @@
ViewMode="{Binding Source={x:Static vm:Preferences.Instance}, Path=CommitChangeViewMode}"
Changes="{Binding VisibleChanges}"
SelectedChanges="{Binding SelectedChanges, Mode=TwoWay}"
AutoSelectFirstChange="True"
ContextRequested="OnChangeContextRequested"/>
</Border>
</Grid>

View file

@ -32,7 +32,7 @@
<DataTemplate DataType="m:Branch">
<StackPanel Orientation="Horizontal">
<Path Width="14" Height="14" Data="{StaticResource Icons.Branch}"/>
<TextBlock VerticalAlignment="Center" Text="{Binding FriendlyName}" Margin="8,0,0,0"/>
<SelectableTextBlock VerticalAlignment="Center" Text="{Binding FriendlyName}" Margin="8,0,0,0"/>
</StackPanel>
</DataTemplate>

View file

@ -37,7 +37,6 @@
<Button Classes="icon_button"
Width="28"
Click="OnGotoFirstChange"
IsVisible="{Binding IsTextDiff}"
ToolTip.Tip="{DynamicResource Text.Diff.First}">
<Button.IsVisible>
<MultiBinding Converter="{x:Static BoolConverters.And}">
@ -78,7 +77,6 @@
<Button Classes="icon_button"
Width="28"
Click="OnGotoLastChange"
IsVisible="{Binding IsTextDiff}"
ToolTip.Tip="{DynamicResource Text.Diff.Last}">
<Button.IsVisible>
<MultiBinding Converter="{x:Static BoolConverters.And}">

View file

@ -39,7 +39,7 @@ namespace SourceGit.Views
}
public static readonly RoutedEvent<LauncherTabSelectedEventArgs> PageSelectedEvent =
RoutedEvent.Register<ChangeCollectionView, LauncherTabSelectedEventArgs>(nameof(PageSelected), RoutingStrategies.Tunnel | RoutingStrategies.Bubble);
RoutedEvent.Register<LauncherTabsSelector, LauncherTabSelectedEventArgs>(nameof(PageSelected), RoutingStrategies.Tunnel | RoutingStrategies.Bubble);
public event EventHandler<LauncherTabSelectedEventArgs> PageSelected
{
@ -74,7 +74,7 @@ namespace SourceGit.Views
private void OnPageSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (sender is ListBox { SelectedItem : ViewModels.LauncherPage page })
if (sender is ListBox { SelectedItem: ViewModels.LauncherPage page })
{
_isProcessingSelection = true;
RaiseEvent(new LauncherTabSelectedEventArgs(page));
@ -88,7 +88,7 @@ namespace SourceGit.Views
{
if (_isProcessingSelection)
return;
VisiblePages.Clear();
if (Pages == null)

View file

@ -522,7 +522,7 @@ namespace SourceGit.Views
private void OnRemoveSelectedHistoriesFilter(object sender, RoutedEventArgs e)
{
if (DataContext is ViewModels.Repository repo && sender is Button { DataContext: Models.Filter filter})
if (DataContext is ViewModels.Repository repo && sender is Button { DataContext: Models.Filter filter })
repo.RemoveHistoriesFilter(filter);
e.Handled = true;

View file

@ -99,6 +99,7 @@
<v:ChangeCollectionView ViewMode="{Binding Source={x:Static vm:Preferences.Instance}, Path=CommitChangeViewMode}"
Changes="{Binding VisibleChanges}"
SelectedChanges="{Binding SelectedChanges, Mode=TwoWay}"
AutoSelectFirstChange="True"
ContextRequested="OnChangeContextRequested"/>
</Border>
</Grid>

View file

@ -1006,7 +1006,7 @@ namespace SourceGit.Views
if (startPosition.Location > endPosition.Location)
(startPosition, endPosition) = (endPosition, startPosition);
var startIdx = Math.Min(startPosition.Line - 1, lines.Count - 1);
var endIdx = Math.Min(endPosition.Line - 1, lines.Count - 1);

View file

@ -352,8 +352,13 @@
Margin="8,0,0,0"
Padding="8,0"
Command="{Binding ContinueMerge}"
IsVisible="{Binding InProgressContext, Converter={x:Static ObjectConverters.IsNotNull}}"
IsEnabled="{Binding !HasUnsolvedConflicts}">
IsVisible="{Binding InProgressContext, Converter={x:Static ObjectConverters.IsNotNull}}">
<SplitButton.IsEnabled>
<MultiBinding Converter="{x:Static BoolConverters.And}">
<Binding Path="IsCommitting" Converter="{x:Static BoolConverters.Not}"/>
<Binding Path="HasUnsolvedConflicts" Converter="{x:Static BoolConverters.Not}"/>
</MultiBinding>
</SplitButton.IsEnabled>
<SplitButton.Flyout>
<MenuFlyout>
<MenuItem Header="{DynamicResource Text.WorkingCopy.CommitToEdit}" Command="{Binding Commit}"/>
@ -370,6 +375,7 @@
Command="{Binding Commit}"
HotKey="{OnPlatform Ctrl+Enter, macOS=⌘+Enter}"
IsVisible="{Binding InProgressContext, Converter={x:Static ObjectConverters.IsNull}}"
IsEnabled="{Binding !IsCommitting}"
ToolTip.Placement="Top"
ToolTip.VerticalOffset="0">
<ToolTip.Tip>
@ -401,6 +407,7 @@
Padding="8,0"
Command="{Binding CommitWithPush}"
HotKey="Alt+Enter"
IsEnabled="{Binding !IsCommitting}"
ToolTip.Tip="{OnPlatform Alt+Enter, macOS=⌥+Enter}"
ToolTip.Placement="Top"
ToolTip.VerticalOffset="0">