diff --git a/src/Commands/QueryStashChanges.cs b/src/Commands/QueryStashChanges.cs
new file mode 100644
index 00000000..7fc27ea3
--- /dev/null
+++ b/src/Commands/QueryStashChanges.cs
@@ -0,0 +1,68 @@
+using System;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+
+namespace SourceGit.Commands
+{
+ ///
+ /// Query stash changes. Requires git >= 2.32.0
+ ///
+ public partial class QueryStashChanges : Command
+ {
+ [GeneratedRegex(@"^([MADRC])\s+(.+)$")]
+ private static partial Regex REG_FORMAT();
+
+ public QueryStashChanges(string repo, string stash)
+ {
+ WorkingDirectory = repo;
+ Context = repo;
+ Args = $"stash show -u --name-status \"{stash}\"";
+ }
+
+ public List Result()
+ {
+ var rs = ReadToEnd();
+ if (!rs.IsSuccess)
+ return [];
+
+ var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
+ var outs = new List();
+ foreach (var line in lines)
+ {
+ var match = REG_FORMAT().Match(line);
+ if (!match.Success)
+ continue;
+
+ var change = new Models.Change() { Path = match.Groups[2].Value };
+ var status = match.Groups[1].Value;
+
+ switch (status[0])
+ {
+ case 'M':
+ change.Set(Models.ChangeState.Modified);
+ outs.Add(change);
+ break;
+ case 'A':
+ change.Set(Models.ChangeState.Added);
+ outs.Add(change);
+ break;
+ case 'D':
+ change.Set(Models.ChangeState.Deleted);
+ outs.Add(change);
+ break;
+ case 'R':
+ change.Set(Models.ChangeState.Renamed);
+ outs.Add(change);
+ break;
+ case 'C':
+ change.Set(Models.ChangeState.Copied);
+ outs.Add(change);
+ break;
+ }
+ }
+
+ outs.Sort((l, r) => string.Compare(l.Path, r.Path, StringComparison.Ordinal));
+ return outs;
+ }
+ }
+}
diff --git a/src/Models/GitVersions.cs b/src/Models/GitVersions.cs
index 394a9518..92fd8c59 100644
--- a/src/Models/GitVersions.cs
+++ b/src/Models/GitVersions.cs
@@ -13,13 +13,18 @@
public static readonly System.Version ADD_WITH_PATHSPECFILE = new System.Version(2, 25, 0);
///
- /// The minimal version of Git that supports the `stash` command with the `--pathspec-from-file` option.
+ /// The minimal version of Git that supports the `stash push` command with the `--pathspec-from-file` option.
///
- public static readonly System.Version STASH_WITH_PATHSPECFILE = new System.Version(2, 26, 0);
+ public static readonly System.Version STASH_PUSH_WITH_PATHSPECFILE = new System.Version(2, 26, 0);
///
- /// The minimal version of Git that supports the `stash` command with the `--staged` option.
+ /// The minimal version of Git that supports the `stash push` command with the `--staged` option.
///
- public static readonly System.Version STASH_ONLY_STAGED = new System.Version(2, 35, 0);
+ public static readonly System.Version STASH_PUSH_ONLY_STAGED = new System.Version(2, 35, 0);
+
+ ///
+ /// The minimal version of Git that supports the `stash show` command with the `-u` option.
+ ///
+ public static readonly System.Version STASH_SHOW_WITH_UNTRACKED = new System.Version(2, 32, 0);
}
}
diff --git a/src/ViewModels/StashChanges.cs b/src/ViewModels/StashChanges.cs
index 33ebb1f3..e35aaad0 100644
--- a/src/ViewModels/StashChanges.cs
+++ b/src/ViewModels/StashChanges.cs
@@ -64,7 +64,7 @@ namespace SourceGit.ViewModels
{
if (OnlyStaged)
{
- if (Native.OS.GitVersion >= Models.GitVersions.STASH_ONLY_STAGED)
+ if (Native.OS.GitVersion >= Models.GitVersions.STASH_PUSH_ONLY_STAGED)
{
succ = new Commands.Stash(_repo.FullPath).PushOnlyStaged(Message, KeepIndex);
}
@@ -109,7 +109,7 @@ namespace SourceGit.ViewModels
return true;
var succ = false;
- if (Native.OS.GitVersion >= Models.GitVersions.STASH_WITH_PATHSPECFILE)
+ if (Native.OS.GitVersion >= Models.GitVersions.STASH_PUSH_WITH_PATHSPECFILE)
{
var paths = new List();
foreach (var c in changes)
diff --git a/src/ViewModels/StashesPage.cs b/src/ViewModels/StashesPage.cs
index d8443c91..77ed5551 100644
--- a/src/ViewModels/StashesPage.cs
+++ b/src/ViewModels/StashesPage.cs
@@ -58,14 +58,26 @@ namespace SourceGit.ViewModels
{
Task.Run(() =>
{
- var changes = new Commands.CompareRevisions(_repo.FullPath, $"{value.SHA}^", value.SHA).Result();
- if (value.Parents.Count == 3)
- {
- var untracked = new Commands.CompareRevisions(_repo.FullPath, "4b825dc642cb6eb9a060e54bf8d69288fbee4904", value.Parents[2]).Result();
- foreach (var c in untracked)
- changes.Add(c);
+ var changes = null as List;
- changes.Sort((l, r) => string.Compare(l.Path, r.Path, StringComparison.Ordinal));
+ if (Native.OS.GitVersion >= Models.GitVersions.STASH_SHOW_WITH_UNTRACKED)
+ {
+ changes = new Commands.QueryStashChanges(_repo.FullPath, value.Name).Result();
+ }
+ else
+ {
+ changes = new Commands.CompareRevisions(_repo.FullPath, $"{value.SHA}^", value.SHA).Result();
+ if (value.Parents.Count == 3)
+ {
+ var untracked = new Commands.CompareRevisions(_repo.FullPath, "4b825dc642cb6eb9a060e54bf8d69288fbee4904", value.Parents[2]).Result();
+ var needSort = changes.Count > 0;
+
+ foreach (var c in untracked)
+ changes.Add(c);
+
+ if (needSort)
+ changes.Sort((l, r) => string.Compare(l.Path, r.Path, StringComparison.Ordinal));
+ }
}
Dispatcher.UIThread.Invoke(() => Changes = changes);