/// <exception cref="NGit.Errors.MissingObjectException"></exception> /// <exception cref="NGit.Errors.IncorrectObjectTypeException"></exception> /// <exception cref="System.IO.IOException"></exception> internal override RevCommit Next() { RevCommit c = this.source.Next(); if (c != null) { foreach (RevCommit p in c.parents) { if ((p.flags & BoundaryGenerator.UNINTERESTING) != 0) { this.held.Add(p); } } return(c); } FIFORevQueue boundary = new FIFORevQueue(); boundary.ShareFreeList(this.held); for (; ;) { c = this.held.Next(); if (c == null) { break; } if ((c.flags & BoundaryGenerator.InitialGenerator.DUPLICATE) != 0) { continue; } if ((c.flags & BoundaryGenerator.InitialGenerator.PARSED) == 0) { c.ParseHeaders(this.walk); } c.flags |= BoundaryGenerator.InitialGenerator.DUPLICATE; boundary.Add(c); } boundary.RemoveFlag(BoundaryGenerator.InitialGenerator.DUPLICATE); this._enclosing.g = boundary; return(boundary.Next()); }
/// <exception cref="NGit.Errors.StopWalkException"></exception> /// <exception cref="NGit.Errors.MissingObjectException"></exception> /// <exception cref="NGit.Errors.IncorrectObjectTypeException"></exception> /// <exception cref="System.IO.IOException"></exception> public override bool Include(RevWalk walker, RevCommit c) { // Reset the tree filter to scan this commit and parents. // RevCommit[] pList = c.parents; int nParents = pList.Length; TreeWalk tw = pathFilter; ObjectId[] trees = new ObjectId[nParents + 1]; for (int i = 0; i < nParents; i++) { RevCommit p = c.parents[i]; if ((p.flags & PARSED) == 0) { p.ParseHeaders(walker); } trees[i] = p.Tree; } trees[nParents] = c.Tree; tw.Reset(trees); if (nParents == 1) { // We have exactly one parent. This is a very common case. // int chgs = 0; int adds = 0; while (tw.Next()) { chgs++; if (tw.GetRawMode(0) == 0 && tw.GetRawMode(1) != 0) { adds++; } else { break; } } // no point in looking at this further. if (chgs == 0) { // No changes, so our tree is effectively the same as // our parent tree. We pass the buck to our parent. // c.flags |= REWRITE; return(false); } else { // We have interesting items, but neither of the special // cases denoted above. // if (adds > 0 && tw.Filter is FollowFilter) { // One of the paths we care about was added in this // commit. We need to update our filter to its older // name, if we can discover it. Find out what that is. // UpdateFollowFilter(trees); } return(true); } } else { if (nParents == 0) { // We have no parents to compare against. Consider us to be // REWRITE only if we have no paths matching our filter. // if (tw.Next()) { return(true); } c.flags |= REWRITE; return(false); } } // We are a merge commit. We can only be REWRITE if we are same // to _all_ parents. We may also be able to eliminate a parent if // it does not contribute changes to us. Such a parent may be an // uninteresting side branch. // int[] chgs_1 = new int[nParents]; int[] adds_1 = new int[nParents]; while (tw.Next()) { int myMode = tw.GetRawMode(nParents); for (int i_1 = 0; i_1 < nParents; i_1++) { int pMode = tw.GetRawMode(i_1); if (myMode == pMode && tw.IdEqual(i_1, nParents)) { continue; } chgs_1[i_1]++; if (pMode == 0 && myMode != 0) { adds_1[i_1]++; } } } bool same = false; bool diff = false; for (int i_2 = 0; i_2 < nParents; i_2++) { if (chgs_1[i_2] == 0) { // No changes, so our tree is effectively the same as // this parent tree. We pass the buck to only this one // parent commit. // RevCommit p = pList[i_2]; if ((p.flags & UNINTERESTING) != 0) { // This parent was marked as not interesting by the // application. We should look for another parent // that is interesting. // same = true; continue; } c.flags |= REWRITE; c.parents = new RevCommit[] { p }; return(false); } if (chgs_1[i_2] == adds_1[i_2]) { // All of the differences from this parent were because we // added files that they did not have. This parent is our // "empty tree root" and thus their history is not relevant. // Cut our grandparents to be an empty list. // pList[i_2].parents = RevCommit.NO_PARENTS; } // We have an interesting difference relative to this parent. // diff = true; } if (diff && !same) { // We did not abort above, so we are different in at least one // way from all of our parents. We have to take the blame for // that difference. // return(true); } // We are the same as all of our parents. We must keep them // as they are and allow those parents to flow into pending // for further scanning. // c.flags |= REWRITE; return(false); }