public BlameResult call() throws GitAPIException { checkCallable(); try (BlameGenerator gen = new BlameGenerator(repo, path)) { if (diffAlgorithm != null) gen.setDiffAlgorithm(diffAlgorithm); if (textComparator != null) gen.setTextComparator(textComparator); if (followFileRenames != null) gen.setFollowFileRenames(followFileRenames.booleanValue()); gen.reverse(startCommit, reverseEndCommits); else if (startCommit != null) gen.push(null, startCommit); else { gen.push(null, repo.resolve(Constants.HEAD)); if (!repo.isBare()) { DirCache dc = repo.readDirCache(); int entry = dc.findEntry(path); if (0 <= entry) gen.push(null, dc.getEntry(entry).getObjectId()); gen.push(null, rawText); return gen.computeBlameResult(); } catch (IOException e) { throw new JGitInternalException(e.getMessage(), e);
private boolean processOne(Candidate n) throws IOException { RevCommit parent = n.getParent(0); if (parent == null) return split(n.getNextCandidate(0), n); revPool.parseHeaders(parent); if (find(parent, n.sourcePath)) { if (idBuf.equals(n.sourceBlob)) return blameEntireRegionOnParent(n, parent); return splitBlameWithParent(n, parent); } if (n.sourceCommit == null) return result(n); DiffEntry r = findRename(parent, n.sourceCommit, n.sourcePath); if (r == null) return result(n); if (0 == r.getOldId().prefixCompare(n.sourceBlob)) { // A 100% rename without any content change can also // skip directly to the parent. n.sourceCommit = parent; n.sourcePath = PathFilter.create(r.getOldPath()); push(n); return false; } Candidate next = n.create(getRepository(), parent, PathFilter.create(r.getOldPath())); next.sourceBlob = r.getOldId().toObjectId(); next.renameScore = r.getScore(); next.loadText(reader); return split(next, n); }
/** * Compute the next available segment and return the first index. * <p> * Computes one segment and returns to the caller the first index that is * available. After return the caller can also inspect {@link #lastLength()} * to determine how many lines of the result were computed. * * @return index that is now available. -1 if no more are available. * @throws java.io.IOException * the repository cannot be read. */ public int computeNext() throws IOException { BlameGenerator gen = generator; if (gen == null) return -1; if (gen.next()) { loadFrom(gen); lastLength = gen.getRegionLength(); return gen.getResultStart(); } else { gen.close(); generator = null; return -1; } }
/** * Construct a new BlameResult for a generator. * * @param gen * the generator the result will consume records from. * @return the new result object. null if the generator cannot find the path * it starts from. * @throws java.io.IOException * the repository cannot be read. */ public static BlameResult create(BlameGenerator gen) throws IOException { String path = gen.getResultPath(); RawText contents = gen.getResultContents(); if (contents == null) { gen.close(); return null; } return new BlameResult(gen, path, contents); }
RevCommit parent = n.getParent(pIdx); revPool.parseHeaders(parent); if (!find(parent, n.sourcePath)) continue; if (!(n instanceof ReverseCandidate) && idBuf.equals(n.sourceBlob)) return blameEntireRegionOnParent(n, parent); if (ids == null) ids = new ObjectId[pCnt]; DiffEntry r = findRename(parent, n.sourceCommit, n.sourcePath); if (r == null) continue; return blameEntireRegionOnParent(n, parent); p = n.create(getRepository(), parent, PathFilter.create(renames[pIdx].getOldPath())); p.renameScore = renames[pIdx].getScore(); p.sourceBlob = renames[pIdx].getOldId().toObjectId(); } else if (ids != null && ids[pIdx] != null) { p = n.create(getRepository(), parent, n.sourcePath); p.sourceBlob = ids[pIdx]; } else { push(p); return result(resultHead); return false;
return result(outCandidate.queueNext); return done(); Candidate n = pop(); if (n == null) return done(); if (processOne(n)) return true; if (processMerge(n)) return true; return result(n);
dateFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss ZZZZ"); //$NON-NLS-1$ BlameGenerator generator = new BlameGenerator(db, file); RevFlag scanned = generator.newFlag("SCANNED"); //$NON-NLS-1$ reader = db.newObjectReader(); try { generator.setTextComparator(comparator); rangeEnd.add(c); generator.reverse(rangeStart, rangeEnd); } else if (revision != null) { generator.push(null, db.resolve(revision + "^{commit}")); //$NON-NLS-1$ } else { generator.push(null, db.resolve(Constants.HEAD)); if (!db.isBare()) { DirCache dc = db.readDirCache(); int entry = dc.findEntry(file); if (0 <= entry) generator.push(null, dc.getEntry(entry).getObjectId()); generator.push(null, new RawText(inTree)); generator.release(); reader.release();
return; if (!gen.next()) { gen.close(); generator = null; return; int resLine = gen.getResultStart(); int resEnd = gen.getResultEnd();
initRevPool(true); if (!find(result, resultPath)) return this; ReverseCandidate c = new ReverseCandidate(getRepository(), result, resultPath); c.sourceBlob = idBuf.toObjectId(); c.regionList = new Region(0, 0, c.sourceText.size()); remaining = c.sourceText.size(); push(c); return this;
private boolean split(Candidate parent, Candidate source) throws IOException { EditList editList = diffAlgorithm.diff(textComparator, parent.sourceText, source.sourceText); if (editList.isEmpty()) { // Ignoring whitespace (or some other special comparator) can // cause non-identical blobs to have an empty edit list. In // a case like this push the parent alone. parent.regionList = source.regionList; push(parent); return false; } parent.takeBlame(editList, source); if (parent.regionList != null) push(parent); if (source.regionList != null) { if (source instanceof ReverseCandidate) return reverseResult(parent, source); return result(source); } return false; }
if (description == null) description = JGitText.get().blameNotCommittedYet; BlobCandidate c = new BlobCandidate(getRepository(), description, resultPath); c.sourceBlob = id.toObjectId(); c.regionList = new Region(0, 0, c.sourceText.size()); remaining = c.sourceText.size(); push(c); return this; if (!find(commit, resultPath)) return this; Candidate c = new Candidate(getRepository(), commit, resultPath); c.sourceBlob = idBuf.toObjectId(); c.loadText(reader); c.regionList = new Region(0, 0, c.sourceText.size()); remaining = c.sourceText.size(); push(c); return this;
initRevPool(true); if (!find(result, resultPath)) return this; c.regionList = new Region(0, 0, c.sourceText.size()); remaining = c.sourceText.size(); push(c); return this;
private boolean blameEntireRegionOnParent(Candidate n, RevCommit parent) { // File was not modified, blame parent. n.sourceCommit = parent; push(n); return false; }
/** * Push a candidate blob onto the generator's traversal stack. * <p> * Candidates should be pushed in history order from oldest-to-newest. * Applications should push the starting commit first, then the index * revision (if the index is interesting), and finally the working tree copy * (if the working tree is interesting). * * @param description * description of the blob revision, such as "Working Tree". * @param contents * contents of the file. * @return {@code this} * @throws java.io.IOException * the repository cannot be read. */ public BlameGenerator push(String description, RawText contents) throws IOException { if (description == null) description = JGitText.get().blameNotCommittedYet; BlobCandidate c = new BlobCandidate(getRepository(), description, resultPath); c.sourceText = contents; c.regionList = new Region(0, 0, contents.size()); remaining = contents.size(); push(c); return this; }
private boolean done() { close(); return false; }
return reverse(start, Collections.singleton(end.toObjectId()));
RevCommit parent = n.getParent(pIdx); revPool.parseHeaders(parent); if (!find(parent, n.sourcePath)) continue; if (!(n instanceof ReverseCandidate) && idBuf.equals(n.sourceBlob)) return blameEntireRegionOnParent(n, parent); if (ids == null) ids = new ObjectId[pCnt]; DiffEntry r = findRename(parent, n.sourceCommit, n.sourcePath); if (r == null) continue; return blameEntireRegionOnParent(n, parent); p = n.create(getRepository(), parent, PathFilter.create(renames[pIdx].getOldPath())); p.renameScore = renames[pIdx].getScore(); p.sourceBlob = renames[pIdx].getOldId().toObjectId(); } else if (ids != null && ids[pIdx] != null) { p = n.create(getRepository(), parent, n.sourcePath); p.sourceBlob = ids[pIdx]; } else { push(p); return result(resultHead); return false;
return result(outCandidate.queueNext); return done(); Candidate n = pop(); if (n == null) return done(); if (processOne(n)) return true; if (processMerge(n)) return true; return result(n);