In Git, I can get all of need commits via
git log hash..master --ancestry-path --merges
Is there an equivalent to do this in LibGit2Sharp?
First some basics:
git log topic..master
var filter = new CommitFilter {
SortBy = CommitSortStrategies.Time,
Since = master,
Until = topic,
};
var commitList = repo.Commits.QueryBy (filter);
git log topic..master --merges
var filter = new CommitFilter {
SortBy = CommitSortStrategies.Time,
Since = master,
Until = topic,
};
var commitList = repo.Commits.QueryBy (filter);
var mergeList = commitList.Where (p => p.Parents.Count () >= 2);
Now to your question:
git log topic..master --ancestry-path --merges
ancestry-path =
When given a range of commits to display (e.g. commit1..commit2 or commit2 ^commit1), only display commits that exist directly on the ancestry chain between the commit1 and commit2, i.e. commits that are both descendants of commit1, and ancestors of commit2.
The -merges
are easy once we have the ancestry path as we can filter the commits that have more then one parent. Getting the ancestry path requires some coding ;-)
Since the ICommitLog
that is returned from commitList
in the first example above contains a DAG (Directed Acyclic Graph) via the .Parents
property, we need to walk the graph and get "all the simple paths” via a depth-first search to find all non-cyclical paths. Once you have a list of all the simple
paths just filter it by which commits have >=2
parents.
Note: I have done this in a few C# projects and even simple ones like calc'ing the pull-request related to a particular commit uses this depth-first ancestry. I tend to stay away from Linq to do this as I have huge
commit lists (100k+ nodes between the start to end nodes within just the sub-DAG that I searching) and also avoid recursive methods due to stack size but your use-case may/will differ. If you get stuck at this point, post another question with your algorithm/code issue.