refactor: git version related commands

* use `--pathspec-from-file=<FILE>` in `git add` command if git >= 2.25.0
* use `--pathspec-from-file=<FILE>` in `git stash push` command if git >= 2.26.0
* use `--staged` in `git stash push` command only if git >= 2.35.0
This commit is contained in:
leo 2025-01-11 17:29:38 +08:00
parent c939308e4c
commit b26838ff68
No known key found for this signature in database
10 changed files with 306 additions and 103 deletions

View file

@ -1,4 +1,6 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
namespace SourceGit.ViewModels
@ -45,37 +47,122 @@ namespace SourceGit.ViewModels
public override Task<bool> Sure()
{
var jobs = _changes;
if (!HasSelectedFiles && !IncludeUntracked)
{
jobs = new List<Models.Change>();
foreach (var job in _changes)
{
if (job.WorkTree != Models.ChangeState.Untracked && job.WorkTree != Models.ChangeState.Added)
{
jobs.Add(job);
}
}
}
if (jobs.Count == 0)
return null;
_repo.SetWatcherEnabled(false);
ProgressDescription = $"Stash changes ...";
return Task.Run(() =>
{
var succ = new Commands.Stash(_repo.FullPath).Push(jobs, Message, !HasSelectedFiles && OnlyStaged, KeepIndex);
var succ = false;
if (!HasSelectedFiles)
{
if (OnlyStaged)
{
if (Native.OS.GitVersion >= Models.GitVersions.STASH_ONLY_STAGED)
{
succ = new Commands.Stash(_repo.FullPath).PushOnlyStaged(Message, KeepIndex);
}
else
{
var staged = new List<Models.Change>();
foreach (var c in _changes)
{
if (c.Index != Models.ChangeState.None && c.Index != Models.ChangeState.Untracked)
staged.Add(c);
}
succ = StashWithChanges(staged);
}
}
else
{
if (IncludeUntracked)
AddUntracked(_changes);
succ = StashWithChanges(_changes);
}
}
else
{
AddUntracked(_changes);
succ = StashWithChanges(_changes);
}
CallUIThread(() =>
{
_repo.MarkWorkingCopyDirtyManually();
_repo.SetWatcherEnabled(true);
});
return succ;
});
}
private void AddUntracked(List<Models.Change> changes)
{
var toBeAdded = new List<Models.Change>();
foreach (var c in changes)
{
if (c.WorkTree == Models.ChangeState.Added || c.WorkTree == Models.ChangeState.Untracked)
toBeAdded.Add(c);
}
if (toBeAdded.Count == 0)
return;
if (Native.OS.GitVersion >= Models.GitVersions.ADD_WITH_PATHSPECFILE)
{
var paths = new List<string>();
foreach (var c in toBeAdded)
paths.Add(c.Path);
var tmpFile = Path.GetTempFileName();
File.WriteAllLines(tmpFile, paths);
new Commands.Add(_repo.FullPath, tmpFile).Exec();
File.Delete(tmpFile);
}
else
{
for (int i = 0; i < toBeAdded.Count; i += 10)
{
var count = Math.Min(10, toBeAdded.Count - i);
var step = toBeAdded.GetRange(i, count);
new Commands.Add(_repo.FullPath, step).Exec();
}
}
}
private bool StashWithChanges(List<Models.Change> changes)
{
if (changes.Count == 0)
return true;
var succ = false;
if (Native.OS.GitVersion >= Models.GitVersions.STASH_WITH_PATHSPECFILE)
{
var paths = new List<string>();
foreach (var c in changes)
paths.Add(c.Path);
var tmpFile = Path.GetTempFileName();
File.WriteAllLines(tmpFile, paths);
succ = new Commands.Stash(_repo.FullPath).Push(Message, tmpFile, KeepIndex);
File.Delete(tmpFile);
}
else
{
for (int i = 0; i < changes.Count; i += 10)
{
var count = Math.Min(10, changes.Count - i);
var step = changes.GetRange(i, count);
succ = new Commands.Stash(_repo.FullPath).Push(Message, step, KeepIndex);
if (!succ)
break;
}
}
return succ;
}
private readonly Repository _repo = null;
private readonly List<Models.Change> _changes = null;
}

View file

@ -347,6 +347,17 @@ namespace SourceGit.ViewModels
{
await Task.Run(() => new Commands.Add(_repo.FullPath, _repo.IncludeUntracked).Exec());
}
else if (Native.OS.GitVersion >= Models.GitVersions.ADD_WITH_PATHSPECFILE)
{
var paths = new List<string>();
foreach (var c in changes)
paths.Add(c.Path);
var tmpFile = Path.GetTempFileName();
File.WriteAllLines(tmpFile, paths);
await Task.Run(() => new Commands.Add(_repo.FullPath, tmpFile).Exec());
File.Delete(tmpFile);
}
else
{
for (int i = 0; i < changes.Count; i += 10)