Created
June 19, 2012 12:20
-
-
Save 13xforever/2953835 to your computer and use it in GitHub Desktop.
Getting last commit with changes in specified subfolder in git repository
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
internal class GitInfo : VcsInfoRetriever | |
{ | |
public override VcsInfoData Execute(string localPath) | |
{ | |
string relativePath; | |
var repoPath = FindRepoRoot(localPath, ".git\\index", out relativePath); | |
if (repoPath == null) return null; | |
using (var repo = new Repository(repoPath)) | |
{ | |
Commit lastCommit = repo.Head.Tip; | |
if (!string.IsNullOrEmpty(relativePath)) | |
{ | |
var splitPath = relativePath.Replace('\\', '/').Trim('/').Split(Path.DirectorySeparatorChar); | |
var changeTreeId = GetTreeId(repo.Head.Tip, splitPath); | |
var previousCommit = repo.Head.Commits | |
.TakeWhile(commit => GetTreeId(commit, splitPath) == changeTreeId) | |
.LastOrDefault(); | |
if (previousCommit != null) | |
lastCommit = previousCommit; | |
} | |
if (lastCommit == null) return null; | |
return new VcsInfoData | |
{ | |
LastChangedDate = new DateTime(lastCommit.Author.When.Ticks), | |
LastChangedRevision = lastCommit.Sha, | |
RevisionIsSequentialNumber = false, | |
VcsName = "git", | |
}; | |
} | |
} | |
private static string FindRepoRoot(string startPath, string metaFile, out string relativePath) | |
{ | |
var completeStartPath = Path.GetFullPath(startPath); | |
relativePath = null; | |
string testPath; | |
do | |
{ | |
testPath = startPath; | |
string metaPath = Path.Combine(testPath, metaFile); | |
if (File.Exists(metaPath)) | |
{ | |
relativePath = completeStartPath.Substring(testPath.Length); | |
return testPath; | |
} | |
startPath = Path.GetFullPath(Path.Combine(startPath, "..")); | |
} while (testPath != startPath); | |
return null; | |
} | |
private static ObjectId GetTreeId(Commit commit, IEnumerable<string> relativePath) | |
{ | |
var root = commit.Tree; | |
foreach (var folder in relativePath) | |
{ | |
if (string.IsNullOrEmpty(folder)) continue; | |
var treeEntry = root[folder]; | |
if (treeEntry == null) return null; | |
root = (Tree)treeEntry.Target; | |
} | |
return root.Id; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment