diff --git a/src/Commands/QueryStashes.cs b/src/Commands/QueryStashes.cs index b4067aaf..bf8756a2 100644 --- a/src/Commands/QueryStashes.cs +++ b/src/Commands/QueryStashes.cs @@ -9,7 +9,7 @@ namespace SourceGit.Commands { WorkingDirectory = repo; Context = repo; - Args = "stash list --format=%H%n%P%n%ct%n%gd%n%s"; + Args = "stash list -z --format=%H%n%P%n%ct%n%gd%n%B"; } public List Result() @@ -19,55 +19,54 @@ namespace SourceGit.Commands if (!rs.IsSuccess) return outs; - var nextPartIdx = 0; - var start = 0; - var end = rs.StdOut.IndexOf('\n', start); - while (end > 0) + var stashes = rs.StdOut.Split('\0', System.StringSplitOptions.RemoveEmptyEntries); + foreach (var stash in stashes) { - var line = rs.StdOut.Substring(start, end - start); + var current = new Models.Stash(); - switch (nextPartIdx) + var nextPartIdx = 0; + var start = 0; + var end = stash.IndexOf('\n', start); + while (end > 0 && nextPartIdx < 4) { - case 0: - _current = new Models.Stash() { SHA = line }; - outs.Add(_current); - break; - case 1: - ParseParent(line); - break; - case 2: - _current.Time = ulong.Parse(line); - break; - case 3: - _current.Name = line; - break; - case 4: - _current.Message = line; - break; + var line = stash.Substring(start, end - start); + + switch (nextPartIdx) + { + case 0: + current = new Models.Stash() { SHA = line }; + break; + case 1: + ParseParent(line, ref current); + break; + case 2: + current.Time = ulong.Parse(line); + break; + case 3: + current.Name = line; + break; + } + + nextPartIdx++; + + start = end + 1; + end = stash.IndexOf('\n', start); } - nextPartIdx++; - if (nextPartIdx > 4) - nextPartIdx = 0; + if (start < stash.Length) + current.Message = stash.Substring(start); - start = end + 1; - end = rs.StdOut.IndexOf('\n', start); + outs.Add(current); } - - if (start < rs.StdOut.Length) - _current.Message = rs.StdOut.Substring(start); - return outs; } - private void ParseParent(string data) + private void ParseParent(string data, ref Models.Stash current) { if (data.Length < 8) return; - _current.Parents.AddRange(data.Split(separator: ' ', options: StringSplitOptions.RemoveEmptyEntries)); + current.Parents.AddRange(data.Split(separator: ' ', options: StringSplitOptions.RemoveEmptyEntries)); } - - private Models.Stash _current = null; } } diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 8c5d1118..8686723c 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -697,6 +697,7 @@ Both staged and unstaged changes of selected file(s) will be stashed!!! Stash Local Changes Apply + Copy Message Drop Save as Patch... Drop Stash diff --git a/src/ViewModels/StashesPage.cs b/src/ViewModels/StashesPage.cs index f039d54e..1f11425d 100644 --- a/src/ViewModels/StashesPage.cs +++ b/src/ViewModels/StashesPage.cs @@ -194,11 +194,21 @@ namespace SourceGit.ViewModels e.Handled = true; }; + var copy = new MenuItem(); + copy.Header = App.Text("StashCM.CopyMessage"); + copy.Icon = App.CreateMenuIcon("Icons.Copy"); + copy.Click += (_, ev) => + { + App.CopyText(stash.Message); + ev.Handled = true; + }; + var menu = new ContextMenu(); menu.Items.Add(apply); menu.Items.Add(drop); menu.Items.Add(new MenuItem { Header = "-" }); menu.Items.Add(patch); + menu.Items.Add(copy); return menu; } diff --git a/src/Views/StashChanges.axaml b/src/Views/StashChanges.axaml index 148fc489..11b18a90 100644 --- a/src/Views/StashChanges.axaml +++ b/src/Views/StashChanges.axaml @@ -20,6 +20,7 @@