/** * Pop the next most recent object. * * @return next most recent object; null if traversal is over. * @throws MissingObjectException one or or more of the next objects are not available from the * object database, but were thought to be candidates for traversal. This usually indicates a * broken link. * @throws IncorrectObjectTypeException one or or more of the objects in a tree do not match the * type indicated. * @throws IOException a pack file or loose object could not be read. */ public RevObject nextObject() throws MissingObjectException, IncorrectObjectTypeException, IOException { if (last != null) treeWalk = last instanceof RevTree ? enter(last) : treeWalk.next(); while (!treeWalk.eof()) { final FileMode mode = treeWalk.getEntryFileMode(); switch (mode.getObjectType()) { case Constants.OBJ_BLOB: { treeWalk.getEntryObjectId(idBuffer); final RevBlob o = lookupBlob(idBuffer); if ((o.flags & SEEN) != 0) break; o.flags |= SEEN; if (shouldSkipObject(o)) break; last = o; return o; } case Constants.OBJ_TREE: { treeWalk.getEntryObjectId(idBuffer); final RevTree o = lookupTree(idBuffer); if ((o.flags & SEEN) != 0) break; o.flags |= SEEN; if (shouldSkipObject(o)) break; last = o; return o; } default: if (FileMode.GITLINK.equals(mode)) break; treeWalk.getEntryObjectId(idBuffer); throw new CorruptObjectException( MessageFormat.format( JGitText.get().corruptObjectInvalidMode3, mode, idBuffer.name(), treeWalk.getEntryPathString(), currentTree.name())); } treeWalk = treeWalk.next(); } last = null; for (; ; ) { final RevObject o = pendingObjects.next(); if (o == null) return null; if ((o.flags & SEEN) != 0) continue; o.flags |= SEEN; if (shouldSkipObject(o)) continue; if (o instanceof RevTree) { currentTree = (RevTree) o; treeWalk = treeWalk.resetRoot(db, currentTree, curs); } return o; } }
public void testEntryFileMode() { for (FileMode m : new FileMode[] { FileMode.TREE, FileMode.REGULAR_FILE, FileMode.EXECUTABLE_FILE, FileMode.GITLINK, FileMode.SYMLINK }) { final FakeTreeIterator i = new FakeTreeIterator("a", m); assertEquals(m.getBits(), i.getEntryRawMode()); assertSame(m, i.getEntryFileMode()); } }
/** * Lookup an entry stored in a tree, failing if not present. * * @param tree the tree to search. * @param path the path to find the entry of. * @return the parsed object entry at this path, never null. * @throws Exception */ public RevObject get(final RevTree tree, final String path) throws Exception { final TreeWalk tw = new TreeWalk(pool.getObjectReader()); tw.setFilter(PathFilterGroup.createFromStrings(Collections.singleton(path))); tw.reset(tree); while (tw.next()) { if (tw.isSubtree() && !path.equals(tw.getPathString())) { tw.enterSubtree(); continue; } final ObjectId entid = tw.getObjectId(0); final FileMode entmode = tw.getFileMode(0); return pool.lookupAny(entid, entmode.getObjectType()); } fail("Can't find " + path + " in tree " + tree.name()); return null; // never reached. }
FileMode parseFileMode(int ptr, final int end) { int tmp = 0; while (ptr < end - 1) { tmp <<= 3; tmp += buf[ptr++] - '0'; } return FileMode.fromBits(tmp); }
private void markTreeUninteresting(final RevTree tree) throws MissingObjectException, IncorrectObjectTypeException, IOException { if ((tree.flags & UNINTERESTING) != 0) return; tree.flags |= UNINTERESTING; treeWalk = treeWalk.resetRoot(db, tree, curs); while (!treeWalk.eof()) { final FileMode mode = treeWalk.getEntryFileMode(); final int sType = mode.getObjectType(); switch (sType) { case Constants.OBJ_BLOB: { treeWalk.getEntryObjectId(idBuffer); lookupBlob(idBuffer).flags |= UNINTERESTING; break; } case Constants.OBJ_TREE: { treeWalk.getEntryObjectId(idBuffer); final RevTree t = lookupTree(idBuffer); if ((t.flags & UNINTERESTING) == 0) { t.flags |= UNINTERESTING; treeWalk = treeWalk.createSubtreeIterator0(db, t, curs); continue; } break; } default: if (FileMode.GITLINK.equals(mode)) break; treeWalk.getEntryObjectId(idBuffer); throw new CorruptObjectException( MessageFormat.format( JGitText.get().corruptObjectInvalidMode3, mode, idBuffer.name(), treeWalk.getEntryPathString(), tree)); } treeWalk = treeWalk.next(); } }
public FakeTreeIterator(String pathName, FileMode fileMode) { super(prefix(pathName), new WorkingTreeOptions(AutoCRLF.FALSE)); mode = fileMode.getBits(); final int s = pathName.lastIndexOf('/'); final byte[] name = Constants.encode(pathName.substring(s + 1)); ensurePathCapacity(pathOffset + name.length, pathOffset); System.arraycopy(name, 0, path, pathOffset, name.length); pathLen = pathOffset + name.length; }
private void assertEntry(FileMode type, boolean entryIgnored, String pathName) throws IOException { assertTrue("walk has entry", walk.next()); assertEquals(pathName, walk.getPathString()); assertEquals(type, walk.getFileMode(0)); WorkingTreeIterator itr = walk.getTree(0, WorkingTreeIterator.class); assertNotNull("has tree", itr); assertEquals("is ignored", entryIgnored, itr.isEntryIgnored()); if (D.equals(type)) walk.enterSubtree(); }
private void assertIteration(FileMode type, String pathName, List<Attribute> nodeAttrs) throws IOException { assertTrue("walk has entry", walk.next()); assertEquals(pathName, walk.getPathString()); assertEquals(type, walk.getFileMode(0)); DirCacheIterator itr = walk.getTree(0, DirCacheIterator.class); assertNotNull("has tree", itr); AttributesNode attributesNode = itr.getEntryAttributesNode(db.newObjectReader()); assertAttributesNode(pathName, attributesNode, nodeAttrs); if (D.equals(type)) walk.enterSubtree(); }
/** * Updates the index after a content merge has happened. If no conflict has occurred this includes * persisting the merged content to the object database. In case of conflicts this method takes * care to write the correct stages to the index. * * @param base * @param ours * @param theirs * @param result * @throws FileNotFoundException * @throws IOException */ private void updateIndex( CanonicalTreeParser base, CanonicalTreeParser ours, CanonicalTreeParser theirs, MergeResult<RawText> result) throws FileNotFoundException, IOException { File mergedFile = !inCore ? writeMergedFile(result) : null; if (result.containsConflicts()) { // A conflict occurred, the file will contain conflict markers // the index will be populated with the three stages and the // workdir (if used) contains the halfway merged content. add(tw.getRawPath(), base, DirCacheEntry.STAGE_1, 0, 0); add(tw.getRawPath(), ours, DirCacheEntry.STAGE_2, 0, 0); add(tw.getRawPath(), theirs, DirCacheEntry.STAGE_3, 0, 0); mergeResults.put(tw.getPathString(), result); return; } // No conflict occurred, the file will contain fully merged content. // The index will be populated with the new merged version. DirCacheEntry dce = new DirCacheEntry(tw.getPathString()); // Set the mode for the new content. Fall back to REGULAR_FILE if // we can't merge modes of OURS and THEIRS. int newMode = mergeFileModes(tw.getRawMode(0), tw.getRawMode(1), tw.getRawMode(2)); dce.setFileMode( newMode == FileMode.MISSING.getBits() ? FileMode.REGULAR_FILE : FileMode.fromBits(newMode)); if (mergedFile != null) { long len = mergedFile.length(); dce.setLastModified(mergedFile.lastModified()); dce.setLength((int) len); InputStream is = new FileInputStream(mergedFile); try { dce.setObjectId(getObjectInserter().insert(OBJ_BLOB, len, is)); } finally { is.close(); } } else dce.setObjectId(insertMergeResult(result)); builder.add(dce); }
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(); final FileMode newMode = ent.getNewMode(); formatGitDiffFirstHeaderLine(o, type, oldp, newp); switch (type) { case ADD: o.write(encodeASCII("new file mode ")); // $NON-NLS-1$ newMode.copyTo(o); o.write('\n'); break; case DELETE: o.write(encodeASCII("deleted file mode ")); // $NON-NLS-1$ oldMode.copyTo(o); o.write('\n'); break; case RENAME: o.write( encodeASCII("similarity index " + ent.getScore() + "%")); // $NON-NLS-1$ //$NON-NLS-2$ o.write('\n'); o.write(encode("rename from " + quotePath(oldp))); // $NON-NLS-1$ o.write('\n'); o.write(encode("rename to " + quotePath(newp))); // $NON-NLS-1$ o.write('\n'); break; case COPY: o.write( encodeASCII("similarity index " + ent.getScore() + "%")); // $NON-NLS-1$ //$NON-NLS-2$ o.write('\n'); o.write(encode("copy from " + quotePath(oldp))); // $NON-NLS-1$ o.write('\n'); o.write(encode("copy to " + quotePath(newp))); // $NON-NLS-1$ o.write('\n'); if (!oldMode.equals(newMode)) { o.write(encodeASCII("new file mode ")); // $NON-NLS-1$ newMode.copyTo(o); o.write('\n'); } break; case MODIFY: if (0 < ent.getScore()) { o.write( encodeASCII( "dissimilarity index " //$NON-NLS-1$ + (100 - ent.getScore()) + "%")); //$NON-NLS-1$ o.write('\n'); } break; } if ((type == MODIFY || type == RENAME) && !oldMode.equals(newMode)) { o.write(encodeASCII("old mode ")); // $NON-NLS-1$ oldMode.copyTo(o); o.write('\n'); o.write(encodeASCII("new mode ")); // $NON-NLS-1$ newMode.copyTo(o); o.write('\n'); } if (!ent.getOldId().equals(ent.getNewId())) { formatIndexLine(o, ent); } }
/** * Obtain the {@link FileMode} for the current entry. * * <p>Every added tree supplies a mode, even if the tree does not contain the current entry. In * the latter case {@link FileMode#MISSING} is returned. * * @param nth tree to obtain the mode from. * @return mode for the current entry of the nth tree. */ public FileMode getFileMode(final int nth) { return FileMode.fromBits(getRawMode(nth)); }
/** * Compares whether two pairs of ObjectId and FileMode are equal. * * @param id1 * @param mode1 * @param id2 * @param mode2 * @return <code>true</code> if FileModes and ObjectIds are equal. <code>false</code> otherwise */ private boolean equalIdAndMode(ObjectId id1, FileMode mode1, ObjectId id2, FileMode mode2) { if (!mode1.equals(mode2)) return false; return id1 != null ? id1.equals(id2) : id2 == null; }
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { handleAuth(req); resp.setCharacterEncoding("UTF-8"); final PrintWriter out = resp.getWriter(); try { String pathInfo = req.getPathInfo(); Pattern pattern = Pattern.compile("/([^/]*)(?:/([^/]*)(?:/(.*))?)?"); Matcher matcher = pattern.matcher(pathInfo); matcher.matches(); String projectName = null; String refName = null; String filePath = null; if (matcher.groupCount() > 0) { projectName = matcher.group(1); refName = matcher.group(2); filePath = matcher.group(3); if (projectName == null || projectName.equals("")) { projectName = null; } else { projectName = java.net.URLDecoder.decode(projectName, "UTF-8"); } if (refName == null || refName.equals("")) { refName = null; } else { refName = java.net.URLDecoder.decode(refName, "UTF-8"); } if (filePath == null || filePath.equals("")) { filePath = null; } else { filePath = java.net.URLDecoder.decode(filePath, "UTF-8"); } } if (projectName != null) { if (filePath == null) filePath = ""; NameKey projName = NameKey.parse(projectName); ProjectControl control; try { control = projControlFactory.controlFor(projName); if (!control.isVisible()) { log.debug("Project not visible!"); resp.sendError( HttpServletResponse.SC_UNAUTHORIZED, "You need to be logged in to see private projects"); return; } } catch (NoSuchProjectException e1) { } Repository repo = repoManager.openRepository(projName); if (refName == null) { JSONArray contents = new JSONArray(); List<Ref> call; try { call = new Git(repo).branchList().call(); Git git = new Git(repo); for (Ref ref : call) { JSONObject jsonObject = new JSONObject(); try { jsonObject.put("name", ref.getName()); jsonObject.put("type", "ref"); jsonObject.put("size", "0"); jsonObject.put("path", ""); jsonObject.put("project", projectName); jsonObject.put("ref", ref.getName()); lastCommit(git, null, ref.getObjectId(), jsonObject); } catch (JSONException e) { } contents.put(jsonObject); } String response = contents.toString(); resp.setContentType("application/json"); resp.setHeader("Cache-Control", "no-cache"); resp.setHeader("ETag", "W/\"" + response.length() + "-" + response.hashCode() + "\""); log.debug(response); out.write(response); } catch (GitAPIException e) { } } else { Ref head = repo.getRef(refName); if (head == null) { JSONArray contents = new JSONArray(); String response = contents.toString(); resp.setContentType("application/json"); resp.setHeader("Cache-Control", "no-cache"); resp.setHeader("ETag", "W/\"" + response.length() + "-" + response.hashCode() + "\""); log.debug(response); out.write(response); return; } RevWalk walk = new RevWalk(repo); // add try catch to catch failures Git git = new Git(repo); RevCommit commit = walk.parseCommit(head.getObjectId()); RevTree tree = commit.getTree(); TreeWalk treeWalk = new TreeWalk(repo); treeWalk.addTree(tree); treeWalk.setRecursive(false); if (!filePath.equals("")) { PathFilter pathFilter = PathFilter.create(filePath); treeWalk.setFilter(pathFilter); } if (!treeWalk.next()) { CanonicalTreeParser canonicalTreeParser = treeWalk.getTree(0, CanonicalTreeParser.class); JSONArray contents = new JSONArray(); if (canonicalTreeParser != null) { while (!canonicalTreeParser.eof()) { String path = canonicalTreeParser.getEntryPathString(); FileMode mode = canonicalTreeParser.getEntryFileMode(); listEntry( path, mode.equals(FileMode.TREE) ? "dir" : "file", "0", path, projectName, head.getName(), git, contents); canonicalTreeParser.next(); } } String response = contents.toString(); resp.setContentType("application/json"); resp.setHeader("Cache-Control", "no-cache"); resp.setHeader("ETag", "\"" + tree.getId().getName() + "\""); log.debug(response); out.write(response); } else { // if (treeWalk.isSubtree()) { // treeWalk.enterSubtree(); // } JSONArray contents = getListEntries(treeWalk, repo, git, head, filePath, projectName); String response = contents.toString(); resp.setContentType("application/json"); resp.setHeader("Cache-Control", "no-cache"); resp.setHeader("ETag", "\"" + tree.getId().getName() + "\""); log.debug(response); out.write(response); } walk.release(); treeWalk.release(); } } } catch (RepositoryNotFoundException e) { handleException(resp, e, 400); } catch (MissingObjectException e) { // example "Missing unknown 7035305927ca125757ecd8407e608f6dcf0bd8a5" // usually indicative of being unable to locate a commit from a submodule log.error(e.getMessage(), e); String msg = e.getMessage() + ". This exception could have been caused by the use of a git submodule, " + "which is currently not supported by the repository browser."; handleException(resp, new Exception(msg), 501); } catch (IOException e) { handleException(resp, e, 500); } finally { out.close(); } }