2024-02-05 23:08:37 -08:00
|
|
|
|
using System;
|
2024-06-17 03:25:57 -07:00
|
|
|
|
using System.Collections.Generic;
|
2021-06-06 23:14:53 -07:00
|
|
|
|
using System.IO;
|
2024-06-17 03:25:57 -07:00
|
|
|
|
using System.Text.RegularExpressions;
|
2021-06-06 23:14:53 -07:00
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
namespace SourceGit.Commands
|
|
|
|
|
{
|
2024-06-17 03:25:57 -07:00
|
|
|
|
public partial class LFS
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-06-17 03:25:57 -07:00
|
|
|
|
[GeneratedRegex(@"^(.+)\s+(\w+)\s+\w+:(\d+)$")]
|
|
|
|
|
private static partial Regex REG_LOCK();
|
|
|
|
|
|
|
|
|
|
class SubCmd : Command
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-06-17 03:25:57 -07:00
|
|
|
|
public SubCmd(string repo, string args, Action<string> onProgress)
|
2024-03-17 18:37:06 -07:00
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
WorkingDirectory = repo;
|
|
|
|
|
Context = repo;
|
2024-06-17 03:25:57 -07:00
|
|
|
|
Args = args;
|
2022-02-09 22:27:46 -08:00
|
|
|
|
TraitErrorAsOutput = true;
|
2024-02-05 23:08:37 -08:00
|
|
|
|
_outputHandler = onProgress;
|
2022-02-09 22:27:46 -08:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
protected override void OnReadline(string line)
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
_outputHandler?.Invoke(line);
|
2022-02-09 22:27:46 -08:00
|
|
|
|
}
|
2024-02-05 23:08:37 -08:00
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
private readonly Action<string> _outputHandler;
|
2022-02-09 22:27:46 -08:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
public LFS(string repo)
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
_repo = repo;
|
2021-06-06 23:14:53 -07:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
public bool IsEnabled()
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
var path = Path.Combine(_repo, ".git", "hooks", "pre-push");
|
2024-03-31 01:54:29 -07:00
|
|
|
|
if (!File.Exists(path))
|
|
|
|
|
return false;
|
2021-06-06 23:14:53 -07:00
|
|
|
|
|
|
|
|
|
var content = File.ReadAllText(path);
|
|
|
|
|
return content.Contains("git lfs pre-push");
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-17 03:25:57 -07:00
|
|
|
|
public bool Install()
|
|
|
|
|
{
|
2024-06-26 00:51:49 -07:00
|
|
|
|
return new SubCmd(_repo, "lfs install --local", null).Exec();
|
2024-06-17 03:25:57 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool Track(string pattern, bool isFilenameMode = false)
|
|
|
|
|
{
|
|
|
|
|
var opt = isFilenameMode ? "--filename" : "";
|
|
|
|
|
return new SubCmd(_repo, $"lfs track {opt} \"{pattern}\"", null).Exec();
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-25 20:49:56 -07:00
|
|
|
|
public void Fetch(string remote, Action<string> outputHandler)
|
2024-06-17 03:25:57 -07:00
|
|
|
|
{
|
2024-06-25 20:49:56 -07:00
|
|
|
|
new SubCmd(_repo, $"lfs fetch {remote}", outputHandler).Exec();
|
2024-06-17 03:25:57 -07:00
|
|
|
|
}
|
|
|
|
|
|
2024-06-25 20:49:56 -07:00
|
|
|
|
public void Pull(string remote, Action<string> outputHandler)
|
2024-06-17 03:25:57 -07:00
|
|
|
|
{
|
2024-06-25 20:49:56 -07:00
|
|
|
|
new SubCmd(_repo, $"lfs pull {remote}", outputHandler).Exec();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Push(string remote, Action<string> outputHandler)
|
|
|
|
|
{
|
|
|
|
|
new SubCmd(_repo, $"lfs push {remote}", outputHandler).Exec();
|
2024-06-17 03:25:57 -07:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
public void Prune(Action<string> outputHandler)
|
|
|
|
|
{
|
2024-06-17 03:25:57 -07:00
|
|
|
|
new SubCmd(_repo, "lfs prune", outputHandler).Exec();
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-25 20:49:56 -07:00
|
|
|
|
public List<Models.LFSLock> Locks(string remote)
|
2024-06-17 03:25:57 -07:00
|
|
|
|
{
|
|
|
|
|
var locks = new List<Models.LFSLock>();
|
2024-06-25 20:49:56 -07:00
|
|
|
|
var cmd = new SubCmd(_repo, $"lfs locks --remote={remote}", null);
|
2024-06-17 03:25:57 -07:00
|
|
|
|
var rs = cmd.ReadToEnd();
|
|
|
|
|
if (rs.IsSuccess)
|
|
|
|
|
{
|
2024-07-14 09:30:31 -07:00
|
|
|
|
var lines = rs.StdOut.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
|
2024-06-17 03:25:57 -07:00
|
|
|
|
foreach (var line in lines)
|
|
|
|
|
{
|
|
|
|
|
var match = REG_LOCK().Match(line);
|
|
|
|
|
if (match.Success)
|
|
|
|
|
{
|
|
|
|
|
locks.Add(new Models.LFSLock()
|
|
|
|
|
{
|
|
|
|
|
File = match.Groups[1].Value,
|
|
|
|
|
User = match.Groups[2].Value,
|
|
|
|
|
ID = long.Parse(match.Groups[3].Value),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return locks;
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-25 20:49:56 -07:00
|
|
|
|
public bool Lock(string remote, string file)
|
2024-06-17 03:25:57 -07:00
|
|
|
|
{
|
2024-06-25 20:49:56 -07:00
|
|
|
|
return new SubCmd(_repo, $"lfs lock --remote={remote} \"{file}\"", null).Exec();
|
2024-06-17 03:25:57 -07:00
|
|
|
|
}
|
|
|
|
|
|
2024-06-25 20:49:56 -07:00
|
|
|
|
public bool Unlock(string remote, string file, bool force)
|
2024-06-17 03:25:57 -07:00
|
|
|
|
{
|
|
|
|
|
var opt = force ? "-f" : "";
|
2024-06-25 20:49:56 -07:00
|
|
|
|
return new SubCmd(_repo, $"lfs unlock --remote={remote} {opt} \"{file}\"", null).Exec();
|
2024-06-17 03:25:57 -07:00
|
|
|
|
}
|
|
|
|
|
|
2024-06-25 20:49:56 -07:00
|
|
|
|
public bool Unlock(string remote, long id, bool force)
|
2024-06-17 03:25:57 -07:00
|
|
|
|
{
|
|
|
|
|
var opt = force ? "-f" : "";
|
2024-06-25 20:49:56 -07:00
|
|
|
|
return new SubCmd(_repo, $"lfs unlock --remote={remote} {opt} --id={id}", null).Exec();
|
2021-06-06 23:14:53 -07:00
|
|
|
|
}
|
2022-02-09 22:27:46 -08:00
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
private readonly string _repo;
|
2021-06-06 23:14:53 -07:00
|
|
|
|
}
|
2024-03-31 01:54:29 -07:00
|
|
|
|
}
|