/** * Remove a {@link DataNode} from the {@link FlowGraph}. The method extracts the nodeId of the * {@link DataNode} from the node config file and uses it to delete the associated {@link DataNode}. * @param change */ private void removeDataNode(DiffEntry change) { if (checkFilePath(change.getOldPath(), NODE_FILE_DEPTH)) { Path nodeFilePath = new Path(this.repositoryDir, change.getOldPath()); Config config = getNodeConfigWithOverrides(ConfigFactory.empty(), nodeFilePath); String nodeId = config.getString(FlowGraphConfigurationKeys.DATA_NODE_ID_KEY); if (!this.flowGraph.deleteDataNode(nodeId)) { log.warn("Could not remove DataNode {} from FlowGraph; skipping", nodeId); } else { log.info("Removed DataNode {} from FlowGraph", nodeId); } } }
/** * Remove a {@link FlowEdge} from the {@link FlowGraph}. The method uses {@link FlowEdgeFactory} * to construct the edgeId of the {@link FlowEdge} from the config file and uses it to delete the associated * {@link FlowEdge}. * @param change */ private void removeFlowEdge(DiffEntry change) { if (checkFilePath(change.getOldPath(), EDGE_FILE_DEPTH)) { Path edgeFilePath = new Path(this.repositoryDir, change.getOldPath()); try { Config config = getEdgeConfigWithOverrides(ConfigFactory.empty(), edgeFilePath); String edgeId = config.getString(FlowGraphConfigurationKeys.FLOW_EDGE_ID_KEY); if (!this.flowGraph.deleteFlowEdge(edgeId)) { log.warn("Could not remove edge {} from FlowGraph; skipping", edgeId); } else { log.info("Removed edge {} from FlowGraph", edgeId); } } catch (Exception e) { log.warn("Could not remove edge defined in {} due to exception {}", edgeFilePath, e.getMessage()); } } }
/** * Remove an element (i.e. either a {@link DataNode} or a {@link FlowEdge} from the {@link FlowGraph} for * a renamed or deleted {@link DataNode} or {@link FlowEdge} file. * @param change */ @Override public void removeChange(DiffEntry change) { Path path = new Path(change.getOldPath()); if (path.depth() == NODE_FILE_DEPTH) { removeDataNode(change); } else if (path.depth() == EDGE_FILE_DEPTH) { removeFlowEdge(change); } }
/** * Sort the changes in a commit so that changes to node files appear before changes to edge files. This is done so that * node related changes are applied to the FlowGraph before edge related changes. An example where the order matters * is the case when a commit adds a new node n2 as well as adds an edge from an existing node n1 to n2. To ensure that the * addition of edge n1->n2 is successful, node n2 must exist in the graph and so needs to be added first. For deletions, * the order does not matter and ordering the changes in the commit will result in the same FlowGraph state as if the changes * were unordered. In other words, deletion of a node deletes all its incident edges from the FlowGraph. So processing an * edge deletion later results in a no-op. Note that node and edge files do not change depth in case of modifications. * * If there are multiple commits between successive polls to Git, the re-ordering of changes across commits should not * affect the final state of the FlowGraph. This is because, the order of changes for a given file type (i.e. node or edge) * is preserved. */ @Override void processGitConfigChanges() throws GitAPIException, IOException { List<DiffEntry> changes = this.gitRepo.getChanges(); Collections.sort(changes, (o1, o2) -> { Integer o1Depth = (o1.getNewPath() != null) ? (new Path(o1.getNewPath())).depth() : (new Path(o1.getOldPath())).depth(); Integer o2Depth = (o2.getNewPath() != null) ? (new Path(o2.getNewPath())).depth() : (new Path(o2.getOldPath())).depth(); return o1Depth.compareTo(o2Depth); }); processGitConfigChangesHelper(changes); //Decrements the latch count. The countdown latch is initialized to 1. So after the first time the latch is decremented, // the following operation should be a no-op. this.initComplete.countDown(); }
/** * remove a {@link FlowSpec} for a deleted or renamed flow config * @param change */ @Override public void removeChange(DiffEntry change) { if (checkConfigFilePath(change.getOldPath())) { Path configFilePath = new Path(this.repositoryDir, change.getOldPath()); String flowName = FSSpecStore.getSpecName(configFilePath); String flowGroup = FSSpecStore.getSpecGroup(configFilePath); // build a dummy config to get the proper URI for delete Config dummyConfig = ConfigBuilder.create() .addPrimitive(ConfigurationKeys.FLOW_GROUP_KEY, flowGroup) .addPrimitive(ConfigurationKeys.FLOW_NAME_KEY, flowName) .build(); FlowSpec spec = FlowSpec.builder() .withConfig(dummyConfig) .withVersion(SPEC_VERSION) .withDescription(SPEC_DESCRIPTION) .build(); this.flowCatalog.remove(spec.getUri()); } }
/** * Get the path associated with this file. * * @param side * which path to obtain. * @return name for this file. */ public String getPath(Side side) { return side == Side.OLD ? getOldPath() : getNewPath(); }
private List<DiffEntry> updateFollowFilter(List<DiffEntry> files) { String oldPath = ((FollowFilter) pathFilter).getPath(); for (DiffEntry ent : files) { if (isRename(ent) && ent.getNewPath().equals(oldPath)) { pathFilter = FollowFilter.create(ent.getOldPath(), diffCfg); return Collections.singletonList(ent); } } return Collections.emptyList(); }
public static ArrayMemory valueOf(DiffEntry value) { ArrayMemory memory = new ArrayMemory(); memory.refOfIndex("oldId").assign(value.getOldId() == null ? Memory.NULL : valueOf(value.getOldId().toObjectId())); memory.refOfIndex("oldPath").assign(value.getOldPath()); memory.refOfIndex("oldMode").assign(value.getOldMode() == null ? Memory.NULL : StringMemory.valueOf(value.getOldMode().toString())); memory.refOfIndex("newId").assign(value.getNewId() == null ? Memory.NULL : valueOf(value.getNewId().toObjectId())); memory.refOfIndex("newPath").assign(value.getNewPath()); memory.refOfIndex("newMode").assign(value.getNewMode() == null ? Memory.NULL : StringMemory.valueOf(value.getNewMode().toString())); memory.refOfIndex("score").assign(value.getScore()); memory.refOfIndex("changeType").assign(value.getChangeType().name()); return memory; }
private static void listDiff(Repository repository, Git git, String oldCommit, String newCommit) throws GitAPIException, IOException { final List<DiffEntry> diffs = git.diff() .setOldTree(prepareTreeParser(repository, oldCommit)) .setNewTree(prepareTreeParser(repository, newCommit)) .call(); System.out.println("Found: " + diffs.size() + " differences"); for (DiffEntry diff : diffs) { System.out.println("Diff: " + diff.getChangeType() + ": " + (diff.getOldPath().equals(diff.getNewPath()) ? diff.getNewPath() : diff.getOldPath() + " -> " + diff.getNewPath())); } }
private static void listDiff(Repository repository, Git git, String oldCommit, String newCommit) throws GitAPIException, IOException { final List<DiffEntry> diffs = git.diff() .setOldTree(prepareTreeParser(repository, oldCommit)) .setNewTree(prepareTreeParser(repository, newCommit)) .call(); System.out.println("Found: " + diffs.size() + " differences"); for (DiffEntry diff : diffs) { System.out.println("Diff: " + diff.getChangeType() + ": " + (diff.getOldPath().equals(diff.getNewPath()) ? diff.getNewPath() : diff.getOldPath() + " -> " + diff.getNewPath())); } }
private void formatOldNewPaths(ByteArrayOutputStream o, DiffEntry ent) throws IOException { if (ent.oldId.equals(ent.newId)) return; final String oldp; final String newp; switch (ent.getChangeType()) { case ADD: oldp = DiffEntry.DEV_NULL; newp = quotePath(newPrefix + ent.getNewPath()); break; case DELETE: oldp = quotePath(oldPrefix + ent.getOldPath()); newp = DiffEntry.DEV_NULL; break; default: oldp = quotePath(oldPrefix + ent.getOldPath()); newp = quotePath(newPrefix + ent.getNewPath()); break; } o.write(encode("--- " + oldp + "\n")); //$NON-NLS-1$ //$NON-NLS-2$ o.write(encode("+++ " + newp + "\n")); //$NON-NLS-1$ //$NON-NLS-2$ }
private void formatHeader(ByteArrayOutputStream o, DiffEntry ent) throws IOException { final ChangeType type = ent.getChangeType(); final String oldp = ent.getOldPath(); final String newp = ent.getNewPath(); final FileMode oldMode = ent.getOldMode();
/** * Breaks apart a DiffEntry into two entries, one DELETE and one ADD. * * @param entry * the DiffEntry to break apart. * @return a list containing two entries. Calling {@link #getChangeType()} * on the first entry will return ChangeType.DELETE. Calling it on * the second entry will return ChangeType.ADD. */ static List<DiffEntry> breakModify(DiffEntry entry) { DiffEntry del = new DiffEntry(); del.oldId = entry.getOldId(); del.oldMode = entry.getOldMode(); del.oldPath = entry.getOldPath(); del.newId = A_ZERO; del.newMode = FileMode.MISSING; del.newPath = DiffEntry.DEV_NULL; del.changeType = ChangeType.DELETE; del.diffAttribute = entry.diffAttribute; DiffEntry add = new DiffEntry(); add.oldId = A_ZERO; add.oldMode = FileMode.MISSING; add.oldPath = DiffEntry.DEV_NULL; add.newId = entry.getNewId(); add.newMode = entry.getNewMode(); add.newPath = entry.getNewPath(); add.changeType = ChangeType.ADD; add.diffAttribute = entry.diffAttribute; return Arrays.asList(del, add); }
/** * @return the old path or <code>/dev/null</code> for a completely new file * @see #getPath() for getting the new or old path depending on change type */ public String getOldPath() { return diffEntry.getOldPath(); }
private void updateFollowFilter(ObjectId[] trees, DiffConfig cfg) throws MissingObjectException, IncorrectObjectTypeException, CorruptObjectException, IOException { TreeWalk tw = pathFilter; FollowFilter oldFilter = (FollowFilter) tw.getFilter(); tw.setFilter(TreeFilter.ANY_DIFF); tw.reset(trees); List<DiffEntry> files = DiffEntry.scan(tw); RenameDetector rd = new RenameDetector(tw.getObjectReader(), cfg); rd.addAll(files); files = rd.compute(); TreeFilter newFilter = oldFilter; for (DiffEntry ent : files) { if (isRename(ent) && ent.getNewPath().equals(oldFilter.getPath())) { newFilter = FollowFilter.create(ent.getOldPath(), cfg); RenameCallback callback = oldFilter.getRenameCallback(); if (callback != null) { callback.renamed(ent); // forward the callback to the new follow filter ((FollowFilter) newFilter).setRenameCallback(callback); } break; } } tw.setFilter(newFilter); }
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); }
@JavascriptInterface public String getOldPath(int index) { DiffEntry diff = mDiffEntries.get(index); String op = diff.getOldPath(); return op; }
n.sourcePath = PathFilter.create(r.getOldPath()); return blameEntireRegionOnParent(n, parent); if (renames != null && renames[pIdx] != null) { p = n.create(getRepository(), parent, PathFilter.create(renames[pIdx].getOldPath())); p.renameScore = renames[pIdx].getScore(); p.sourceBlob = renames[pIdx].getOldId().toObjectId();
TreeWalk tw = new TreeWalk(repository); tw.setRecursive(true); tw.addTree(CommitUtils.getHead(repository).getTree()); tw.addTree(new FileTreeIterator(repository)); RenameDetector rd = new RenameDetector(repository); rd.addAll(DiffEntry.scan(tw)); List<DiffEntry> lde = rd.compute(tw.getObjectReader(), null); for (DiffEntry de : lde) { if (de.getScore() >= rd.getRenameScore()) { System.out.println("file: " + de.getOldPath() + " copied/moved to: " + de.getNewPath()); } }
public static BlobIdent getOldBlobIdent(DiffEntry diffEntry, String oldRev) { BlobIdent blobIdent; if (diffEntry.getChangeType() != ChangeType.ADD) { blobIdent = new BlobIdent(oldRev, diffEntry.getOldPath(), diffEntry.getOldMode().getBits()); } else { blobIdent = new BlobIdent(oldRev, null, null); } return blobIdent; }