/// <summary> /// Returns a list of visual branches which are around the given commit. /// </summary> /// <param name="commit"></param> /// <param name="repo"></param> /// <returns></returns> public static List<Branch> GetBranchesAroundCommit(Commit commit, ObservableCollection<Branch> branches) { List<Branch> list = new List<Branch>(); // Loop through all branches and determine if they are around the specified commit. foreach (Branch branch in branches) { // Tip has to be found and in case multiple branches share the tree, get rid of the others -- messes up visual position counting. if (branch.Tip == null || list.Any(b => branch.Tip.Branches.Contains(b)) || list.Any(b => b.Tip.Branches.Contains(branch))) continue; // The branch's tip must be newer/same than the commit. if (branch.Tip.Date >= commit.Date) // TODO: && first commit-ever must be older? We might not need to do that... ... ? { list.Add(branch); } else { // If there's a branch with a tip commit older than commit.Date, then it's around this commit if they don't share a single branch. bool foundThisBranch = branch.Tip.Branches.Any(b => commit.Branches.Contains(b)); if (foundThisBranch == false) list.Add(branch); } } return list; }
/// <summary> /// Retrives the tree changes for the given commit. /// </summary> /// <returns></returns> public static LibGit2Sharp.TreeChanges GetTreeChangesForCommit(LibGit2Sharp.Repository repo, Commit commit) { // Retrieve the Tree for this commit. LibGit2Sharp.Tree thisTree = ((LibGit2Sharp.Commit) repo.Lookup(commit.ObjectId)).Tree; // Retrieve the Tree for the previous commit (parent). // TODO: What about Merge commits? LibGit2Sharp.Tree parentTree = ((LibGit2Sharp.Commit) repo.Lookup(commit.Parents.ElementAt(0).ObjectId)).Tree; // Take the diff. return repo.Diff.Compare(parentTree, thisTree); }
/// <summary> /// Increments the visual position for this commit tree. /// </summary> /// <param name="commit"></param> public static void IncrementCommitTreeVisualPositionsRecursively(Commit commit, int level = 0) { // The visual position for this commit has already been calculated or the commit does not exist. if (commit == null || commit.VisualPosition != -1) return; // We have reached a commit with multiple children, we only continue if this commit is the "left most chain". if (commit.Children.Count > 1 && level > 0) return; // Update commit's visual position. commit.VisualPosition = level; // Update commit's branches' visual positions if needed. commit.Branches.ForEach(b => { if (b.RightMostVisualPosition < level) b.RightMostVisualPosition = level; }); if (commit.IsMergeCommit()) { int i = 0; foreach (Commit parentCommit in commit.Parents) { RepoUtil.IncrementCommitTreeVisualPositionsRecursively(parentCommit, level + i); i++; } } else if (commit.Parents.Count > 0) { RepoUtil.IncrementCommitTreeVisualPositionsRecursively(commit.Parents.ElementAt(0)); } }
/// <summary> /// Creates a new commit object from the given parameters. /// </summary> /// <param name="repo"></param> /// <param name="commit"></param> /// <param name="tags"> </param> /// <returns></returns> public static Commit Create(LibGit2Sharp.Repository repo, LibGit2Sharp.Commit commit, ObservableCollection<Tag> tags) { var c = new Commit(); // Process Tags (Git tags to display next to the commit description). var commitTags = new ObservableCollection<Tag>(); foreach (var tag in tags) { if (tag.TargetSha == commit.Sha) { commitTags.Add(tag); tag.Target = c; } } // Process display tags. var displayTags = new List<string>(); if (repo.Head.Tip == commit) displayTags.Add("HEAD"); // Process ParentHashes. var parentHashes = new List<string>(); foreach (var parentCommit in commit.Parents) { parentHashes.Add(parentCommit.Sha); } // Set properties. c.AuthorEmail = commit.Author.Email; c.AuthorName = commit.Author.Name; c.Date = commit.Author.When.DateTime; c.Description = commit.Message; c.ShortDescription = commit.Message.Right(72).RemoveLineBreaks(); c.DisplayTags = displayTags; c.Branches = new List<Branch>(); c.Tags = commitTags; c.Hash = commit.Sha; c.ParentHashes = parentHashes; c.ParentCount = commit.ParentsCount; c.Parents = new List<Commit>(); c.ObjectId = commit.Id; c.VisualPosition = -1; // -1 means it's not yet calculated. c.Children = new List<Commit>(); return c; }