How do I get a list of commits which contain a particular file, ie the equivalent of git log path
for LibGit2Sharp
.
Has it not been implemented or is there a way that I'm missing?
I was working on getting the same functionality into my application with LibGit2Sharp.
I wrote the code below which will list all of the commits that contain the file. The GitCommit class isn't included, but it is just a collection of properties.
My intention was to have the code only list commits where the file had changed, similar to a SVN log, but I haven't written that part yet.
Please note that the code hasn't been optimized, it was merely my initial attempt, but I hope it will be useful.
/// <summary>
/// Loads the history for a file
/// </summary>
/// <param name="filePath">Path to file</param>
/// <returns>List of version history</returns>
public List<IVersionHistory> LoadHistory(string filePath)
{
LibGit2Sharp.Repository repo = new Repository(this.pathToRepo);
string path = filePath.Replace(this.pathToRepo.Replace(System.IO.Path.DirectorySeparatorChar + ".git", string.Empty), string.Empty).Substring(1);
List<IVersionHistory> list = new List<IVersionHistory>();
foreach (Commit commit in repo.Head.Commits)
{
if (this.TreeContainsFile(commit.Tree, path) && list.Count(x => x.Date == commit.Author.When) == 0)
{
list.Add(new GitCommit() { Author = commit.Author.Name, Date = commit.Author.When, Message = commit.MessageShort} as IVersionHistory);
}
}
return list;
}
/// <summary>
/// Checks a GIT tree to see if a file exists
/// </summary>
/// <param name="tree">The GIT tree</param>
/// <param name="filename">The file name</param>
/// <returns>true if file exists</returns>
private bool TreeContainsFile(Tree tree, string filename)
{
if (tree.Any(x => x.Path == filename))
{
return true;
}
else
{
foreach (Tree branch in tree.Where(x => x.Type == GitObjectType.Tree).Select(x => x.Target as Tree))
{
if (this.TreeContainsFile(branch, filename))
{
return true;
}
}
}
return false;
}
LibGit2Sharp comes from the C library libgit2... which didn't include git log
in the first place ;)
Yet, LibGit2Sharp has its own git log
function:
Its page on git log
involves Filters, but a Filter doesn't seem to filter by path (as detailed in "How to exclude stashes while querying refs?").
So it doesn't seem to be implemented at the moment.
Each time when tree/blob has been changed it gets new id hash. All you need is to compare with parent commit tree/blob item hash:
var commits = repository.Commits
.Where(c => c.Parents.Count() == 1 && c.Tree["file"] != null &&
(c.Parents.FirstOrDefault().Tree["file"] == null ||
c.Tree["file"].Target.Id !=
c.Parents.FirstOrDefault().Tree["file"].Target.Id));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With