Skip to content

Commit

Permalink
refactor: git version related commands
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
love-linger committed Jan 11, 2025
1 parent c939308 commit b26838f
Show file tree
Hide file tree
Showing 10 changed files with 305 additions and 102 deletions.
7 changes: 7 additions & 0 deletions src/Commands/Add.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,12 @@ public Add(string repo, List<Models.Change> changes)
}
Args = builder.ToString();
}

public Add(string repo, string pathspecFromFile)
{
WorkingDirectory = repo;
Context = repo;
Args = $"add --pathspec-from-file=\"{pathspecFromFile}\"";
}
}
}
61 changes: 31 additions & 30 deletions src/Commands/Stash.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,51 +17,52 @@ public bool Push(string message)
return Exec();
}

public bool Push(List<Models.Change> changes, string message, bool onlyStaged, bool keepIndex)
public bool Push(string message, List<Models.Change> changes, bool keepIndex)
{
var builder = new StringBuilder();
builder.Append("stash push ");
if (onlyStaged)
builder.Append("--staged ");
if (keepIndex)
builder.Append("--keep-index ");
builder.Append("-m \"");
builder.Append(message);
builder.Append("\" -- ");

if (onlyStaged)
{
foreach (var c in changes)
builder.Append($"\"{c.Path}\" ");
}
else
{
var needAdd = new List<Models.Change>();
foreach (var c in changes)
{
builder.Append($"\"{c.Path}\" ");
foreach (var c in changes)
builder.Append($"\"{c.Path}\" ");

if (c.WorkTree == Models.ChangeState.Added || c.WorkTree == Models.ChangeState.Untracked)
{
needAdd.Add(c);
if (needAdd.Count > 10)
{
new Add(WorkingDirectory, needAdd).Exec();
needAdd.Clear();
}
}
}
if (needAdd.Count > 0)
{
new Add(WorkingDirectory, needAdd).Exec();
needAdd.Clear();
}
}
Args = builder.ToString();
return Exec();
}

public bool Push(string message, string pathspecFromFile, bool keepIndex)
{
var builder = new StringBuilder();
builder.Append("stash push --pathspec-from-file=\"");
builder.Append(pathspecFromFile);
builder.Append("\" ");
if (keepIndex)
builder.Append("--keep-index ");
builder.Append("-m \"");
builder.Append(message);
builder.Append("\"");

Args = builder.ToString();
return Exec();
}

public bool PushOnlyStaged(string message, bool keepIndex)
{
var builder = new StringBuilder();
builder.Append("stash push --staged ");
if (keepIndex)
builder.Append("--keep-index ");
builder.Append("-m \"");
builder.Append(message);
builder.Append("\"");
Args = builder.ToString();
return Exec();
}

public bool Apply(string name)
{
Args = $"stash apply -q {name}";
Expand Down
19 changes: 0 additions & 19 deletions src/Commands/Version.cs

This file was deleted.

24 changes: 1 addition & 23 deletions src/Converters/StringConverters.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
using System;
using System.Globalization;
using System.Text.RegularExpressions;

using Avalonia.Data.Converters;
using Avalonia.Styling;

namespace SourceGit.Converters
{
public static partial class StringConverters
public static class StringConverters
{
public class ToLocaleConverter : IValueConverter
{
Expand Down Expand Up @@ -68,22 +67,6 @@ public object ConvertBack(object value, Type targetType, object parameter, Cultu
public static readonly FuncValueConverter<string, string> ToShortSHA =
new FuncValueConverter<string, string>(v => v == null ? string.Empty : (v.Length > 10 ? v.Substring(0, 10) : v));

public static readonly FuncValueConverter<string, bool> UnderRecommendGitVersion =
new(v =>
{
var match = REG_GIT_VERSION().Match(v ?? "");
if (match.Success)
{
var major = int.Parse(match.Groups[1].Value);
var minor = int.Parse(match.Groups[2].Value);
var build = int.Parse(match.Groups[3].Value);

return new Version(major, minor, build) < MINIMAL_GIT_VERSION;
}

return true;
});

public static readonly FuncValueConverter<string, string> TrimRefsPrefix =
new FuncValueConverter<string, string>(v =>
{
Expand All @@ -95,10 +78,5 @@ public object ConvertBack(object value, Type targetType, object parameter, Cultu
return v.Substring(13);
return v;
});

[GeneratedRegex(@"^[\s\w]*(\d+)\.(\d+)[\.\-](\d+).*$")]
private static partial Regex REG_GIT_VERSION();

private static readonly Version MINIMAL_GIT_VERSION = new Version(2, 23, 0);
}
}
25 changes: 25 additions & 0 deletions src/Models/GitVersions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
namespace SourceGit.Models
{
public static class GitVersions
{
/// <summary>
/// The minimal version of Git that required by this app.
/// </summary>
public static readonly System.Version MINIMAL = new System.Version(2, 23, 0);

/// <summary>
/// The minimal version of Git that supports the `add` command with the `--pathspec-from-file` option.
/// </summary>
public static readonly System.Version ADD_WITH_PATHSPECFILE = new System.Version(2, 25, 0);

/// <summary>
/// The minimal version of Git that supports the `stash` command with the `--pathspec-from-file` option.
/// </summary>
public static readonly System.Version STASH_WITH_PATHSPECFILE = new System.Version(2, 26, 0);

/// <summary>
/// The minimal version of Git that supports the `stash` command with the `--staged` option.
/// </summary>
public static readonly System.Version STASH_ONLY_STAGED = new System.Version(2, 35, 0);
}
}
107 changes: 101 additions & 6 deletions src/Native/OS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

using Avalonia;

namespace SourceGit.Native
{
public static class OS
public static partial class OS
{
public interface IBackend
{
Expand All @@ -23,11 +25,51 @@ public interface IBackend
void OpenWithDefaultEditor(string file);
}

public static string DataDir { get; private set; } = string.Empty;
public static string GitExecutable { get; set; } = string.Empty;
public static string ShellOrTerminal { get; set; } = string.Empty;
public static List<Models.ExternalTool> ExternalTools { get; set; } = [];
public static string CustomPathEnv { get; set; } = string.Empty;
public static string DataDir {
get;
private set;
} = string.Empty;

public static string CustomPathEnv
{
get;
set;
} = string.Empty;

public static string GitExecutable
{
get => _gitExecutable;
set
{
if (_gitExecutable != value)
{
_gitExecutable = value;
UpdateGitVersion();
}
}
}

public static string GitVersionString
{
get;
private set;
} = string.Empty;

public static Version GitVersion
{
get;
private set;
} = new Version(0, 0, 0);

public static string ShellOrTerminal {
get;
set;
} = string.Empty;

public static List<Models.ExternalTool> ExternalTools {
get;
set;
} = [];

static OS()
{
Expand Down Expand Up @@ -123,6 +165,59 @@ public static void OpenWithDefaultEditor(string file)
_backend.OpenWithDefaultEditor(file);
}

private static void UpdateGitVersion()
{
if (string.IsNullOrEmpty(_gitExecutable) || !File.Exists(_gitExecutable))
{
GitVersionString = string.Empty;
GitVersion = new Version(0, 0, 0);
return;
}

var start = new ProcessStartInfo();
start.FileName = _gitExecutable;
start.Arguments = "--version";
start.UseShellExecute = false;
start.CreateNoWindow = true;
start.RedirectStandardOutput = true;
start.RedirectStandardError = true;
start.StandardOutputEncoding = Encoding.UTF8;
start.StandardErrorEncoding = Encoding.UTF8;

var proc = new Process() { StartInfo = start };
try
{
proc.Start();

var rs = proc.StandardOutput.ReadToEnd();
proc.WaitForExit();
if (proc.ExitCode == 0 && !string.IsNullOrWhiteSpace(rs))
{
GitVersionString = rs.Trim();

var match = REG_GIT_VERSION().Match(GitVersionString);
if (match.Success)
{
var major = int.Parse(match.Groups[1].Value);
var minor = int.Parse(match.Groups[2].Value);
var build = int.Parse(match.Groups[3].Value);
GitVersion = new Version(major, minor, build);
GitVersionString = GitVersionString.Substring(11).Trim();
}
}
}
catch
{
// Ignore errors
}

proc.Close();
}

[GeneratedRegex(@"^git version[\s\w]*(\d+)\.(\d+)[\.\-](\d+).*$")]
private static partial Regex REG_GIT_VERSION();

private static IBackend _backend = null;
private static string _gitExecutable = string.Empty;
}
}
Loading

0 comments on commit b26838f

Please sign in to comment.