sourcegit/src/Commands/QueryFileChangedLines.cs
2025-04-13 17:12:36 +02:00

124 lines
4.1 KiB
C#

using System.IO;
namespace SourceGit.Commands
{
public class QueryFileChangedLines : Command
{
public QueryFileChangedLines(string repo, string revision1, string revision2, string filePath)
{
WorkingDirectory = repo;
Context = repo;
_repo = repo;
_filePath = filePath;
// Handle various diff scenarios
if (string.IsNullOrEmpty(revision1) && string.IsNullOrEmpty(revision2))
{
// Working copy changes (unstaged)
Args = $"diff --numstat -- \"{filePath}\"";
_checkNewWorkingDirFile = true;
}
else if (string.IsNullOrEmpty(revision1) && revision2 == "--staged")
{
// Staged changes
Args = $"diff --cached --numstat -- \"{filePath}\"";
_checkNewStagedFile = true;
}
else if (string.IsNullOrEmpty(revision1) || revision1 == "/dev/null")
{
// New file case - we'll count lines manually
_isNewFile = true;
_newRevision = revision2;
}
else
{
// Comparing two revisions
Args = $"diff --numstat {revision1} {revision2} -- \"{filePath}\"";
}
}
public (int, int) Result()
{
_addedLines = 0;
_removedLines = 0;
// Check for new files first
if (_isNewFile || _checkNewWorkingDirFile || _checkNewStagedFile)
{
int lineCount = 0;
if (_isNewFile && !string.IsNullOrEmpty(_newRevision))
{
var stream = QueryFileContent.Run(_repo, _newRevision, _filePath);
using (var reader = new StreamReader(stream))
{
string line;
while ((line = reader.ReadLine()) != null)
{
lineCount++;
}
}
}
else
{
var fullPath = Path.Combine(_repo, _filePath);
if (File.Exists(fullPath))
{
if (_checkNewWorkingDirFile || _checkNewStagedFile)
{
Exec();
if (_addedLines == 0 && _removedLines == 0)
{
var lines = File.ReadAllLines(fullPath);
lineCount = lines.Length;
}
else
{
return (_addedLines, _removedLines);
}
}
else
{
var lines = File.ReadAllLines(fullPath);
lineCount = lines.Length;
}
}
}
if (lineCount > 0)
{
return (lineCount, 0);
}
}
Exec();
return (_addedLines, _removedLines);
}
protected override void OnReadline(string line)
{
var parts = line.Split('\t');
if (parts.Length >= 2)
{
if (int.TryParse(parts[0], out int added))
{
_addedLines = added;
}
if (int.TryParse(parts[1], out int removed))
{
_removedLines = removed;
}
}
}
private readonly string _repo;
private readonly string _filePath;
private readonly bool _isNewFile = false;
private readonly string _newRevision = null;
private readonly bool _checkNewWorkingDirFile = false;
private readonly bool _checkNewStagedFile = false;
private int _addedLines;
private int _removedLines;
}
}