Reputation: 3972
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?
Upvotes: 11
Views: 3623
Reputation: 1685
Very similar to dmck's answer but more up to date
private bool TreeContainsFile(Tree tree, string filePath)
{
//filePath is the relative path of your file to the root directory
if (tree.Any(x => x.Path == filePath))
{
return true;
}
return tree.Where(x => x.GetType() == typeof (TreeEntry))
.Select(x => x.Target)
.OfType<Tree>()
.Any(branch => TreeContainsFile(branch, filePath));
}
Upvotes: 1
Reputation: 83
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));
Upvotes: 6
Reputation: 7861
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;
}
Upvotes: 6
Reputation: 1324218
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.
Upvotes: 5