diff --git a/src/Commands/Discard.cs b/src/Commands/Discard.cs index f245799c..0c3854c8 100644 --- a/src/Commands/Discard.cs +++ b/src/Commands/Discard.cs @@ -36,7 +36,7 @@ namespace SourceGit.Commands }); } - new Restore(repo, false) { Log = log }.Exec(); + new Restore(repo) { Log = log }.Exec(); if (includeIgnored) new Clean(repo) { Log = log }.Exec(); } @@ -71,10 +71,20 @@ namespace SourceGit.Commands }); } - for (int i = 0; i < restores.Count; i += 10) + if (Native.OS.GitVersion >= Models.GitVersions.RESTORE_WITH_PATHSPECFILE) { - var count = Math.Min(10, restores.Count - i); - new Restore(repo, restores.GetRange(i, count), "--worktree --recurse-submodules") { Log = log }.Exec(); + var tmpFile = Path.GetTempFileName(); + File.WriteAllLines(tmpFile, restores); + new Restore(repo, tmpFile, "--worktree --recurse-submodules") { Log = log }.Exec(); + File.Delete(tmpFile); + } + else + { + for (int i = 0; i < restores.Count; i += 32) + { + var count = Math.Min(32, restores.Count - i); + new Restore(repo, restores.GetRange(i, count), "--worktree --recurse-submodules") { Log = log }.Exec(); + } } } } diff --git a/src/Commands/Restore.cs b/src/Commands/Restore.cs index be0179e9..b8e5e0c7 100644 --- a/src/Commands/Restore.cs +++ b/src/Commands/Restore.cs @@ -5,17 +5,23 @@ namespace SourceGit.Commands { public class Restore : Command { - public Restore(string repo, bool onlyStaged) + /// + /// Only used to discard all changes in the working directory and staged area. + /// + /// + public Restore(string repo) { WorkingDirectory = repo; Context = repo; - - if (onlyStaged) - Args = "restore --source=HEAD --staged ."; - else - Args = "restore --source=HEAD --staged --worktree --recurse-submodules ."; + Args = "restore --source=HEAD --staged --worktree --recurse-submodules ."; } + /// + /// Discard changes with git (< 2.25.0) that does not support the `--pathspec-from-file` option. + /// + /// + /// + /// public Restore(string repo, List files, string extra) { WorkingDirectory = repo; @@ -30,5 +36,24 @@ namespace SourceGit.Commands builder.Append(' ').Append('"').Append(f).Append('"'); Args = builder.ToString(); } + + /// + /// Discard changes with git (>= 2.25.0) that supports the `--pathspec-from-file` option. + /// + /// + /// + /// + public Restore(string repo, string pathspecFile, string extra) + { + WorkingDirectory = repo; + Context = repo; + + var builder = new StringBuilder(); + builder.Append("restore "); + if (!string.IsNullOrEmpty(extra)) + builder.Append(extra).Append(" "); + builder.Append("--pathspec-from-file=\"").Append(pathspecFile).Append('"'); + Args = builder.ToString(); + } } } diff --git a/src/Models/GitVersions.cs b/src/Models/GitVersions.cs index 81d85870..b06d3e34 100644 --- a/src/Models/GitVersions.cs +++ b/src/Models/GitVersions.cs @@ -11,6 +11,11 @@ /// The minimal version of Git that supports the `add` command with the `--pathspec-from-file` option. /// public static readonly System.Version ADD_WITH_PATHSPECFILE = new System.Version(2, 25, 0); + + /// + /// The minimal version of Git that supports the `restore` command with the `--pathspec-from-file` option. + /// + public static readonly System.Version RESTORE_WITH_PATHSPECFILE = new System.Version(2, 25, 0); /// /// The minimal version of Git that supports the `stash push` command with the `--pathspec-from-file` option. diff --git a/src/ViewModels/StashChanges.cs b/src/ViewModels/StashChanges.cs index 0b4fa7db..75edfb7b 100644 --- a/src/ViewModels/StashChanges.cs +++ b/src/ViewModels/StashChanges.cs @@ -124,9 +124,9 @@ namespace SourceGit.ViewModels } else { - for (int i = 0; i < changes.Count; i += 10) + for (int i = 0; i < changes.Count; i += 32) { - var count = Math.Min(10, changes.Count - i); + var count = Math.Min(32, changes.Count - i); var step = changes.GetRange(i, count); succ = new Commands.Stash(_repo.FullPath).Use(log).Push(Message, step, KeepIndex); if (!succ) diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs index 38cc0153..c17cea44 100644 --- a/src/ViewModels/WorkingCopy.cs +++ b/src/ViewModels/WorkingCopy.cs @@ -1634,13 +1634,14 @@ namespace SourceGit.ViewModels foreach (var c in changes) paths.Add(c.Path); - for (int i = 0; i < count; i += 10) + for (int i = 0; i < count; i += 32) { - var step = paths.GetRange(i, Math.Min(10, count - i)); + var step = paths.GetRange(i, Math.Min(32, count - i)); await Task.Run(() => new Commands.Add(_repo.FullPath, step).Use(log).Exec()); } } log.Complete(); + _repo.MarkWorkingCopyDirtyManually(); _repo.SetWatcherEnabled(true); IsStaging = false; @@ -1664,15 +1665,26 @@ namespace SourceGit.ViewModels log.AppendLine("$ git update-index --index-info "); await Task.Run(() => new Commands.UnstageChangesForAmend(_repo.FullPath, changes).Exec()); } - else if (count == _staged.Count) + else if (Native.OS.GitVersion >= Models.GitVersions.RESTORE_WITH_PATHSPECFILE) { - await Task.Run(() => new Commands.Restore(_repo.FullPath, true).Use(log).Exec()); + var paths = new List(); + foreach (var c in changes) + { + paths.Add(c.Path); + if (c.Index == Models.ChangeState.Renamed) + paths.Add(c.OriginalPath); + } + + var tmpFile = Path.GetTempFileName(); + File.WriteAllLines(tmpFile, paths); + await Task.Run(() => new Commands.Restore(_repo.FullPath, tmpFile, "--staged").Use(log).Exec()); + File.Delete(tmpFile); } else { - for (int i = 0; i < count; i += 10) + for (int i = 0; i < count; i += 32) { - var step = changes.GetRange(i, Math.Min(10, count - i)); + var step = changes.GetRange(i, Math.Min(32, count - i)); var files = new List(); foreach (var c in step) { @@ -1685,6 +1697,7 @@ namespace SourceGit.ViewModels } } log.Complete(); + _repo.MarkWorkingCopyDirtyManually(); _repo.SetWatcherEnabled(true); IsUnstaging = false;