Skip to content

Commit 78f9ae2

Browse files
committed
refactor: rewrite git restore integration
Signed-off-by: leo <[email protected]>
1 parent 80df53c commit 78f9ae2

File tree

5 files changed

+71
-18
lines changed

5 files changed

+71
-18
lines changed

src/Commands/Discard.cs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public static void All(string repo, bool includeIgnored, Models.ICommandLog log)
3636
});
3737
}
3838

39-
new Restore(repo, false) { Log = log }.Exec();
39+
new Restore(repo) { Log = log }.Exec();
4040
if (includeIgnored)
4141
new Clean(repo) { Log = log }.Exec();
4242
}
@@ -71,10 +71,20 @@ public static void Changes(string repo, List<Models.Change> changes, Models.ICom
7171
});
7272
}
7373

74-
for (int i = 0; i < restores.Count; i += 10)
74+
if (Native.OS.GitVersion >= Models.GitVersions.RESTORE_WITH_PATHSPECFILE)
7575
{
76-
var count = Math.Min(10, restores.Count - i);
77-
new Restore(repo, restores.GetRange(i, count), "--worktree --recurse-submodules") { Log = log }.Exec();
76+
var tmpFile = Path.GetTempFileName();
77+
File.WriteAllLines(tmpFile, restores);
78+
new Restore(repo, tmpFile, "--worktree --recurse-submodules") { Log = log }.Exec();
79+
File.Delete(tmpFile);
80+
}
81+
else
82+
{
83+
for (int i = 0; i < restores.Count; i += 32)
84+
{
85+
var count = Math.Min(32, restores.Count - i);
86+
new Restore(repo, restores.GetRange(i, count), "--worktree --recurse-submodules") { Log = log }.Exec();
87+
}
7888
}
7989
}
8090
}

src/Commands/Restore.cs

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,23 @@ namespace SourceGit.Commands
55
{
66
public class Restore : Command
77
{
8-
public Restore(string repo, bool onlyStaged)
8+
/// <summary>
9+
/// Only used to discard all changes in the working directory and staged area.
10+
/// </summary>
11+
/// <param name="repo"></param>
12+
public Restore(string repo)
913
{
1014
WorkingDirectory = repo;
1115
Context = repo;
12-
13-
if (onlyStaged)
14-
Args = "restore --source=HEAD --staged .";
15-
else
16-
Args = "restore --source=HEAD --staged --worktree --recurse-submodules .";
16+
Args = "restore --source=HEAD --staged --worktree --recurse-submodules .";
1717
}
1818

19+
/// <summary>
20+
/// Discard changes with git (&lt; 2.25.0) that does not support the `--pathspec-from-file` option.
21+
/// </summary>
22+
/// <param name="repo"></param>
23+
/// <param name="files"></param>
24+
/// <param name="extra"></param>
1925
public Restore(string repo, List<string> files, string extra)
2026
{
2127
WorkingDirectory = repo;
@@ -30,5 +36,24 @@ public Restore(string repo, List<string> files, string extra)
3036
builder.Append(' ').Append('"').Append(f).Append('"');
3137
Args = builder.ToString();
3238
}
39+
40+
/// <summary>
41+
/// Discard changes with git (&gt;= 2.25.0) that supports the `--pathspec-from-file` option.
42+
/// </summary>
43+
/// <param name="repo"></param>
44+
/// <param name="pathspecFile"></param>
45+
/// <param name="extra"></param>
46+
public Restore(string repo, string pathspecFile, string extra)
47+
{
48+
WorkingDirectory = repo;
49+
Context = repo;
50+
51+
var builder = new StringBuilder();
52+
builder.Append("restore ");
53+
if (!string.IsNullOrEmpty(extra))
54+
builder.Append(extra).Append(" ");
55+
builder.Append("--pathspec-from-file=\"").Append(pathspecFile).Append('"');
56+
Args = builder.ToString();
57+
}
3358
}
3459
}

src/Models/GitVersions.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ public static class GitVersions
1111
/// The minimal version of Git that supports the `add` command with the `--pathspec-from-file` option.
1212
/// </summary>
1313
public static readonly System.Version ADD_WITH_PATHSPECFILE = new System.Version(2, 25, 0);
14+
15+
/// <summary>
16+
/// The minimal version of Git that supports the `restore` command with the `--pathspec-from-file` option.
17+
/// </summary>
18+
public static readonly System.Version RESTORE_WITH_PATHSPECFILE = new System.Version(2, 25, 0);
1419

1520
/// <summary>
1621
/// The minimal version of Git that supports the `stash push` command with the `--pathspec-from-file` option.

src/ViewModels/StashChanges.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,9 @@ private bool StashWithChanges(List<Models.Change> changes, CommandLog log)
124124
}
125125
else
126126
{
127-
for (int i = 0; i < changes.Count; i += 10)
127+
for (int i = 0; i < changes.Count; i += 32)
128128
{
129-
var count = Math.Min(10, changes.Count - i);
129+
var count = Math.Min(32, changes.Count - i);
130130
var step = changes.GetRange(i, count);
131131
succ = new Commands.Stash(_repo.FullPath).Use(log).Push(Message, step, KeepIndex);
132132
if (!succ)

src/ViewModels/WorkingCopy.cs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1634,13 +1634,14 @@ private async void StageChanges(List<Models.Change> changes, Models.Change next)
16341634
foreach (var c in changes)
16351635
paths.Add(c.Path);
16361636

1637-
for (int i = 0; i < count; i += 10)
1637+
for (int i = 0; i < count; i += 32)
16381638
{
1639-
var step = paths.GetRange(i, Math.Min(10, count - i));
1639+
var step = paths.GetRange(i, Math.Min(32, count - i));
16401640
await Task.Run(() => new Commands.Add(_repo.FullPath, step).Use(log).Exec());
16411641
}
16421642
}
16431643
log.Complete();
1644+
16441645
_repo.MarkWorkingCopyDirtyManually();
16451646
_repo.SetWatcherEnabled(true);
16461647
IsStaging = false;
@@ -1664,15 +1665,26 @@ private async void UnstageChanges(List<Models.Change> changes, Models.Change nex
16641665
log.AppendLine("$ git update-index --index-info ");
16651666
await Task.Run(() => new Commands.UnstageChangesForAmend(_repo.FullPath, changes).Exec());
16661667
}
1667-
else if (count == _staged.Count)
1668+
else if (Native.OS.GitVersion >= Models.GitVersions.RESTORE_WITH_PATHSPECFILE)
16681669
{
1669-
await Task.Run(() => new Commands.Restore(_repo.FullPath, true).Use(log).Exec());
1670+
var paths = new List<string>();
1671+
foreach (var c in changes)
1672+
{
1673+
paths.Add(c.Path);
1674+
if (c.Index == Models.ChangeState.Renamed)
1675+
paths.Add(c.OriginalPath);
1676+
}
1677+
1678+
var tmpFile = Path.GetTempFileName();
1679+
File.WriteAllLines(tmpFile, paths);
1680+
await Task.Run(() => new Commands.Restore(_repo.FullPath, tmpFile, "--staged").Use(log).Exec());
1681+
File.Delete(tmpFile);
16701682
}
16711683
else
16721684
{
1673-
for (int i = 0; i < count; i += 10)
1685+
for (int i = 0; i < count; i += 32)
16741686
{
1675-
var step = changes.GetRange(i, Math.Min(10, count - i));
1687+
var step = changes.GetRange(i, Math.Min(32, count - i));
16761688
var files = new List<string>();
16771689
foreach (var c in step)
16781690
{
@@ -1685,6 +1697,7 @@ private async void UnstageChanges(List<Models.Change> changes, Models.Change nex
16851697
}
16861698
}
16871699
log.Complete();
1700+
16881701
_repo.MarkWorkingCopyDirtyManually();
16891702
_repo.SetWatcherEnabled(true);
16901703
IsUnstaging = false;

0 commit comments

Comments
 (0)