public override RevCommit next() { RevCommit c = _source.next(); if (c != null) { foreach (RevCommit p in c.Parents) { if ((p.Flags & RevWalk.UNINTERESTING) != 0) { _held.add(p); } } return(c); } var boundary = new FIFORevQueue(); boundary.shareFreeList(_held); while (true) { c = _held.next(); if (c == null) { break; } if ((c.Flags & Duplicate) != 0) { continue; } if ((c.Flags & Parsed) == 0) { c.parseHeaders(_walk); } c.Flags |= Duplicate; boundary.add(c); } boundary.removeFlag(Duplicate); _parent._generator = boundary; return(boundary.next()); }
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.TreeWalk tw = _pathFilter; var 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, 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); } // We have interesting items, but neither of the special // cases denoted above. // return(true); } 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. // var chgs_ = new int[nParents]; var adds_ = new int[nParents]; while (tw.next()) { int myMode = tw.getRawMode(nParents); for (int i = 0; i < nParents; i++) { int pMode = tw.getRawMode(i); if (myMode == pMode && tw.idEqual(i, nParents)) { continue; } chgs_[i]++; if (pMode == 0 && myMode != 0) { adds_[i]++; } } } bool same = false; bool diff = false; for (int i = 0; i < nParents; i++) { if (chgs_[i] == 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]; 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[] { p }; return(false); } if (chgs_[i] == adds_[i]) { // 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].Parents = RevCommit.NoParents; } // 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); }