From 3a152ec4d8357ebddfba6bca936e512cccdda1e3 Mon Sep 17 00:00:00 2001 From: Fabi Nacimiento Date: Wed, 28 Oct 2026 08:32:54 +0000 Subject: [PATCH] Fix Windows working copy status and long paths --- src/Commands/Command.cs | 12 +++++++ src/Commands/Discard.cs | 3 ++ src/Commands/QueryLocalChanges.cs | 36 +++++++++++++------- src/Commands/SaveChangesAsPatch.cs | 2 +- src/Models/DiffResult.cs | 2 ++ src/Resources/Locales/ca_ES.axaml | 3 ++ src/Resources/Locales/de_DE.axaml | 3 ++ src/Resources/Locales/el_GR.axaml | 3 ++ src/Resources/Locales/en_US.axaml | 3 ++ src/Resources/Locales/es_ES.axaml | 3 ++ src/Resources/Locales/fr_FR.axaml | 3 ++ src/Resources/Locales/he_IL.axaml | 3 ++ src/Resources/Locales/id_ID.axaml | 3 ++ src/Resources/Locales/it_IT.axaml | 3 ++ src/Resources/Locales/ja_JP.axaml | 3 ++ src/Resources/Locales/ko_KR.axaml | 3 ++ src/Resources/Locales/pt_BR.axaml | 3 ++ src/Resources/Locales/ru_RU.axaml | 3 ++ src/Resources/Locales/ta_IN.axaml | 3 ++ src/Resources/Locales/uk_UA.axaml | 3 ++ src/Resources/Locales/zh_CN.axaml | 3 ++ src/Resources/Locales/zh_TW.axaml | 3 ++ src/ViewModels/DiffContext.cs | 11 +++++-- src/ViewModels/Preferences.cs | 23 +++++++++++++ src/ViewModels/Repository.cs | 3 ++ src/ViewModels/RepositoryConfigure.cs | 12 +++++++ src/ViewModels/StashChanges.cs | 6 ++++ src/ViewModels/WorkingCopy.cs | 47 +++++++++++++++++++-------- src/Views/DiffView.axaml | 12 +++++++ src/Views/RepositoryConfigure.axaml | 8 ++++- 30 files changed, 199 insertions(+), 29 deletions(-) diff --git a/src/Commands/Command.cs b/src/Commands/Command.cs index 14430805c2..6c54e02763 100644 --- a/src/Commands/Command.cs +++ b/src/Commands/Command.cs @@ -37,6 +37,16 @@ public enum EditorType public bool RaiseError { get; set; } = true; public Models.ICommandLog Log { get; set; } = null; + internal static string GetRepositoryConfigArguments(string repo) + { + if (!OperatingSystem.IsWindows()) + return string.Empty; + + return ViewModels.Preferences.Instance.IgnoresFileMode(repo) + ? "-c core.longpaths=true -c core.filemode=false " + : "-c core.longpaths=true "; + } + public async Task ExecAsync() { Log?.AppendLine($"$ git {Args}\n"); @@ -165,6 +175,8 @@ protected ProcessStartInfo CreateGitStartInfo(bool redirect) if (useSetSid) builder.Append(Native.OS.GitExecutable.Quoted()).Append(' '); + builder.Append(GetRepositoryConfigArguments(WorkingDirectory)); + builder .Append("--no-pager -c core.quotepath=off -c credential.helper=") .Append(Native.OS.CredentialHelper) diff --git a/src/Commands/Discard.cs b/src/Commands/Discard.cs index 8d08b90a7b..94018d9b12 100644 --- a/src/Commands/Discard.cs +++ b/src/Commands/Discard.cs @@ -16,6 +16,9 @@ public static async Task AllAsync(string repo, bool includeModified, bool includ { // Untracked paths that contains `.git` file (detached submodule) must be removed manually. var changes = await new QueryLocalChanges(repo).GetResultAsync().ConfigureAwait(false); + if (changes == null) + return; + try { foreach (var c in changes) diff --git a/src/Commands/QueryLocalChanges.cs b/src/Commands/QueryLocalChanges.cs index 7c2e4156ab..2016499d14 100644 --- a/src/Commands/QueryLocalChanges.cs +++ b/src/Commands/QueryLocalChanges.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Diagnostics; using System.Text; using System.Text.RegularExpressions; @@ -40,17 +41,15 @@ public QueryLocalChanges(string repo, bool includeUntracked = true, bool noOptio proc.StartInfo = CreateGitStartInfo(true); proc.Start(); - if (CancellationToken.CanBeCanceled) + using var registration = CancellationToken.Register(() => { - CancellationToken.Register(() => + lock (capturedLock) { - lock (capturedLock) - { - if (captured is { Process: { HasExited: false } proc }) - Native.OS.TerminateProcess(proc); - } - }); - } + if (captured is { Process: { HasExited: false } running }) + Native.OS.TerminateProcess(running); + } + }); + var errorTask = proc.StandardError.ReadToEndAsync(); while (await proc.StandardOutput.ReadLineAsync().ConfigureAwait(false) is { } line) { @@ -181,14 +180,27 @@ public QueryLocalChanges(string repo, bool includeUntracked = true, bool noOptio outs.Add(change); } + await proc.WaitForExitAsync().ConfigureAwait(false); + var error = await errorTask.ConfigureAwait(false); lock (capturedLock) { captured.Process = null; } + + if (CancellationToken.IsCancellationRequested) + return null; + + if (proc.ExitCode != 0) + { + RaiseException(string.IsNullOrWhiteSpace(error) ? "Failed to query local changes." : error.Trim()); + return null; + } } - catch + catch (Exception e) { - // Ignore exceptions. + if (!CancellationToken.IsCancellationRequested) + RaiseException($"Failed to query local changes: {e.Message}"); + return null; } return outs; diff --git a/src/Commands/SaveChangesAsPatch.cs b/src/Commands/SaveChangesAsPatch.cs index 4ec83a6a63..4029ecaa57 100644 --- a/src/Commands/SaveChangesAsPatch.cs +++ b/src/Commands/SaveChangesAsPatch.cs @@ -54,7 +54,7 @@ private static async Task ProcessSingleChangeAsync(string repo, Models.Dif var starter = new ProcessStartInfo(); starter.WorkingDirectory = repo; starter.FileName = Native.OS.GitExecutable; - starter.Arguments = $"diff --no-color --no-ext-diff --ignore-cr-at-eol --unified=4 {opt}"; + starter.Arguments = $"{Command.GetRepositoryConfigArguments(repo)}diff --no-color --no-ext-diff --ignore-cr-at-eol --unified=4 {opt}"; starter.UseShellExecute = false; starter.CreateNoWindow = true; starter.WindowStyle = ProcessWindowStyle.Hidden; diff --git a/src/Models/DiffResult.cs b/src/Models/DiffResult.cs index 35b175c530..4762a986ba 100644 --- a/src/Models/DiffResult.cs +++ b/src/Models/DiffResult.cs @@ -91,6 +91,8 @@ public class EmptyFile public class NoOrEOLChange; + public class FileModeOnlyChange : NoOrEOLChange; + public class SubmoduleDiff { public string FullPath { get; set; } = string.Empty; diff --git a/src/Resources/Locales/ca_ES.axaml b/src/Resources/Locales/ca_ES.axaml index a37a7709db..6eb44d4893 100644 --- a/src/Resources/Locales/ca_ES.axaml +++ b/src/Resources/Locales/ca_ES.axaml @@ -256,6 +256,8 @@ Adreça de correu electrònic GIT Pregunta abans d'actualitzar automàticament els submòduls + Ignore executable permission changes in this repository (Windows) + Applies only to this SourceGit installation on Windows. Staged permission changes remain visible. Obtén els remots automàticament Minut(s) Tipus de comissió convencionals @@ -387,6 +389,7 @@ NOU Diferència següent SENSE CANVIS O NOMÉS CANVIS DE FI DE LÍNIA + File permissions changed; other differences may be hidden. ANTIC Diferència anterior Desa com a pedaç diff --git a/src/Resources/Locales/de_DE.axaml b/src/Resources/Locales/de_DE.axaml index 9c59fd3deb..81e9d9bc25 100644 --- a/src/Resources/Locales/de_DE.axaml +++ b/src/Resources/Locales/de_DE.axaml @@ -244,6 +244,8 @@ $1, $2, … Werte der Eingabe-Steuerelemente E-Mail-Adresse GIT Vor dem Auto-Aktualisieren von Submodulen fragen + Ignore executable permission changes in this repository (Windows) + Applies only to this SourceGit installation on Windows. Staged permission changes remain visible. Remotes automatisch fetchen Minute(n) Konventionelle Commit-Typen @@ -373,6 +375,7 @@ $1, $2, … Werte der Eingabe-Steuerelemente NEU Nächster Unterschied KEINE ÄNDERUNG ODER NUR ZEILENENDE-ÄNDERUNGEN + File permissions changed; other differences may be hidden. ALT Vorheriger Unterschied Als Patch speichern diff --git a/src/Resources/Locales/el_GR.axaml b/src/Resources/Locales/el_GR.axaml index 22cb8b4c74..de5788464d 100644 --- a/src/Resources/Locales/el_GR.axaml +++ b/src/Resources/Locales/el_GR.axaml @@ -244,6 +244,8 @@ Διεύθυνση email GIT Ερώτηση πριν την αυτόματη ενημέρωση υπομονάδων + Ignore executable permission changes in this repository (Windows) + Applies only to this SourceGit installation on Windows. Staged permission changes remain visible. Αυτόματο fetch από τα απομακρυσμένα Λεπτό(-ά) Τύποι Conventional Commit @@ -373,6 +375,7 @@ ΝΕΟ Επόμενη διαφορά ΚΑΜΙΑ ΑΛΛΑΓΗ Ή ΜΟΝΟ ΑΛΛΑΓΕΣ EOL + File permissions changed; other differences may be hidden. ΠΑΛΙΟ Προηγούμενη διαφορά Αποθήκευση ως Patch diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 1b1f29d8fb..7e6293ac57 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -252,6 +252,8 @@ Email address GIT Ask before auto-updating submodules + Ignore executable permission changes in this repository (Windows) + Applies only to this SourceGit installation on Windows. Staged permission changes remain visible. Fetch remotes automatically Minute(s) Conventional Commit Types @@ -384,6 +386,7 @@ NEW Next Difference NO CHANGES OR ONLY EOL CHANGES + File permissions changed; other differences may be hidden. OLD Previous Difference Save as Patch diff --git a/src/Resources/Locales/es_ES.axaml b/src/Resources/Locales/es_ES.axaml index 026caeede2..bcb675c6ec 100644 --- a/src/Resources/Locales/es_ES.axaml +++ b/src/Resources/Locales/es_ES.axaml @@ -256,6 +256,8 @@ Dirección de email GIT Preguntar antes de actualizar automáticamente los submódulos + Ignore executable permission changes in this repository (Windows) + Applies only to this SourceGit installation on Windows. Staged permission changes remain visible. Fetch remotos automáticamente Minuto(s) Tipos de Commit Convencionales @@ -388,6 +390,7 @@ NUEVO Siguiente Diferencia SIN CAMBIOS O SOLO CAMBIOS DE EOL + File permissions changed; other differences may be hidden. VIEJO Diferencia Anterior Guardar como Parche diff --git a/src/Resources/Locales/fr_FR.axaml b/src/Resources/Locales/fr_FR.axaml index 6b7bacef1c..88638d82d8 100644 --- a/src/Resources/Locales/fr_FR.axaml +++ b/src/Resources/Locales/fr_FR.axaml @@ -234,6 +234,8 @@ Adresse e-mail GIT Demander avant mise à jour automatique des sous-modules + Ignore executable permission changes in this repository (Windows) + Applies only to this SourceGit installation on Windows. Staged permission changes remain visible. Fetch les dépôts distants automatiquement minute(s) Types de commit conventionnels @@ -359,6 +361,7 @@ NOUVEAU Différence suivante PAS DE CHANGEMENT OU SEULEMENT EN FIN DE LIGNE + File permissions changed; other differences may be hidden. ANCIEN Différence précédente Enregistrer en tant que patch diff --git a/src/Resources/Locales/he_IL.axaml b/src/Resources/Locales/he_IL.axaml index 153f55ef78..050d1c6b74 100644 --- a/src/Resources/Locales/he_IL.axaml +++ b/src/Resources/Locales/he_IL.axaml @@ -234,6 +234,8 @@ כתובת דוא"ל GIT לבקש אישור לפני עדכון אוטומטי של submodules + Ignore executable permission changes in this repository (Windows) + Applies only to this SourceGit installation on Windows. Staged permission changes remain visible. Fetch אוטומטי מ־remotes דקות סוגי Conventional Commit @@ -359,6 +361,7 @@ חדש ההבדל הבא אין שינויים או רק שינויי EOL + File permissions changed; other differences may be hidden. ישן ההבדל הקודם שמור כ־Patch diff --git a/src/Resources/Locales/id_ID.axaml b/src/Resources/Locales/id_ID.axaml index d8eda31ee4..99cf159154 100644 --- a/src/Resources/Locales/id_ID.axaml +++ b/src/Resources/Locales/id_ID.axaml @@ -244,6 +244,8 @@ Alamat email GIT Tanyakan sebelum memperbarui submodule secara otomatis + Ignore executable permission changes in this repository (Windows) + Applies only to this SourceGit installation on Windows. Staged permission changes remain visible. Fetch remote secara otomatis Menit Tipe Conventional Commit @@ -373,6 +375,7 @@ BARU Perbedaan Berikutnya TIDAK ADA PERUBAHAN ATAU HANYA PERUBAHAN EOL + File permissions changed; other differences may be hidden. LAMA Perbedaan Sebelumnya Simpan sebagai Patch diff --git a/src/Resources/Locales/it_IT.axaml b/src/Resources/Locales/it_IT.axaml index eee191cedc..a7818b1ade 100644 --- a/src/Resources/Locales/it_IT.axaml +++ b/src/Resources/Locales/it_IT.axaml @@ -214,6 +214,8 @@ ${pure_files:N} Come ${files:N}, ma senza cartelle Indirizzo email GIT Chiedi prima di aggiornare automaticamente i sottomoduli + Ignore executable permission changes in this repository (Windows) + Applies only to this SourceGit installation on Windows. Staged permission changes remain visible. Recupera automaticamente i remoti Minuto/i Tipi di Commit Convenzionali @@ -335,6 +337,7 @@ ${pure_files:N} Come ${files:N}, ma senza cartelle NUOVO Differenza Successiva NESSUNA MODIFICA O SOLO CAMBIAMENTI DI FINE LINEA + File permissions changed; other differences may be hidden. VECCHIO Differenza Precedente Salva come Patch diff --git a/src/Resources/Locales/ja_JP.axaml b/src/Resources/Locales/ja_JP.axaml index fdef11c278..ee197ca850 100644 --- a/src/Resources/Locales/ja_JP.axaml +++ b/src/Resources/Locales/ja_JP.axaml @@ -246,6 +246,8 @@ E メールアドレス Git サブモジュールを自動更新する前に尋ねる + Ignore executable permission changes in this repository (Windows) + Applies only to this SourceGit installation on Windows. Staged permission changes remain visible. リモートから 分ごとに自動フェッチ コンベンショナルコミットの種類定義 @@ -377,6 +379,7 @@ 新版 次の差分 変更なし、または行末コードの変更のみ + File permissions changed; other differences may be hidden. 旧版 前の差分 パッチとして保存 diff --git a/src/Resources/Locales/ko_KR.axaml b/src/Resources/Locales/ko_KR.axaml index e3dda7a432..edd20ab5b5 100644 --- a/src/Resources/Locales/ko_KR.axaml +++ b/src/Resources/Locales/ko_KR.axaml @@ -232,6 +232,8 @@ 이메일 주소 GIT 서브모듈 자동 업데이트 전에 확인 + Ignore executable permission changes in this repository (Windows) + Applies only to this SourceGit installation on Windows. Staged permission changes remain visible. 원격 자동 Fetch 분 Conventional Commit 유형 @@ -358,6 +360,7 @@ 신규 다음 차이점 변경 사항 없음 또는 줄바꿈(EOL) 변경만 있음 + File permissions changed; other differences may be hidden. 기존 이전 차이점 패치로 저장 diff --git a/src/Resources/Locales/pt_BR.axaml b/src/Resources/Locales/pt_BR.axaml index 5084f0180b..b1b15476a0 100644 --- a/src/Resources/Locales/pt_BR.axaml +++ b/src/Resources/Locales/pt_BR.axaml @@ -227,6 +227,7 @@ MUDANÇA DE OBJETO LFS Próxima Diferença SEM MUDANÇAS OU APENAS MUDANÇAS DE EOL + File permissions changed; other differences may be hidden. Diferença Anterior Salvar como um Patch Exibir símbolos ocultos @@ -636,4 +637,6 @@ Bloquear Remover Desbloquear + Ignore executable permission changes in this repository (Windows) + Applies only to this SourceGit installation on Windows. Staged permission changes remain visible. diff --git a/src/Resources/Locales/ru_RU.axaml b/src/Resources/Locales/ru_RU.axaml index 1c06deabe4..42feb9b270 100644 --- a/src/Resources/Locales/ru_RU.axaml +++ b/src/Resources/Locales/ru_RU.axaml @@ -256,6 +256,8 @@ Адрес электронной почты GIT Спрашивать перед автоматическим обновлением подмодулей. + Ignore executable permission changes in this repository (Windows) + Applies only to this SourceGit installation on Windows. Staged permission changes remain visible. Автозагрузка изменений Минут(а/ы) Общепринятые типы ревизии @@ -387,6 +389,7 @@ НОВЫЙ Следующее сравнение НИКАКИХ ИЗМЕНЕНИЙ ИЛИ МЕНЯЕТСЯ ТОЛЬКО EOL + File permissions changed; other differences may be hidden. СТАРЫЙ Предыдущее сравнение Сохранить как заплатку diff --git a/src/Resources/Locales/ta_IN.axaml b/src/Resources/Locales/ta_IN.axaml index 3473ff1cab..fb8d8872ea 100644 --- a/src/Resources/Locales/ta_IN.axaml +++ b/src/Resources/Locales/ta_IN.axaml @@ -210,6 +210,7 @@ பெகோஅ பொருள் மாற்றம் அடுத்த வேறுபாடு மாற்றங்கள் இல்லை அல்லது வரிமுடிவு மாற்றங்கள் மட்டும் + File permissions changed; other differences may be hidden. முந்தைய வேறுபாடு ஒட்டாகச் சேமி மறைக்கப்பட்ட சின்னங்களைக் காட்டு @@ -653,4 +654,6 @@ பூட்டு நீக்கு திற + Ignore executable permission changes in this repository (Windows) + Applies only to this SourceGit installation on Windows. Staged permission changes remain visible. diff --git a/src/Resources/Locales/uk_UA.axaml b/src/Resources/Locales/uk_UA.axaml index 5f44193e39..1d9a73a745 100644 --- a/src/Resources/Locales/uk_UA.axaml +++ b/src/Resources/Locales/uk_UA.axaml @@ -214,6 +214,7 @@ ЗМІНА ОБ'ЄКТА LFS Наступна відмінність НЕМАЄ ЗМІН АБО ЛИШЕ ЗМІНИ КІНЦЯ РЯДКА + File permissions changed; other differences may be hidden. Попередня відмінність Зберегти як патч Показати приховані символи @@ -661,4 +662,6 @@ Заблокувати Видалити Розблокувати + Ignore executable permission changes in this repository (Windows) + Applies only to this SourceGit installation on Windows. Staged permission changes remain visible. diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index 3716d725ab..69102b6661 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -256,6 +256,8 @@ 邮箱地址 GIT配置 在自动更新子模块前询问用户 + 忽略此仓库的可执行权限变更(Windows) + 仅影响此 Windows 上的 SourceGit;已暂存的权限变更仍会显示。 启用定时自动拉取远程更新 分钟 自定义规范化提交类型 @@ -388,6 +390,7 @@ 变更后 下一个差异 没有变更或仅有换行符差异 + 文件权限已变更,其他差异可能已被隐藏。 变更前 上一个差异 保存为补丁文件 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index 92bfffb3e9..182d6695b1 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -256,6 +256,8 @@ 電子郵件地址 Git 設定 在自動更新子模組之前先詢問 + 忽略此儲存庫的可執行權限變更(Windows) + 僅影響此 Windows 上的 SourceGit;已暫存的權限變更仍會顯示。 啟用定時自動提取 (fetch) 遠端更新 分鐘 自訂約定式提交類型 @@ -387,6 +389,7 @@ 變更後 下一個差異 沒有變更或僅有換行字元差異 + 檔案權限已變更,其他差異可能已被隱藏。 變更前 上一個差異 另存為修補檔 (patch) diff --git a/src/ViewModels/DiffContext.cs b/src/ViewModels/DiffContext.cs index ddbdffbb60..6ff27cb617 100644 --- a/src/ViewModels/DiffContext.cs +++ b/src/ViewModels/DiffContext.cs @@ -175,7 +175,9 @@ private void LoadContent() } else { - rs = new Models.NoOrEOLChange(); + rs = latest.OldMode != 0 && latest.NewMode != 0 && latest.OldMode != latest.NewMode + ? new Models.FileModeOnlyChange() + : new Models.NoOrEOLChange(); } Dispatcher.UIThread.Post(() => @@ -360,6 +362,8 @@ private class Info public bool IgnoreWhitespace { get; } public string OldHash { get; } public string NewHash { get; } + public int OldMode { get; } + public int NewMode { get; } public Info(Models.DiffOption option, int unifiedLines, bool ignoreWhitespace, Models.DiffResult result) { @@ -368,6 +372,8 @@ public Info(Models.DiffOption option, int unifiedLines, bool ignoreWhitespace, M IgnoreWhitespace = ignoreWhitespace; OldHash = result.OldHash; NewHash = result.NewHash; + OldMode = result.OldMode; + NewMode = result.NewMode; } public bool IsSame(Info other) @@ -376,7 +382,8 @@ public bool IsSame(Info other) UnifiedLines == other.UnifiedLines && IgnoreWhitespace == other.IgnoreWhitespace && OldHash.Equals(other.OldHash, StringComparison.Ordinal) && - NewHash.Equals(other.NewHash, StringComparison.Ordinal); + NewHash.Equals(other.NewHash, StringComparison.Ordinal) && + OldMode == other.OldMode && NewMode == other.NewMode; } } diff --git a/src/ViewModels/Preferences.cs b/src/ViewModels/Preferences.cs index 9d9fb3f9f9..2f5e31c7b4 100644 --- a/src/ViewModels/Preferences.cs +++ b/src/ViewModels/Preferences.cs @@ -450,6 +450,29 @@ public List RepositoryNodes set; } = []; + public List IgnoreFileModeRepositories { get; set; } = []; + + public bool IgnoresFileMode(string repo) + { + if (string.IsNullOrEmpty(repo)) + return false; + + var normalized = repo.Replace('\\', '/').TrimEnd('/'); + var repositories = IgnoreFileModeRepositories; + return repositories != null && repositories.Exists(path => + string.Equals(path, normalized, StringComparison.OrdinalIgnoreCase)); + } + + public void SetIgnoreFileMode(string repo, bool ignore) + { + var normalized = repo.Replace('\\', '/').TrimEnd('/'); + var repositories = new List(IgnoreFileModeRepositories ?? []); + repositories.RemoveAll(path => string.Equals(path, normalized, StringComparison.OrdinalIgnoreCase)); + if (ignore) + repositories.Add(normalized); + IgnoreFileModeRepositories = repositories; + } + public List Workspaces { get; diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index 1ea5951a83..ec89be6a99 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -1339,6 +1339,9 @@ public void RefreshWorkingCopyChanges() .GetResultAsync() .ConfigureAwait(false); + if (changes == null || token.IsCancellationRequested) + return; + changes.Sort((l, r) => Models.NumericSort.Compare(l.Path, r.Path)); Dispatcher.UIThread.Invoke(() => diff --git a/src/ViewModels/RepositoryConfigure.cs b/src/ViewModels/RepositoryConfigure.cs index a761947169..32364c2f77 100644 --- a/src/ViewModels/RepositoryConfigure.cs +++ b/src/ViewModels/RepositoryConfigure.cs @@ -95,6 +95,10 @@ public bool EnablePruneOnFetch set; } + public bool IsWindows => OperatingSystem.IsWindows(); + + public bool IgnoreFileModeOnWindows { get; set; } + public bool AskBeforeAutoUpdatingSubmodules { get => _repo.Settings.AskBeforeAutoUpdatingSubmodules; @@ -155,6 +159,7 @@ public Models.CustomAction SelectedCustomAction public RepositoryConfigure(Repository repo) { _repo = repo; + IgnoreFileModeOnWindows = Preferences.Instance.IgnoresFileMode(repo.FullPath); Remotes = new List(); foreach (var remote in _repo.Remotes) @@ -274,6 +279,13 @@ public async Task SaveAsync() { _repo.Settings.Save(); + if (IsWindows && IgnoreFileModeOnWindows != Preferences.Instance.IgnoresFileMode(_repo.FullPath)) + { + Preferences.Instance.SetIgnoreFileMode(_repo.FullPath, IgnoreFileModeOnWindows); + Preferences.Instance.Save(); + _repo.RefreshWorkingCopyChanges(); + } + await SetIfChangedAsync("user.name", UserName, ""); await SetIfChangedAsync("user.email", UserEmail, ""); await SetIfChangedAsync("commit.gpgsign", GPGCommitSigningEnabled ? "true" : "false", "false"); diff --git a/src/ViewModels/StashChanges.cs b/src/ViewModels/StashChanges.cs index bde579b8a9..6ca2114246 100644 --- a/src/ViewModels/StashChanges.cs +++ b/src/ViewModels/StashChanges.cs @@ -77,6 +77,12 @@ public override async Task Sure() .Use(log) .GetResultAsync(); + if (all == null) + { + log.Complete(); + return false; + } + var staged = new List(); foreach (var c in all) { diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs index 38612dbdaa..2fde12a66a 100644 --- a/src/ViewModels/WorkingCopy.cs +++ b/src/ViewModels/WorkingCopy.cs @@ -374,24 +374,45 @@ public async Task StageChangesAsync(List changes, Models.Change n return; IsStaging = true; - _selectedUnstaged = new(next != null ? new List { next } : null); - using var lockWatcher = _repo.LockWatcher(); var log = _repo.CreateLog("Stage"); - var pathSpecFile = Path.GetTempFileName(); - await using (var writer = new StreamWriter(pathSpecFile)) + string pathSpecFile = null; + try { - foreach (var c in canStaged) - await writer.WriteLineAsync(c.Path); - } - - await new Commands.Add(_repo.FullPath, pathSpecFile).Use(log).ExecAsync(); - File.Delete(pathSpecFile); - log.Complete(); + pathSpecFile = Path.GetTempFileName(); + await using (var writer = new StreamWriter(pathSpecFile)) + { + foreach (var c in canStaged) + await writer.WriteLineAsync(c.Path); + } - _repo.MarkWorkingCopyDirtyManually(); - IsStaging = false; + if (await new Commands.Add(_repo.FullPath, pathSpecFile).Use(log).ExecAsync()) + _selectedUnstaged = new(next != null ? new List { next } : null); + } + catch (Exception e) + { + _repo.SendNotification($"Failed to stage changes: {e.Message}", true); + } + finally + { + if (pathSpecFile != null) + { + try + { + File.Delete(pathSpecFile); + } + catch (IOException) + { + } + catch (UnauthorizedAccessException) + { + } + } + log.Complete(); + IsStaging = false; + _repo.MarkWorkingCopyDirtyManually(); + } } public async Task UnstageChangesAsync(List changes, Models.Change next) diff --git a/src/Views/DiffView.axaml b/src/Views/DiffView.axaml index ba889d09b7..4467fb6588 100644 --- a/src/Views/DiffView.axaml +++ b/src/Views/DiffView.axaml @@ -411,6 +411,18 @@ + + + + + + + + diff --git a/src/Views/RepositoryConfigure.axaml b/src/Views/RepositoryConfigure.axaml index 0b92d46e38..ab9749ac9a 100644 --- a/src/Views/RepositoryConfigure.axaml +++ b/src/Views/RepositoryConfigure.axaml @@ -44,7 +44,7 @@ - + + +