@Test public void testAddUnstagedChanges() throws IOException, NoHeadException, NoMessageException, ConcurrentRefUpdateException, JGitInternalException, WrongRepositoryStateException, NoFilepatternException { File file = new File(db.getWorkTree(), "a.txt"); FileUtils.createNewFile(file); PrintWriter writer = new PrintWriter(file); writer.print("content"); writer.close(); Git git = new Git(db); git.add().addFilepattern("a.txt").call(); RevCommit commit = git.commit().setMessage("initial commit").call(); TreeWalk tw = TreeWalk.forPath(db, "a.txt", commit.getTree()); assertEquals("6b584e8ece562ebffc15d38808cd6b98fc3d97ea", tw.getObjectId(0).getName()); writer = new PrintWriter(file); writer.print("content2"); writer.close(); commit = git.commit().setMessage("second commit").call(); tw = TreeWalk.forPath(db, "a.txt", commit.getTree()); assertEquals("6b584e8ece562ebffc15d38808cd6b98fc3d97ea", tw.getObjectId(0).getName()); commit = git.commit().setAll(true).setMessage("third commit").setAll(true).call(); tw = TreeWalk.forPath(db, "a.txt", commit.getTree()); assertEquals("db00fd65b218578127ea51f3dffac701f12f486a", tw.getObjectId(0).getName()); }
@Nullable private static MarkdownFile findFile(RevWalk rw, RevTree root, String path) throws IOException { if (Strings.isNullOrEmpty(path)) { path = INDEX_MD; } ObjectReader reader = rw.getObjectReader(); try (TreeWalk tw = TreeWalk.forPath(reader, path, root)) { if (tw == null) { return null; } if ((tw.getRawMode(0) & TYPE_MASK) == TYPE_TREE) { if (findIndexFile(tw)) { path = tw.getPathString(); } else { return null; } } if ((tw.getRawMode(0) & TYPE_MASK) == TYPE_FILE) { if (!path.endsWith(".md")) { return null; } return new MarkdownFile(path, tw.getObjectId(0)); } return null; } }
private boolean find(RevCommit commit, PathFilter path) throws IOException { treeWalk.setFilter(path); treeWalk.reset(commit.getTree()); if (treeWalk.next() && isFile(treeWalk.getRawMode(0))) { treeWalk.getObjectId(idBuf, 0); return true; } return false; }
private String getRepositoryContent(Repository repository, RevCommit revCommit, String fileName) throws IOException { TreeWalk treewalk = TreeWalk.forPath(repository, fileName, revCommit.getTree()); if (treewalk != null) { return new String(repository.open(treewalk.getObjectId(0)).getBytes()); } else { return null; } }
private static byte[] read(Repository db, AnyObjectId treeish, String path) throws MissingObjectException, IncorrectObjectTypeException, IOException { try (ObjectReader or = db.newObjectReader()) { TreeWalk tree = TreeWalk.forPath(or, path, asTree(or, treeish)); if (tree == null) throw new FileNotFoundException( MessageFormat.format(JGitText.get().entryNotFoundByPath, path)); return read(or, tree.getObjectId(0)); } }
protected ObjectId getObjectId(String fileName) throws IOException { if (revision == null) { return null; } TreeWalk tw = TreeWalk.forPath(reader, fileName, revision.getTree()); if (tw != null) { return tw.getObjectId(0); } return null; }
protected byte[] readFile(String fileName) throws IOException { if (revision == null) { return new byte[] {}; } TreeWalk tw = TreeWalk.forPath(reader, fileName, revision.getTree()); if (tw != null) { ObjectLoader obj = reader.open(tw.getObjectId(0), Constants.OBJ_BLOB); return obj.getCachedBytes(Integer.MAX_VALUE); } else { return new byte[] {}; } }
/** * 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. }
@Override public byte[] getData(String commitName, String filePath) { try { RevCommit revCommit = revWalk.parseCommit(ObjectId.fromString(commitName)); RevTree tree = revCommit.getTree(); TreeWalk treeWalk = TreeWalk.forPath(reader, filePath, tree); if (treeWalk == null) return null; else return reader.open(treeWalk.getObjectId(0)).getBytes(); } catch (IOException e) { throw new VisMinerAPIException(e.getMessage(), e); } }
/** * Returns a path model of the current file in the treewalk. * * @param tw * @param basePath * @param commit * @return a path model of the current file in the treewalk */ private static PathModel getPathModel(TreeWalk tw, String basePath, RevCommit commit) { String name; long size = 0; if (basePath == null) { name = tw.getPathString(); } else { name = tw.getPathString().substring(basePath.length() + 1); } try { if (!tw.isSubtree()) { size = tw.getObjectReader().getObjectSize(tw.getObjectId(0), Constants.OBJ_BLOB); } } catch (Throwable t) { // error(t, null, "failed to retrieve blob size for " + tw.getPathString()); Logger.error(t, t.getMessage()); } return new PathModel( name, tw.getPathString(), size, tw.getFileMode(0).getBits(), commit.getName()); }
public static JSONArray getListEntries( TreeWalk treeWalk, Repository repo, Git git, Ref head, String filePath, String projectName) throws MissingObjectException, IncorrectObjectTypeException, CorruptObjectException, IOException { JSONArray contents = new JSONArray(); do { if (treeWalk.isSubtree()) { String test = new String(treeWalk.getRawPath()); if (test.length() /*treeWalk.getPathLength()*/ > filePath.length()) { listEntry( treeWalk.getNameString(), "dir", "0", treeWalk.getPathString(), projectName, head.getName(), git, contents); } if (test.length() /*treeWalk.getPathLength()*/ <= filePath.length()) { treeWalk.enterSubtree(); } } else { ObjectId objId = treeWalk.getObjectId(0); ObjectLoader loader = repo.open(objId); long size = loader.getSize(); listEntry( treeWalk.getNameString(), "file", Long.toString(size), treeWalk.getPathString(), projectName, head.getName(), git, contents); } } while (treeWalk.next()); return contents; }
private void buildMaps( Repository repository, RevCommit baseCommit, RevCommit compareCommit, IProgressMonitor monitor) throws InterruptedException, IOException { monitor.beginTask(UIText.CompareTreeView_AnalyzingRepositoryTaskText, IProgressMonitor.UNKNOWN); boolean useIndex = compareVersion.equals(INDEX_VERSION); deletedPaths.clear(); equalContentPaths.clear(); baseVersionMap.clear(); compareVersionMap.clear(); compareVersionPathsWithChildren.clear(); addedPaths.clear(); baseVersionPathsWithChildren.clear(); boolean checkIgnored = false; TreeWalk tw = new TreeWalk(repository); try { int baseTreeIndex; if (baseCommit == null) { checkIgnored = true; baseTreeIndex = tw.addTree( new AdaptableFileTreeIterator( repository, ResourcesPlugin.getWorkspace().getRoot())); } else baseTreeIndex = tw.addTree( new CanonicalTreeParser(null, repository.newObjectReader(), baseCommit.getTree())); int compareTreeIndex; if (!useIndex) compareTreeIndex = tw.addTree( new CanonicalTreeParser( null, repository.newObjectReader(), compareCommit.getTree())); else compareTreeIndex = tw.addTree(new DirCacheIterator(repository.readDirCache())); if (input instanceof IResource[]) { IResource[] resources = (IResource[]) input; List<TreeFilter> orFilters = new ArrayList<TreeFilter>(resources.length); for (IResource resource : resources) { String relPath = repositoryMapping.getRepoRelativePath(resource); if (relPath.length() > 0) orFilters.add(PathFilter.create(relPath)); } if (orFilters.size() > 1) tw.setFilter(OrTreeFilter.create(orFilters)); else if (orFilters.size() == 1) tw.setFilter(orFilters.get(0)); } tw.setRecursive(true); if (monitor.isCanceled()) throw new InterruptedException(); while (tw.next()) { if (monitor.isCanceled()) throw new InterruptedException(); AbstractTreeIterator compareVersionIterator = tw.getTree(compareTreeIndex, AbstractTreeIterator.class); AbstractTreeIterator baseVersionIterator = tw.getTree(baseTreeIndex, AbstractTreeIterator.class); if (checkIgnored && baseVersionIterator != null && ((WorkingTreeIterator) baseVersionIterator).isEntryIgnored()) continue; if (compareVersionIterator != null && baseVersionIterator != null) { monitor.setTaskName(baseVersionIterator.getEntryPathString()); IPath currentPath = new Path(baseVersionIterator.getEntryPathString()); if (!useIndex) compareVersionMap.put( currentPath, GitFileRevision.inCommit( repository, compareCommit, baseVersionIterator.getEntryPathString(), tw.getObjectId(compareTreeIndex))); else compareVersionMap.put( currentPath, GitFileRevision.inIndex(repository, baseVersionIterator.getEntryPathString())); if (baseCommit != null) baseVersionMap.put( currentPath, GitFileRevision.inCommit( repository, baseCommit, baseVersionIterator.getEntryPathString(), tw.getObjectId(baseTreeIndex))); boolean equalContent = compareVersionIterator .getEntryObjectId() .equals(baseVersionIterator.getEntryObjectId()); if (equalContent) equalContentPaths.add(currentPath); if (equalContent && !showEquals) continue; while (currentPath.segmentCount() > 0) { currentPath = currentPath.removeLastSegments(1); if (!baseVersionPathsWithChildren.add(currentPath)) break; } } else if (baseVersionIterator != null && compareVersionIterator == null) { monitor.setTaskName(baseVersionIterator.getEntryPathString()); // only on base side IPath currentPath = new Path(baseVersionIterator.getEntryPathString()); addedPaths.add(currentPath); if (baseCommit != null) baseVersionMap.put( currentPath, GitFileRevision.inCommit( repository, baseCommit, baseVersionIterator.getEntryPathString(), tw.getObjectId(baseTreeIndex))); while (currentPath.segmentCount() > 0) { currentPath = currentPath.removeLastSegments(1); if (!baseVersionPathsWithChildren.add(currentPath)) break; } } else if (compareVersionIterator != null && baseVersionIterator == null) { monitor.setTaskName(compareVersionIterator.getEntryPathString()); // only on compare side IPath currentPath = new Path(compareVersionIterator.getEntryPathString()); deletedPaths.add(currentPath); List<PathNodeAdapter> children = compareVersionPathsWithChildren.get(currentPath.removeLastSegments(1)); if (children == null) { children = new ArrayList<PathNodeAdapter>(1); compareVersionPathsWithChildren.put(currentPath.removeLastSegments(1), children); } children.add(new PathNodeAdapter(new PathNode(currentPath, Type.FILE_DELETED))); if (!useIndex) compareVersionMap.put( currentPath, GitFileRevision.inCommit( repository, compareCommit, compareVersionIterator.getEntryPathString(), tw.getObjectId(compareTreeIndex))); else compareVersionMap.put( currentPath, GitFileRevision.inIndex(repository, compareVersionIterator.getEntryPathString())); } } } finally { tw.release(); monitor.done(); } }
public HistoryPanel( String wicketId, final String repositoryName, final String objectId, final String path, Repository r, int limit, int pageOffset, boolean showRemoteRefs) { super(wicketId); boolean pageResults = limit <= 0; int itemsPerPage = GitBlit.getInteger(Keys.web.itemsPerPage, 50); if (itemsPerPage <= 1) { itemsPerPage = 50; } RevCommit commit = JGitUtils.getCommit(r, objectId); List<PathChangeModel> paths = JGitUtils.getFilesInCommit(r, commit); Map<String, SubmoduleModel> submodules = new HashMap<String, SubmoduleModel>(); for (SubmoduleModel model : JGitUtils.getSubmodules(r, commit.getTree())) { submodules.put(model.path, model); } PathModel matchingPath = null; for (PathModel p : paths) { if (p.path.equals(path)) { matchingPath = p; break; } } if (matchingPath == null) { // path not in commit // manually locate path in tree TreeWalk tw = new TreeWalk(r); tw.reset(); tw.setRecursive(true); try { tw.addTree(commit.getTree()); tw.setFilter(PathFilterGroup.createFromStrings(Collections.singleton(path))); while (tw.next()) { if (tw.getPathString().equals(path)) { matchingPath = new PathChangeModel( tw.getPathString(), tw.getPathString(), 0, tw.getRawMode(0), tw.getObjectId(0).getName(), commit.getId().getName(), ChangeType.MODIFY); } } } catch (Exception e) { } finally { tw.release(); } } final boolean isTree = matchingPath == null ? true : matchingPath.isTree(); final boolean isSubmodule = matchingPath == null ? true : matchingPath.isSubmodule(); // submodule SubmoduleModel submodule = getSubmodule(submodules, repositoryName, matchingPath.path); final String submodulePath; final boolean hasSubmodule; if (submodule != null) { submodulePath = submodule.gitblitPath; hasSubmodule = submodule.hasSubmodule; } else { submodulePath = ""; hasSubmodule = false; } final Map<ObjectId, List<RefModel>> allRefs = JGitUtils.getAllRefs(r, showRemoteRefs); List<RevCommit> commits; if (pageResults) { // Paging result set commits = JGitUtils.getRevLog(r, objectId, path, pageOffset * itemsPerPage, itemsPerPage); } else { // Fixed size result set commits = JGitUtils.getRevLog(r, objectId, path, 0, limit); } // inaccurate way to determine if there are more commits. // works unless commits.size() represents the exact end. hasMore = commits.size() >= itemsPerPage; add(new CommitHeaderPanel("commitHeader", repositoryName, commit)); // breadcrumbs add(new PathBreadcrumbsPanel("breadcrumbs", repositoryName, path, objectId)); final int hashLen = GitBlit.getInteger(Keys.web.shortCommitIdLength, 6); ListDataProvider<RevCommit> dp = new ListDataProvider<RevCommit>(commits); DataView<RevCommit> logView = new DataView<RevCommit>("commit", dp) { private static final long serialVersionUID = 1L; int counter; public void populateItem(final Item<RevCommit> item) { final RevCommit entry = item.getModelObject(); final Date date = JGitUtils.getCommitDate(entry); item.add( WicketUtils.createDateLabel("commitDate", date, getTimeZone(), getTimeUtils())); // author search link String author = entry.getAuthorIdent().getName(); LinkPanel authorLink = new LinkPanel( "commitAuthor", "list", author, GitSearchPage.class, WicketUtils.newSearchParameter( repositoryName, objectId, author, Constants.SearchType.AUTHOR)); setPersonSearchTooltip(authorLink, author, Constants.SearchType.AUTHOR); item.add(authorLink); // merge icon if (entry.getParentCount() > 1) { item.add(WicketUtils.newImage("commitIcon", "commit_merge_16x16.png")); } else { item.add(WicketUtils.newBlankImage("commitIcon")); } String shortMessage = entry.getShortMessage(); String trimmedMessage = shortMessage; if (allRefs.containsKey(entry.getId())) { trimmedMessage = StringUtils.trimString(shortMessage, Constants.LEN_SHORTLOG_REFS); } else { trimmedMessage = StringUtils.trimString(shortMessage, Constants.LEN_SHORTLOG); } LinkPanel shortlog = new LinkPanel( "commitShortMessage", "list subject", trimmedMessage, CommitPage.class, WicketUtils.newObjectParameter(repositoryName, entry.getName())); if (!shortMessage.equals(trimmedMessage)) { WicketUtils.setHtmlTooltip(shortlog, shortMessage); } item.add(shortlog); item.add(new RefsPanel("commitRefs", repositoryName, entry, allRefs)); if (isTree) { // tree item.add(new Label("hashLabel", getString("gb.tree") + "@")); LinkPanel commitHash = new LinkPanel( "hashLink", null, entry.getName().substring(0, hashLen), TreePage.class, WicketUtils.newObjectParameter(repositoryName, entry.getName())); WicketUtils.setCssClass(commitHash, "shortsha1"); WicketUtils.setHtmlTooltip(commitHash, entry.getName()); item.add(commitHash); Fragment links = new Fragment("historyLinks", "treeLinks", this); links.add( new BookmarkablePageLink<Void>( "commitdiff", CommitDiffPage.class, WicketUtils.newObjectParameter(repositoryName, entry.getName()))); item.add(links); } else if (isSubmodule) { // submodule item.add(new Label("hashLabel", submodulePath + "@")); Repository repository = GitBlit.self().getRepository(repositoryName); String submoduleId = JGitUtils.getSubmoduleCommitId(repository, path, entry); repository.close(); LinkPanel commitHash = new LinkPanel( "hashLink", null, submoduleId.substring(0, hashLen), TreePage.class, WicketUtils.newObjectParameter(submodulePath, submoduleId)); WicketUtils.setCssClass(commitHash, "shortsha1"); WicketUtils.setHtmlTooltip(commitHash, submoduleId); item.add(commitHash.setEnabled(hasSubmodule)); Fragment links = new Fragment("historyLinks", "treeLinks", this); links.add( new BookmarkablePageLink<Void>( "commitdiff", CommitDiffPage.class, WicketUtils.newObjectParameter(repositoryName, entry.getName()))); item.add(links); } else { // commit item.add(new Label("hashLabel", getString("gb.blob") + "@")); LinkPanel commitHash = new LinkPanel( "hashLink", null, entry.getName().substring(0, hashLen), BlobPage.class, WicketUtils.newPathParameter(repositoryName, entry.getName(), path)); WicketUtils.setCssClass(commitHash, "sha1"); WicketUtils.setHtmlTooltip(commitHash, entry.getName()); item.add(commitHash); Fragment links = new Fragment("historyLinks", "blobLinks", this); links.add( new BookmarkablePageLink<Void>( "commitdiff", CommitDiffPage.class, WicketUtils.newObjectParameter(repositoryName, entry.getName()))); links.add( new BookmarkablePageLink<Void>( "difftocurrent", BlobDiffPage.class, WicketUtils.newBlobDiffParameter( repositoryName, entry.getName(), objectId, path)) .setEnabled(counter > 0)); item.add(links); } WicketUtils.setAlternatingBackground(item, counter); counter++; } }; add(logView); // determine to show pager, more, or neither if (limit <= 0) { // no display limit add(new Label("moreHistory", "").setVisible(false)); } else { if (pageResults) { // paging add(new Label("moreHistory", "").setVisible(false)); } else { // more if (commits.size() == limit) { // show more add( new LinkPanel( "moreHistory", "link", new StringResourceModel("gb.moreHistory", this, null), HistoryPage.class, WicketUtils.newPathParameter(repositoryName, objectId, path))); } else { // no more add(new Label("moreHistory", "").setVisible(false)); } } } }
protected PathInfo(TreeWalk tw) { fileMode = tw.getFileMode(0); path = tw.getPathString(); objectId = tw.getObjectId(0); }
@Override public List<CommitInfo> history( String objectId, String path, int limit, int pageOffset, boolean showRemoteRefs, int itemsPerPage) { try { if (itemsPerPage <= 1) { itemsPerPage = 50; } boolean pageResults = limit <= 0; Repository r = git.getRepository(); // TODO not sure if this is the right String we should use for the sub module stuff... String repositoryName = getConfigDirectory().getPath(); objectId = defaultObjectId(objectId); RevCommit commit = JGitUtils.getCommit(r, objectId); List<PathModel.PathChangeModel> paths = JGitUtils.getFilesInCommit(r, commit); Map<String, SubmoduleModel> submodules = new HashMap<String, SubmoduleModel>(); for (SubmoduleModel model : JGitUtils.getSubmodules(r, commit.getTree())) { submodules.put(model.path, model); } PathModel matchingPath = null; for (PathModel p : paths) { if (p.path.equals(path)) { matchingPath = p; break; } } if (matchingPath == null) { // path not in commit // manually locate path in tree TreeWalk tw = new TreeWalk(r); tw.reset(); tw.setRecursive(true); try { tw.addTree(commit.getTree()); tw.setFilter(PathFilterGroup.createFromStrings(Collections.singleton(path))); while (tw.next()) { if (tw.getPathString().equals(path)) { matchingPath = new PathModel.PathChangeModel( tw.getPathString(), tw.getPathString(), 0, tw.getRawMode(0), tw.getObjectId(0).getName(), commit.getId().getName(), ChangeType.MODIFY); } } } catch (Exception e) { } finally { tw.release(); } } final boolean isTree = matchingPath == null ? true : matchingPath.isTree(); final boolean isSubmodule = matchingPath == null ? true : matchingPath.isSubmodule(); // submodule SubmoduleModel submodule = null; if (matchingPath != null) { submodule = getSubmodule(submodules, repositoryName, matchingPath.path); } final String submodulePath; final boolean hasSubmodule; if (submodule != null) { submodulePath = submodule.gitblitPath; hasSubmodule = submodule.hasSubmodule; } else { submodulePath = ""; hasSubmodule = false; } final Map<ObjectId, List<RefModel>> allRefs = JGitUtils.getAllRefs(r, showRemoteRefs); List<RevCommit> commits; if (pageResults) { // Paging result set commits = JGitUtils.getRevLog(r, objectId, path, pageOffset * itemsPerPage, itemsPerPage); } else { // Fixed size result set commits = JGitUtils.getRevLog(r, objectId, path, 0, limit); } // inaccurate way to determine if there are more commits. // works unless commits.size() represents the exact end. boolean hasMore = commits.size() >= itemsPerPage; List<CommitInfo> results = new ArrayList<CommitInfo>(); for (RevCommit entry : commits) { final Date date = JGitUtils.getCommitDate(entry); String author = entry.getAuthorIdent().getName(); boolean merge = entry.getParentCount() > 1; String shortMessage = entry.getShortMessage(); String trimmedMessage = shortMessage; if (allRefs.containsKey(entry.getId())) { trimmedMessage = StringUtils.trimString(shortMessage, Constants.LEN_SHORTLOG_REFS); } else { trimmedMessage = StringUtils.trimString(shortMessage, Constants.LEN_SHORTLOG); } String name = entry.getName(); String commitHashText = getShortCommitHash(name); String kind; if (isTree) { kind = "tree"; } else if (isSubmodule) { kind = "submodule"; } else kind = "file"; results.add( new CommitInfo( commitHashText, name, kind, author, date, merge, trimmedMessage, shortMessage)); } return results; } catch (Exception e) { throw new RuntimeIOException(e); } }
@Override protected void doGet(final HttpServletRequest req, final HttpServletResponse rsp) throws IOException { String keyStr = req.getPathInfo(); // We shouldn't have to do this extra decode pass, but somehow we // are now receiving our "^1" suffix as "%5E1", which confuses us // downstream. Other times we get our embedded "," as "%2C", which // is equally bad. And yet when these happen a "%2F" is left as-is, // rather than escaped as "%252F", which makes me feel really really // uncomfortable with a blind decode right here. // keyStr = URLDecoder.decode(keyStr, "UTF-8"); if (!keyStr.startsWith("/")) { rsp.sendError(HttpServletResponse.SC_NOT_FOUND); return; } keyStr = keyStr.substring(1); final Patch.Key patchKey; final int side; { final int c = keyStr.lastIndexOf('^'); if (c == 0) { rsp.sendError(HttpServletResponse.SC_NOT_FOUND); return; } if (c < 0) { side = 0; } else { try { side = Integer.parseInt(keyStr.substring(c + 1)); keyStr = keyStr.substring(0, c); } catch (NumberFormatException e) { rsp.sendError(HttpServletResponse.SC_NOT_FOUND); return; } } try { patchKey = Patch.Key.parse(keyStr); } catch (NumberFormatException e) { rsp.sendError(HttpServletResponse.SC_NOT_FOUND); return; } } final Change.Id changeId = patchKey.getParentKey().getParentKey(); final Project project; final PatchSet patchSet; try { final ReviewDb db = requestDb.get(); final ChangeControl control = changeControl.validateFor(changeId); project = control.getProject(); patchSet = db.patchSets().get(patchKey.getParentKey()); if (patchSet == null) { rsp.sendError(HttpServletResponse.SC_NOT_FOUND); return; } } catch (NoSuchChangeException e) { rsp.sendError(HttpServletResponse.SC_NOT_FOUND); return; } catch (OrmException e) { getServletContext().log("Cannot query database", e); rsp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); return; } final Repository repo; try { repo = repoManager.openRepository(project.getNameKey()); } catch (RepositoryNotFoundException e) { getServletContext().log("Cannot open repository", e); rsp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); return; } final ObjectLoader blobLoader; final RevCommit fromCommit; final String suffix; final String path = patchKey.getFileName(); try { final ObjectReader reader = repo.newObjectReader(); try { final RevWalk rw = new RevWalk(reader); final RevCommit c; final TreeWalk tw; c = rw.parseCommit(ObjectId.fromString(patchSet.getRevision().get())); if (side == 0) { fromCommit = c; suffix = "new"; } else if (1 <= side && side - 1 < c.getParentCount()) { fromCommit = rw.parseCommit(c.getParent(side - 1)); if (c.getParentCount() == 1) { suffix = "old"; } else { suffix = "old" + side; } } else { rsp.sendError(HttpServletResponse.SC_NOT_FOUND); return; } tw = TreeWalk.forPath(reader, path, fromCommit.getTree()); if (tw == null) { rsp.sendError(HttpServletResponse.SC_NOT_FOUND); return; } if (tw.getFileMode(0).getObjectType() == Constants.OBJ_BLOB) { blobLoader = reader.open(tw.getObjectId(0), Constants.OBJ_BLOB); } else { rsp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); return; } } finally { reader.release(); } } catch (IOException e) { getServletContext().log("Cannot read repository", e); rsp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); return; } catch (RuntimeException e) { getServletContext().log("Cannot read repository", e); rsp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); return; } finally { repo.close(); } final byte[] raw = blobLoader.isLarge() ? null : blobLoader.getCachedBytes(); final long when = fromCommit.getCommitTime() * 1000L; rsp.setDateHeader("Last-Modified", when); rsp.setDateHeader("Expires", 0L); rsp.setHeader("Pragma", "no-cache"); rsp.setHeader("Cache-Control", "no-cache, must-revalidate"); OutputStream out; ZipOutputStream zo; final MimeType contentType = registry.getMimeType(path, raw); if (!registry.isSafeInline(contentType)) { // The content may not be safe to transmit inline, as a browser might // interpret it as HTML or JavaScript hosted by this site. Such code // might then run in the site's security domain, and may be able to use // the user's cookies to perform unauthorized actions. // // Usually, wrapping the content into a ZIP file forces the browser to // save the content to the local system instead. // rsp.setContentType(ZIP.toString()); rsp.setHeader( "Content-Disposition", "attachment; filename=\"" + safeFileName(path, suffix) + ".zip" + "\""); zo = new ZipOutputStream(rsp.getOutputStream()); final ZipEntry e = new ZipEntry(safeFileName(path, rand(req, suffix))); e.setComment(fromCommit.name() + ":" + path); e.setSize(blobLoader.getSize()); e.setTime(when); zo.putNextEntry(e); out = zo; } else { rsp.setContentType(contentType.toString()); rsp.setHeader("Content-Length", "" + blobLoader.getSize()); out = rsp.getOutputStream(); zo = null; } if (raw != null) { out.write(raw); } else { blobLoader.copyTo(out); } if (zo != null) { zo.closeEntry(); } out.close(); }
private IDiffContainer buildDiffContainer( RevCommit baseCommit, RevCommit compareCommit, IProgressMonitor monitor) throws IOException, InterruptedException { boolean useIndex = compareVersion.equals(CompareTreeView.INDEX_VERSION); boolean checkIgnored = false; IDiffContainer result = new DiffNode(Differencer.CONFLICTING); try (TreeWalk tw = new TreeWalk(repository)) { // filter by selected resources if (filterPathStrings.size() > 1) { List<TreeFilter> suffixFilters = new ArrayList<TreeFilter>(); for (String filterPath : filterPathStrings) suffixFilters.add(PathFilter.create(filterPath)); TreeFilter otf = OrTreeFilter.create(suffixFilters); tw.setFilter(otf); } else if (filterPathStrings.size() > 0) { String path = filterPathStrings.get(0); if (path.length() != 0) tw.setFilter(PathFilter.create(path)); } tw.setRecursive(true); int baseTreeIndex; if (baseCommit == null) { // compare workspace with something checkIgnored = true; baseTreeIndex = tw.addTree(new FileTreeIterator(repository)); } else baseTreeIndex = tw.addTree( new CanonicalTreeParser(null, repository.newObjectReader(), baseCommit.getTree())); int compareTreeIndex; if (!useIndex) compareTreeIndex = tw.addTree( new CanonicalTreeParser( null, repository.newObjectReader(), compareCommit.getTree())); else // compare something with the index compareTreeIndex = tw.addTree(new DirCacheIterator(repository.readDirCache())); while (tw.next()) { if (monitor.isCanceled()) throw new InterruptedException(); AbstractTreeIterator compareVersionIterator = tw.getTree(compareTreeIndex, AbstractTreeIterator.class); AbstractTreeIterator baseVersionIterator = tw.getTree(baseTreeIndex, AbstractTreeIterator.class); if (checkIgnored && baseVersionIterator != null && ((WorkingTreeIterator) baseVersionIterator).isEntryIgnored()) continue; if (compareVersionIterator != null && baseVersionIterator != null) { boolean equalContent = compareVersionIterator .getEntryObjectId() .equals(baseVersionIterator.getEntryObjectId()); if (equalContent) continue; } String encoding = null; GitFileRevision compareRev = null; if (compareVersionIterator != null) { String entryPath = compareVersionIterator.getEntryPathString(); encoding = CompareCoreUtils.getResourceEncoding(repository, entryPath); if (!useIndex) compareRev = GitFileRevision.inCommit( repository, compareCommit, entryPath, tw.getObjectId(compareTreeIndex)); else compareRev = GitFileRevision.inIndex(repository, entryPath); } GitFileRevision baseRev = null; if (baseVersionIterator != null) { String entryPath = baseVersionIterator.getEntryPathString(); if (encoding == null) { encoding = CompareCoreUtils.getResourceEncoding(repository, entryPath); } baseRev = GitFileRevision.inCommit( repository, baseCommit, entryPath, tw.getObjectId(baseTreeIndex)); } if (compareVersionIterator != null && baseVersionIterator != null) { monitor.setTaskName(baseVersionIterator.getEntryPathString()); // content exists on both sides add( result, baseVersionIterator.getEntryPathString(), new DiffNode( new FileRevisionTypedElement(compareRev, encoding), new FileRevisionTypedElement(baseRev, encoding))); } else if (baseVersionIterator != null && compareVersionIterator == null) { monitor.setTaskName(baseVersionIterator.getEntryPathString()); // only on base side add( result, baseVersionIterator.getEntryPathString(), new DiffNode( Differencer.DELETION | Differencer.RIGHT, null, null, new FileRevisionTypedElement(baseRev, encoding))); } else if (compareVersionIterator != null && baseVersionIterator == null) { monitor.setTaskName(compareVersionIterator.getEntryPathString()); // only on compare side add( result, compareVersionIterator.getEntryPathString(), new DiffNode( Differencer.ADDITION | Differencer.RIGHT, null, new FileRevisionTypedElement(compareRev, encoding), null)); } if (monitor.isCanceled()) throw new InterruptedException(); } return result; } }
public Map<String, Object> toSoyData(ObjectId treeId, TreeWalk tw) throws MissingObjectException, IOException { ReadmeHelper readme = new ReadmeHelper(reader, view, MarkdownConfig.get(cfg), rootTree, requestUri); List<Object> entries = Lists.newArrayList(); GitilesView.Builder urlBuilder = GitilesView.path().copyFrom(view); while (tw.next()) { FileType type = FileType.forEntry(tw); String name = tw.getNameString(); GitilesView.Type viewType = view.getType(); if (viewType == GitilesView.Type.PATH) { urlBuilder.setPathPart(view.getPathPart() + "/" + name); } else if (viewType == GitilesView.Type.REVISION) { // Got here from a tag pointing at a tree. urlBuilder.setPathPart(name); } else { throw new IllegalStateException( String.format("Cannot render TreeSoyData from %s view", viewType)); } String url = urlBuilder.toUrl(); if (type == FileType.TREE) { name += "/"; url += "/"; } Map<String, String> entry = Maps.newHashMapWithExpectedSize(4); entry.put("type", type.toString()); entry.put("name", name); entry.put("url", url); if (type == FileType.SYMLINK) { String target = new String(reader.open(tw.getObjectId(0)).getCachedBytes(), UTF_8); entry.put("targetName", getTargetDisplayName(target)); String targetUrl = resolveTargetUrl(view, target); if (targetUrl != null) { entry.put("targetUrl", targetUrl); } } else { readme.considerEntry(tw); } entries.add(entry); } Map<String, Object> data = Maps.newHashMapWithExpectedSize(3); data.put("sha", treeId.name()); data.put("entries", entries); if (view.getType() == GitilesView.Type.PATH && view.getRevision().getPeeledType() == OBJ_COMMIT) { data.put("logUrl", GitilesView.log().copyFrom(view).toUrl()); data.put( "archiveUrl", GitilesView.archive() .copyFrom(view) .setPathPart(Strings.emptyToNull(view.getPathPart())) .setExtension(archiveFormat.getDefaultSuffix()) .toUrl()); data.put("archiveType", archiveFormat.getShortName()); } if (readme.isPresent()) { data.put("readmePath", readme.getPath()); data.put("readmeHtml", readme.render()); } return data; }
protected void addInformationForPath( Repository repository, Git git, DocumentWriter writer, RevCommit commit, String path, CallSpecification spec, Values values) throws GitAPIException, IOException { // Make sure the path is in the canonical form we need ... if (path.startsWith("/")) { if (path.length() == 1) path = ""; else path = path.substring(1); } // Now see if we're actually referring to the "jcr:content" node ... boolean isContentNode = false; if (path.endsWith(JCR_CONTENT_SUFFIX)) { isContentNode = true; path = path.substring(0, path.length() - JCR_CONTENT_SUFFIX.length()); } // Create the TreeWalk that we'll use to navigate the files/directories ... final TreeWalk tw = new TreeWalk(repository); tw.addTree(commit.getTree()); if ("".equals(path)) { // This is the top-level directory, so we don't need to pre-walk to find anything ... tw.setRecursive(false); while (tw.next()) { String childName = tw.getNameString(); String childId = spec.childId(childName); writer.addChild(childId, childName); } } else { // We need to first find our path *before* we can walk the children ... PathFilter filter = PathFilter.create(path); tw.setFilter(filter); while (tw.next()) { if (filter.isDone(tw)) { break; } else if (tw.isSubtree()) { tw.enterSubtree(); } } // Now that the TreeWalk is the in right location given by the 'path', we can get the if (tw.isSubtree()) { // The object at the 'path' is a directory, so go into it ... tw.enterSubtree(); // Find the commit in which this folder was last modified ... // This may not be terribly efficient, but it seems to work faster on subsequent runs ... RevCommit folderCommit = git.log().addPath(path).call().iterator().next(); // Add folder-related properties ... String committer = folderCommit.getCommitterIdent().getName(); String author = folderCommit.getAuthorIdent().getName(); DateTime committed = values.dateFrom(folderCommit.getCommitTime()); writer.setPrimaryType(GitLexicon.FOLDER); writer.addProperty(JcrLexicon.CREATED, committed); writer.addProperty(JcrLexicon.CREATED_BY, committer); writer.addProperty(GitLexicon.OBJECT_ID, folderCommit.getId().name()); writer.addProperty(GitLexicon.AUTHOR, author); writer.addProperty(GitLexicon.COMMITTER, committer); writer.addProperty(GitLexicon.COMMITTED, committed); writer.addProperty(GitLexicon.TITLE, folderCommit.getShortMessage()); // And now walk the contents of the directory ... while (tw.next()) { String childName = tw.getNameString(); String childId = spec.childId(childName); writer.addChild(childId, childName); } } else { // The path specifies a file (or a content node) ... // Find the commit in which this folder was last modified ... // This may not be terribly efficient, but it seems to work faster on subsequent runs ... RevCommit fileCommit = git.log().addPath(path).call().iterator().next(); // Add file-related properties ... String committer = fileCommit.getCommitterIdent().getName(); String author = fileCommit.getAuthorIdent().getName(); DateTime committed = values.dateFrom(fileCommit.getCommitTime()); if (isContentNode) { writer.setPrimaryType(GitLexicon.RESOURCE); writer.addProperty(JcrLexicon.LAST_MODIFIED, committed); writer.addProperty(JcrLexicon.LAST_MODIFIED_BY, committer); writer.addProperty(GitLexicon.OBJECT_ID, fileCommit.getId().name()); writer.addProperty(GitLexicon.AUTHOR, author); writer.addProperty(GitLexicon.COMMITTER, committer); writer.addProperty(GitLexicon.COMMITTED, committed); writer.addProperty(GitLexicon.TITLE, fileCommit.getShortMessage()); // Create the BinaryValue ... ObjectId fileObjectId = tw.getObjectId(0); ObjectLoader fileLoader = repository.open(fileObjectId); BinaryKey key = new BinaryKey(fileObjectId.getName()); BinaryValue value = values.binaryFor(key, fileLoader.getSize()); if (value == null) { // It wasn't found in the binary store ... if (fileLoader.isLarge()) { // Too large to hold in memory, so use the binary store (which reads the file // immediately) ... value = values.binaryFrom(fileLoader.openStream()); } else { // This is small enough to fit into a byte[], but it still may be pretty big ... value = new GitBinaryValue( fileObjectId, fileLoader, connector.getSourceName(), name, connector.getMimeTypeDetector()); } } writer.addProperty(JcrLexicon.DATA, value); if (connector.includeMimeType()) { try { String filename = spec.parameter(spec.parameterCount() - 1); // the last is 'jcr:content' String mimeType = value.getMimeType(filename); if (mimeType != null) writer.addProperty(JcrLexicon.MIMETYPE, mimeType); } catch (RepositoryException e) { // do nothing } catch (IOException e) { // do nothing } } } else { writer.setPrimaryType(GitLexicon.FILE); writer.addProperty(JcrLexicon.CREATED, committed); writer.addProperty(JcrLexicon.CREATED_BY, committer); writer.addProperty(GitLexicon.OBJECT_ID, fileCommit.getId().name()); writer.addProperty(GitLexicon.AUTHOR, author); writer.addProperty(GitLexicon.COMMITTER, committer); writer.addProperty(GitLexicon.COMMITTED, committed); writer.addProperty(GitLexicon.TITLE, fileCommit.getShortMessage()); // Add the "jcr:content" child node ... String childId = spec.childId(JCR_CONTENT); writer.addChild(childId, JCR_CONTENT); } } } }