/// <summary> /// Compare reference commit against compared commit. You may pass in a null commit (i.e. for getting the changes of the first commit) /// </summary> /// <param name="reference">Usually the more recent commit</param> /// <param name="compared">Usually an ancestor of the reference commit</param> /// <returns>a list of changes (<see cref="Change"/>)</returns> public static IEnumerable <Change> CompareCommits(Commit reference, Commit compared) { var changes = new List <Change>(); if (reference == null && compared == null) { return(changes); } var repo = (reference ?? compared).Repository; var ref_tree = (reference != null ? reference.Tree._id : ObjectId.ZeroId); var compared_tree = (compared != null ? compared.Tree._id : ObjectId.ZeroId); var db = repo._internal_repo; var walk = new TreeWalk(db); if (reference == null || compared == null) { walk.reset((reference ?? compared).Tree._id); } else { walk.reset(new GitSharp.Core.AnyObjectId[] { ref_tree, compared_tree }); } walk.Recursive = true; walk.setFilter(AndTreeFilter.create(TreeFilter.ANY_DIFF, TreeFilter.ALL)); return(CalculateCommitDiff(repo, walk, new[] { reference, compared })); }
/// <summary> /// Compare a commit against (one or multiple) parents (merge scenario) /// </summary> /// <returns>Changes of the commit</returns> private IEnumerable <Change> CompareAgainstParents() { var db = _repo._internal_repo; var tree_ids = new[] { this }.Concat(Parents).Select(c => c.Tree._id).ToArray(); var walk = new TreeWalk(db); walk.reset(tree_ids); walk.Recursive = true; walk.setFilter(AndTreeFilter.create(TreeFilter.ANY_DIFF, TreeFilter.ALL)); return(CalculateCommitDiff(_repo, walk, new[] { this }.Concat(Parents).ToArray())); }
/// <summary> /// Compare reference commit against compared commit. You may pass in a null commit (i.e. for getting the changes of the first commit) /// </summary> /// <param name="reference"></param> /// <param name="compared"></param> /// <returns></returns> public static IEnumerable <Change> CompareCommits(Commit reference, Commit compared) { var changes = new List <Change>(); if (reference == null && compared == null) { return(changes); } var repo = (reference ?? compared).Repository; if (compared.Repository.Directory != repo.Directory) { throw new InvalidOperationException("Can not compare commits from different repositories"); } var ref_tree = (reference != null ? reference.Tree._id : ObjectId.ZeroId); var compared_tree = (compared != null ? compared.Tree._id : ObjectId.ZeroId); var db = repo._internal_repo; var pathFilter = TreeFilter.ALL; var walk = new TreeWalk(db); //new GitSharp.Core.ObjectWriter(repo).WriteTree( new CoreTree(repo)); // <--- writing an empty tree object. very ugly hack that is necessary to get an empty tree into the treewalker. if (reference == null || compared == null) { walk.reset((reference ?? compared).Tree._id); } else { walk.reset(new GitSharp.Core.AnyObjectId[] { ref_tree, compared_tree }); } //if (ref_tree == ObjectId.ZeroId) // walk.addTree(new EmptyTreeIterator()); //else // walk.addTree(ref_tree); //if (compared_tree == ObjectId.ZeroId) // walk.addTree(new EmptyTreeIterator()); //else // walk.addTree(compared_tree); walk.Recursive = true; walk.setFilter(AndTreeFilter.create(TreeFilter.ANY_DIFF, pathFilter)); while (walk.next()) { if (walk.getTreeCount() == 2) { int m0 = walk.getRawMode(0); int m1 = walk.getRawMode(1); var change = new Change() { ReferenceCommit = reference, ComparedCommit = compared, ReferencePermissions = walk.getFileMode(0).Bits, ComparedPermissions = walk.getFileMode(1).Bits, Name = walk.getNameString(), Path = walk.getPathString(), }; changes.Add(change); if (m0 == 0 && m1 != 0) { change.ChangeType = ChangeType.Added; change.ComparedObject = AbstractObject.Wrap(repo, walk.getObjectId(1)); } else if (m0 != 0 && m1 == 0) { change.ChangeType = ChangeType.Deleted; change.ReferenceObject = AbstractObject.Wrap(repo, walk.getObjectId(0)); } else if (m0 != m1 && walk.idEqual(0, 1)) { change.ChangeType = ChangeType.TypeChanged; change.ReferenceObject = AbstractObject.Wrap(repo, walk.getObjectId(0)); change.ComparedObject = AbstractObject.Wrap(repo, walk.getObjectId(1)); } else { change.ChangeType = ChangeType.Modified; change.ReferenceObject = AbstractObject.Wrap(repo, walk.getObjectId(0)); change.ComparedObject = AbstractObject.Wrap(repo, walk.getObjectId(1)); } } else { var change = new Change() { ReferenceCommit = reference, ComparedCommit = compared, Name = walk.getNameString(), Path = walk.getPathString(), }; changes.Add(change); if (reference != null) { change.ReferencePermissions = walk.getFileMode(0).Bits; change.ChangeType = ChangeType.Deleted; change.ReferenceObject = AbstractObject.Wrap(repo, walk.getObjectId(0)); } else { change.ComparedPermissions = walk.getFileMode(0).Bits; change.ChangeType = ChangeType.Added; change.ComparedObject = AbstractObject.Wrap(repo, walk.getObjectId(0)); } } } return(changes); }
protected void filter(string path) { rw.setTreeFilter(AndTreeFilter.create( PathFilterGroup.createFromStrings(new[] { path }), TreeFilter.ANY_DIFF)); }