diff --git a/src/App.axaml.cs b/src/App.axaml.cs index 935e2e198..669d095a6 100644 --- a/src/App.axaml.cs +++ b/src/App.axaml.cs @@ -83,24 +83,25 @@ public static void LogException(Exception ex) if (ex == null) return; - var builder = new StringBuilder(); - builder.Append($"Crash::: {ex.GetType().FullName}: {ex.Message}\n\n"); - builder.Append("----------------------------\n"); - builder.Append($"Version: {Assembly.GetExecutingAssembly().GetName().Version}\n"); - builder.Append($"OS: {Environment.OSVersion}\n"); - builder.Append($"Framework: {AppDomain.CurrentDomain.SetupInformation.TargetFrameworkName}\n"); - builder.Append($"Source: {ex.Source}\n"); - builder.Append($"Thread Name: {Thread.CurrentThread.Name ?? "Unnamed"}\n"); - builder.Append($"User: {Environment.UserName}\n"); - builder.Append($"App Start Time: {Process.GetCurrentProcess().StartTime}\n"); - builder.Append($"Exception Time: {DateTime.Now}\n"); - builder.Append($"Memory Usage: {Process.GetCurrentProcess().PrivateMemorySize64 / 1024 / 1024} MB\n"); - builder.Append("---------------------------\n\n"); - builder.Append(ex); - var time = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"); var file = Path.Combine(Native.OS.DataDir, $"crash_{time}.log"); - File.WriteAllText(file, builder.ToString()); + using var writer = new StreamWriter(file); + writer.WriteLine($"Crash::: {ex.GetType().FullName}: {ex.Message}"); + writer.WriteLine(); + writer.WriteLine("----------------------------"); + writer.WriteLine($"Version: {Assembly.GetExecutingAssembly().GetName().Version}"); + writer.WriteLine($"OS: {Environment.OSVersion}"); + writer.WriteLine($"Framework: {AppDomain.CurrentDomain.SetupInformation.TargetFrameworkName}"); + writer.WriteLine($"Source: {ex.Source}"); + writer.WriteLine($"Thread Name: {Thread.CurrentThread.Name ?? "Unnamed"}"); + writer.WriteLine($"User: {Environment.UserName}"); + writer.WriteLine($"App Start Time: {Process.GetCurrentProcess().StartTime}"); + writer.WriteLine($"Exception Time: {DateTime.Now}"); + writer.WriteLine($"Memory Usage: {Process.GetCurrentProcess().PrivateMemorySize64 / 1024 / 1024} MB"); + writer.WriteLine("----------------------------"); + writer.WriteLine(); + writer.WriteLine(ex); + writer.Flush(); } #endregion @@ -436,33 +437,33 @@ private static bool TryLaunchAsRebaseTodoEditor(string[] args, out int exitCode) return true; var collection = JsonSerializer.Deserialize(File.ReadAllText(jobsFile), JsonCodeGen.Default.InteractiveRebaseJobCollection); - var lines = new List(); + using var writer = new StreamWriter(file); foreach (var job in collection.Jobs) { switch (job.Action) { case Models.InteractiveRebaseAction.Pick: - lines.Add($"p {job.SHA}"); + writer.WriteLine($"p {job.SHA}"); break; case Models.InteractiveRebaseAction.Edit: - lines.Add($"e {job.SHA}"); + writer.WriteLine($"e {job.SHA}"); break; case Models.InteractiveRebaseAction.Reword: - lines.Add($"r {job.SHA}"); + writer.WriteLine($"r {job.SHA}"); break; case Models.InteractiveRebaseAction.Squash: - lines.Add($"s {job.SHA}"); + writer.WriteLine($"s {job.SHA}"); break; case Models.InteractiveRebaseAction.Fixup: - lines.Add($"f {job.SHA}"); + writer.WriteLine($"f {job.SHA}"); break; default: - lines.Add($"d {job.SHA}"); + writer.WriteLine($"d {job.SHA}"); break; } } - File.WriteAllLines(file, lines); + writer.Flush(); exitCode = 0; return true; diff --git a/src/Models/DiffResult.cs b/src/Models/DiffResult.cs index 2f06c0cfb..c76a0cefe 100644 --- a/src/Models/DiffResult.cs +++ b/src/Models/DiffResult.cs @@ -1,5 +1,5 @@ using System.Collections.Generic; -using System.Text; +using System.IO; using System.Text.RegularExpressions; using Avalonia; @@ -148,13 +148,13 @@ public void GenerateNewPatchFromSelection(Change change, string fileBlobGuid, Te var isTracked = !string.IsNullOrEmpty(fileBlobGuid); var fileGuid = isTracked ? fileBlobGuid : "00000000"; - var builder = new StringBuilder(); - builder.Append("diff --git a/").Append(change.Path).Append(" b/").Append(change.Path).Append('\n'); + using var writer = new StreamWriter(output); + writer.WriteLine($"diff --git a/{change.Path} b/{change.Path}"); if (!revert && !isTracked) - builder.Append("new file mode 100644\n"); - builder.Append("index 00000000...").Append(fileGuid).Append('\n'); - builder.Append("--- ").Append((revert || isTracked) ? $"a/{change.Path}\n" : "/dev/null\n"); - builder.Append("+++ b/").Append(change.Path).Append('\n'); + writer.WriteLine("new file mode 100644"); + writer.WriteLine($"index 00000000...{fileGuid}"); + writer.WriteLine($"--- {(revert || isTracked ? $"a/{change.Path}" : "/dev/null")}"); + writer.WriteLine($"+++ b/{change.Path}"); var additions = selection.EndLine - selection.StartLine; if (selection.StartLine != 1) @@ -163,40 +163,40 @@ public void GenerateNewPatchFromSelection(Change change, string fileBlobGuid, Te if (revert) { var totalLines = Lines.Count - 1; - builder.Append("@@ -0,").Append(totalLines - additions).Append(" +0,").Append(totalLines).Append(" @@"); + writer.WriteLine($"@@ -0,{totalLines - additions} +0,{totalLines} @@"); for (int i = 1; i <= totalLines; i++) { var line = Lines[i]; if (line.Type != TextDiffLineType.Added) continue; - builder.Append(selection.IsInRange(i) ? "\n+" : "\n ").Append(line.Content); + writer.WriteLine($"{(selection.IsInRange(i) ? "+" : " ")}{line.Content}"); } } else { - builder.Append("@@ -0,0 +0,").Append(additions).Append(" @@"); + writer.WriteLine($"@@ -0,0 +0,{additions} @@"); for (int i = selection.StartLine - 1; i < selection.EndLine; i++) { var line = Lines[i]; if (line.Type != TextDiffLineType.Added) continue; - builder.Append("\n+").Append(line.Content); + writer.WriteLine($"+{line.Content}"); } } - builder.Append("\n\\ No newline at end of file\n"); - System.IO.File.WriteAllText(output, builder.ToString()); + writer.WriteLine("\\ No newline at end of file"); + writer.Flush(); } public void GeneratePatchFromSelection(Change change, string fileTreeGuid, TextDiffSelection selection, bool revert, string output) { var orgFile = !string.IsNullOrEmpty(change.OriginalPath) ? change.OriginalPath : change.Path; - var builder = new StringBuilder(); - builder.Append("diff --git a/").Append(change.Path).Append(" b/").Append(change.Path).Append('\n'); - builder.Append("index 00000000...").Append(fileTreeGuid).Append(" 100644\n"); - builder.Append("--- a/").Append(orgFile).Append('\n'); - builder.Append("+++ b/").Append(change.Path); + using var writer = new StreamWriter(output); + writer.WriteLine($"diff --git a/{change.Path} b/{change.Path}"); + writer.WriteLine($"index 00000000...{fileTreeGuid} 100644"); + writer.WriteLine($"--- a/{orgFile}"); + writer.WriteLine($"+++ b/{change.Path}"); // If last line of selection is a change. Find one more line. var tail = null as string; @@ -264,21 +264,21 @@ public void GeneratePatchFromSelection(Change change, string fileTreeGuid, TextD var line = Lines[i]; if (line.Type == TextDiffLineType.Indicator) { - ProcessIndicatorForPatch(builder, line, i, selection.StartLine, selection.EndLine, ignoreRemoves, ignoreAdds, revert, tail != null); + ProcessIndicatorForPatch(writer, line, i, selection.StartLine, selection.EndLine, ignoreRemoves, ignoreAdds, revert, tail != null); } else if (line.Type == TextDiffLineType.Added) { if (revert) - builder.Append("\n ").Append(line.Content); + writer.WriteLine($" {line.Content}"); } else if (line.Type == TextDiffLineType.Deleted) { if (!revert) - builder.Append("\n ").Append(line.Content); + writer.WriteLine($" {line.Content}"); } else if (line.Type == TextDiffLineType.Normal) { - builder.Append("\n ").Append(line.Content); + writer.WriteLine($" {line.Content}"); } } } @@ -289,39 +289,38 @@ public void GeneratePatchFromSelection(Change change, string fileTreeGuid, TextD var line = Lines[i]; if (line.Type == TextDiffLineType.Indicator) { - if (!ProcessIndicatorForPatch(builder, line, i, selection.StartLine, selection.EndLine, selection.IgnoredDeletes, selection.IgnoredAdds, revert, tail != null)) + if (!ProcessIndicatorForPatch(writer, line, i, selection.StartLine, selection.EndLine, selection.IgnoredDeletes, selection.IgnoredAdds, revert, tail != null)) { break; } } else if (line.Type == TextDiffLineType.Normal) { - builder.Append("\n ").Append(line.Content); + writer.WriteLine($" {line.Content}"); } else if (line.Type == TextDiffLineType.Added) { - builder.Append("\n+").Append(line.Content); + writer.WriteLine($"+{line.Content}"); } else if (line.Type == TextDiffLineType.Deleted) { - builder.Append("\n-").Append(line.Content); + writer.WriteLine($"-{line.Content}"); } } - builder.Append("\n ").Append(tail); - builder.Append("\n"); - System.IO.File.WriteAllText(output, builder.ToString()); + writer.WriteLine($" {tail}"); + writer.Flush(); } public void GeneratePatchFromSelectionSingleSide(Change change, string fileTreeGuid, TextDiffSelection selection, bool revert, bool isOldSide, string output) { var orgFile = !string.IsNullOrEmpty(change.OriginalPath) ? change.OriginalPath : change.Path; - var builder = new StringBuilder(); - builder.Append("diff --git a/").Append(change.Path).Append(" b/").Append(change.Path).Append('\n'); - builder.Append("index 00000000...").Append(fileTreeGuid).Append(" 100644\n"); - builder.Append("--- a/").Append(orgFile).Append('\n'); - builder.Append("+++ b/").Append(change.Path); + using var writer = new StreamWriter(output); + writer.WriteLine($"diff --git a/{change.Path} b/{change.Path}"); + writer.WriteLine($"index 00000000...{fileTreeGuid} 100644"); + writer.WriteLine($"--- a/{orgFile}"); + writer.WriteLine($"+++ b/{change.Path}"); // If last line of selection is a change. Find one more line. var tail = null as string; @@ -389,21 +388,21 @@ public void GeneratePatchFromSelectionSingleSide(Change change, string fileTreeG var line = Lines[i]; if (line.Type == TextDiffLineType.Indicator) { - ProcessIndicatorForPatchSingleSide(builder, line, i, selection.StartLine, selection.EndLine, ignoreRemoves, ignoreAdds, revert, isOldSide, tail != null); + ProcessIndicatorForPatchSingleSide(writer, line, i, selection.StartLine, selection.EndLine, ignoreRemoves, ignoreAdds, revert, isOldSide, tail != null); } else if (line.Type == TextDiffLineType.Added) { if (revert) - builder.Append("\n ").Append(line.Content); + writer.WriteLine($" {line.Content}"); } else if (line.Type == TextDiffLineType.Deleted) { if (!revert) - builder.Append("\n ").Append(line.Content); + writer.WriteLine($" {line.Content}"); } else if (line.Type == TextDiffLineType.Normal) { - builder.Append("\n ").Append(line.Content); + writer.WriteLine($" {line.Content}"); } } } @@ -414,14 +413,14 @@ public void GeneratePatchFromSelectionSingleSide(Change change, string fileTreeG var line = Lines[i]; if (line.Type == TextDiffLineType.Indicator) { - if (!ProcessIndicatorForPatchSingleSide(builder, line, i, selection.StartLine, selection.EndLine, selection.IgnoredDeletes, selection.IgnoredAdds, revert, isOldSide, tail != null)) + if (!ProcessIndicatorForPatchSingleSide(writer, line, i, selection.StartLine, selection.EndLine, selection.IgnoredDeletes, selection.IgnoredAdds, revert, isOldSide, tail != null)) { break; } } else if (line.Type == TextDiffLineType.Normal) { - builder.Append("\n ").Append(line.Content); + writer.WriteLine($" {line.Content}"); } else if (line.Type == TextDiffLineType.Added) { @@ -429,7 +428,7 @@ public void GeneratePatchFromSelectionSingleSide(Change change, string fileTreeG { if (revert) { - builder.Append("\n ").Append(line.Content); + writer.WriteLine($" {line.Content}"); } else { @@ -438,20 +437,20 @@ public void GeneratePatchFromSelectionSingleSide(Change change, string fileTreeG } else { - builder.Append("\n+").Append(line.Content); + writer.WriteLine($"+{line.Content}"); } } else if (line.Type == TextDiffLineType.Deleted) { if (isOldSide) { - builder.Append("\n-").Append(line.Content); + writer.WriteLine($"-{line.Content}"); } else { if (!revert) { - builder.Append("\n ").Append(line.Content); + writer.WriteLine($" {line.Content}"); } else { @@ -461,12 +460,11 @@ public void GeneratePatchFromSelectionSingleSide(Change change, string fileTreeG } } - builder.Append("\n ").Append(tail); - builder.Append("\n"); - System.IO.File.WriteAllText(output, builder.ToString()); + writer.WriteLine($" {tail}"); + writer.Flush(); } - private bool ProcessIndicatorForPatch(StringBuilder builder, TextDiffLine indicator, int idx, int start, int end, int ignoreRemoves, int ignoreAdds, bool revert, bool tailed) + private bool ProcessIndicatorForPatch(StreamWriter writer, TextDiffLine indicator, int idx, int start, int end, int ignoreRemoves, int ignoreAdds, bool revert, bool tailed) { var match = REG_INDICATOR().Match(indicator.Content); var oldStart = int.Parse(match.Groups[1].Value); @@ -531,11 +529,11 @@ private bool ProcessIndicatorForPatch(StringBuilder builder, TextDiffLine indica if (oldCount == 0 && newCount == 0) return false; - builder.Append($"\n@@ -{oldStart},{oldCount} +{newStart},{newCount} @@"); + writer.WriteLine($"@@ -{oldStart},{oldCount} +{newStart},{newCount} @@"); return true; } - private bool ProcessIndicatorForPatchSingleSide(StringBuilder builder, TextDiffLine indicator, int idx, int start, int end, int ignoreRemoves, int ignoreAdds, bool revert, bool isOldSide, bool tailed) + private bool ProcessIndicatorForPatchSingleSide(StreamWriter writer, TextDiffLine indicator, int idx, int start, int end, int ignoreRemoves, int ignoreAdds, bool revert, bool isOldSide, bool tailed) { var match = REG_INDICATOR().Match(indicator.Content); var oldStart = int.Parse(match.Groups[1].Value); @@ -611,7 +609,7 @@ private bool ProcessIndicatorForPatchSingleSide(StringBuilder builder, TextDiffL if (oldCount == 0 && newCount == 0) return false; - builder.Append($"\n@@ -{oldStart},{oldCount} +{newStart},{newCount} @@"); + writer.WriteLine($"@@ -{oldStart},{oldCount} +{newStart},{newCount} @@"); return true; } diff --git a/src/ViewModels/InteractiveRebase.cs b/src/ViewModels/InteractiveRebase.cs index e22d0d731..4e9557870 100644 --- a/src/ViewModels/InteractiveRebase.cs +++ b/src/ViewModels/InteractiveRebase.cs @@ -206,7 +206,10 @@ public Task Start() Message = item.FullMessage, }); } - File.WriteAllText(saveFile, JsonSerializer.Serialize(collection, JsonCodeGen.Default.InteractiveRebaseJobCollection)); + using (var stream = File.Create(saveFile)) + { + JsonSerializer.Serialize(stream, collection, JsonCodeGen.Default.InteractiveRebaseJobCollection); + } var log = _repo.CreateLog("Interactive Rebase"); return Task.Run(() => diff --git a/src/ViewModels/Preferences.cs b/src/ViewModels/Preferences.cs index 665b76048..4cff477ad 100644 --- a/src/ViewModels/Preferences.cs +++ b/src/ViewModels/Preferences.cs @@ -523,8 +523,8 @@ public void Save() return; var file = Path.Combine(Native.OS.DataDir, "preference.json"); - var data = JsonSerializer.Serialize(this, JsonCodeGen.Default.Preferences); - File.WriteAllText(file, data); + using var stream = File.Create(file); + JsonSerializer.Serialize(stream, this, JsonCodeGen.Default.Preferences); } private static Preferences Load() diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs index 1b56e2137..4e2e10436 100644 --- a/src/ViewModels/WorkingCopy.cs +++ b/src/ViewModels/WorkingCopy.cs @@ -1787,12 +1787,13 @@ private async void StageChanges(List changes, Models.Change next) } else { - var paths = new List(); - foreach (var c in changes) - paths.Add(c.Path); - var pathSpecFile = Path.GetTempFileName(); - await File.WriteAllLinesAsync(pathSpecFile, paths); + using (var writer = new StreamWriter(pathSpecFile)) + { + foreach (var c in changes) + await writer.WriteLineAsync(c.Path); + } + await Task.Run(() => new Commands.Add(_repo.FullPath, pathSpecFile).Use(log).Exec()); File.Delete(pathSpecFile); } @@ -1823,16 +1824,17 @@ private async void UnstageChanges(List changes, Models.Change nex } else { - var paths = new List(); - foreach (var c in changes) + var pathSpecFile = Path.GetTempFileName(); + using (var writer = new StreamWriter(pathSpecFile)) { - paths.Add(c.Path); - if (c.Index == Models.ChangeState.Renamed) - paths.Add(c.OriginalPath); + foreach (var c in changes) + { + await writer.WriteLineAsync(c.Path); + if (c.Index == Models.ChangeState.Renamed) + await writer.WriteLineAsync(c.OriginalPath); + } } - var pathSpecFile = Path.GetTempFileName(); - await File.WriteAllLinesAsync(pathSpecFile, paths); await Task.Run(() => new Commands.Restore(_repo.FullPath, pathSpecFile, true).Use(log).Exec()); File.Delete(pathSpecFile); } diff --git a/src/Views/Askpass.axaml.cs b/src/Views/Askpass.axaml.cs index bbe26e988..ab1505fe8 100644 --- a/src/Views/Askpass.axaml.cs +++ b/src/Views/Askpass.axaml.cs @@ -19,7 +19,7 @@ private void CloseWindow(object _1, RoutedEventArgs _2) private void EnterPassword(object _1, RoutedEventArgs _2) { var passphrase = TxtPassphrase.Text ?? string.Empty; - Console.Out.Write($"{passphrase}\n"); + Console.Out.WriteLine(passphrase); App.Quit(0); } }