You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否用LibGit2Sharp复现指定git log命令并获取文件统计?

用LibGit2Sharp复现目标Git命令并实现需求

完全可以用LibGit2Sharp复现你指定的git命令,同时满足获取提交哈希、作者日期、文件增删行数,以及处理路径变更/重命名的需求。以下是具体实现思路和代码示例:

1. 核心配置与提交遍历

首先初始化仓库,设置和原命令匹配的提交遍历规则:

  • 只走当前分支的第一父提交(对应--first-parent)
  • 过滤出过去61个月内的提交(对应--since-as-filter=61.months.ago)
  • 仅加载必要字段,跳过提交消息以节省资源
using LibGit2Sharp;
using System;
using System.Collections.Generic;
using System.Linq;

var repoPath = "你的仓库路径";
var cutoffDate = DateTime.Now.AddMonths(-61);

using var repo = new Repository(repoPath);
var currentBranch = repo.Head;

// 构建提交过滤规则
var commitFilter = new CommitFilter
{
    IncludeReachableFrom = currentBranch,
    FirstParentOnly = true,
    Since = cutoffDate,
    SortBy = CommitSortStrategies.Time // 按提交时间排序
};

2. 获取提交的文件统计与变更信息

LibGit2Sharp的Commit对象通过Stats属性提供文件增删行数,同时利用TreeChanges可以识别文件重命名、路径变更等操作:

foreach (var commit in repo.Commits.QueryBy(commitFilter))
{
    // 获取提交完整哈希和本地时区的作者日期
    var commitHash = commit.Sha;
    var localAuthorDate = commit.Author.When.ToLocalTime();

    // 跳过初始提交(无父提交)的特殊处理
    var parentCommit = commit.Parents.FirstOrDefault();
    if (parentCommit == null) continue;

    // 对比当前提交与父提交的树变更,识别重命名/路径修改
    var treeChanges = repo.Diff.Compare<TreeChanges>(parentCommit.Tree, commit.Tree);

    foreach (var change in treeChanges)
    {
        string targetFilePath = change.Path;
        // 处理重命名:保留原路径或新路径可按需调整
        if (change.Status == ChangeKind.Renamed)
        {
            targetFilePath = change.OldPath;
        }

        // 获取当前文件的增删行数
        if (commit.Stats.TryGetEntry(targetFilePath, out var fileStat))
        {
            int additions = fileStat.Additions;
            int deletions = fileStat.Deletions;

            // 此处可将数据存入自定义对象或字典,用于后续任务处理
        }
    }
}

3. 实现你的两个核心任务

任务1:找出每个文件最后被修改的时间

用字典记录每个文件的最新修改时间,遍历提交时更新:

var fileLastModified = new Dictionary<string, DateTime>();

foreach (var commit in repo.Commits.QueryBy(commitFilter))
{
    var localDate = commit.Author.When.ToLocalTime();
    var parentCommit = commit.Parents.FirstOrDefault();
    if (parentCommit == null) continue;

    var treeChanges = repo.Diff.Compare<TreeChanges>(parentCommit.Tree, commit.Tree);
    foreach (var change in treeChanges)
    {
        // 处理重命名场景,同时更新原路径和新路径的记录
        if (change.Status == ChangeKind.Renamed)
        {
            UpdateFileLastModified(change.OldPath, localDate);
            UpdateFileLastModified(change.Path, localDate);
        }
        else
        {
            UpdateFileLastModified(change.Path, localDate);
        }
    }
}

// 辅助方法:更新文件最后修改时间
void UpdateFileLastModified(string filePath, DateTime newDate)
{
    if (!fileLastModified.ContainsKey(filePath) || newDate > fileLastModified[filePath])
    {
        fileLastModified[filePath] = newDate;
    }
}

任务2:统计过去30天内的代码增删行数

添加时间过滤,仅统计近30天的提交数据:

var thirtyDaysAgo = DateTime.Now.AddDays(-30);
int totalAdditions = 0;
int totalDeletions = 0;

foreach (var commit in repo.Commits.QueryBy(commitFilter))
{
    var localDate = commit.Author.When.ToLocalTime();
    // 跳过30天前的提交
    if (localDate < thirtyDaysAgo) continue;

    var parentCommit = commit.Parents.FirstOrDefault();
    if (parentCommit == null) continue;

    var treeChanges = repo.Diff.Compare<TreeChanges>(parentCommit.Tree, commit.Tree);
    foreach (var change in treeChanges)
    {
        string filePath = change.Status == ChangeKind.Renamed ? change.OldPath : change.Path;
        if (commit.Stats.TryGetEntry(filePath, out var fileStat))
        {
            totalAdditions += fileStat.Additions;
            totalDeletions += fileStat.Deletions;
        }
    }
}

// 输出统计结果
Console.WriteLine($"近30天新增行数:{totalAdditions}");
Console.WriteLine($"近30天删除行数:{totalDeletions}");

关键注意事项

  • 重命名处理:通过TreeChanges的ChangeKind.Renamed标记,可以避免将同一文件的不同路径视为独立文件,保证统计准确性。
  • 性能优化:全程仅加载必要的提交属性,跳过提交消息等无关数据,适配无服务器环境的资源限制。
  • 时区转换:LibGit2Sharp默认使用UTC时间,通过ToLocalTime()转换为本地时间,和原命令的--date=local行为一致。

内容的提问来源于stack exchange,提问作者scottctr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 17:43:06