예제 #1
0
  public void testRecursiveTreeWalk() throws Exception {
    RevCommit commit = writeFileInFolderAndCommit();
    deleteAll();
    writeFileWithFolderName();
    TreeWalk treeWalk = createTreeWalk(commit);

    assertTrue(treeWalk.next());
    assertEquals("folder", treeWalk.getPathString());
    assertTrue(treeWalk.next());
    assertEquals("folder/file", treeWalk.getPathString());
    assertFalse(treeWalk.next());
  }
예제 #2
0
 private void assertPaths(TreeWalk treeWalk, String... paths) throws Exception {
   for (int i = 0; i < paths.length; i++) {
     assertTrue(treeWalk.next());
     assertPath(treeWalk.getPathString(), paths);
   }
   assertFalse(treeWalk.next());
 }
예제 #3
0
  @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;
    }
  }
예제 #4
0
  private TreeFormatter createTreeFormatter(
      Map<SubtreeConfig, RevCommit> parentCommits, String commitMessage)
      throws MissingObjectException, IncorrectObjectTypeException, CorruptObjectException,
          IOException {
    TreeWalk treeWalk = new TreeWalk(repository);
    try {
      treeWalk.setRecursive(false);
      addTrees(parentCommits, treeWalk);

      TreeFormatter treeFormatter = new TreeFormatter();
      while (treeWalk.next()) {
        AbstractTreeIterator iterator = getSingleTreeIterator(treeWalk, commitMessage);
        if (iterator == null) {
          throw new IllegalStateException(
              "Tree walker did not return a single tree (should not happen): "
                  + treeWalk.getPathString());
        }
        treeFormatter.append(
            iterator.getEntryPathBuffer(),
            0,
            iterator.getEntryPathLength(),
            iterator.getEntryFileMode(),
            iterator.getEntryObjectId());
      }
      return treeFormatter;
    } finally {
      treeWalk.release();
    }
  }
예제 #5
0
 public static List<File> getNotIgnoredFilesOfRepo(File directory) throws GitException {
   Git git = openRepository(directory);
   Repository repo = null;
   repo = git.getRepository();
   List<File> foundFiles = new ArrayList<>();
   TreeWalk treeWalk = null;
   try {
     treeWalk = new TreeWalk(repo);
     FileTreeIterator tree = new FileTreeIterator(repo);
     treeWalk.addTree(tree);
     treeWalk.setRecursive(false);
     while (treeWalk.next()) {
       WorkingTreeIterator iterator = treeWalk.getTree(0, WorkingTreeIterator.class);
       if (!iterator.isEntryIgnored())
         if (treeWalk.isSubtree()) {
           treeWalk.enterSubtree();
         } else {
           File file = new File(directory, treeWalk.getPathString());
           foundFiles.add(file);
         }
     }
   } catch (IOException e) {
     throw new GitException("Listing of non-ignored files in " + directory + " failed", e);
   } finally {
     if (treeWalk != null) treeWalk.close();
   }
   return foundFiles;
 }
  /**
   * Returns all tree entries that do not match the ignore paths.
   *
   * @param db
   * @param ignorePaths
   * @param dcBuilder
   * @throws IOException
   */
  private List<DirCacheEntry> getTreeEntries(Repository db, Collection<String> ignorePaths)
      throws IOException {
    List<DirCacheEntry> list = new ArrayList<DirCacheEntry>();
    ObjectId treeId = db.resolve(BRANCH + "^{tree}");
    if (treeId == null) {
      // branch does not exist yet, could be migrating tickets
      return list;
    }
    try (TreeWalk tw = new TreeWalk(db)) {
      int hIdx = tw.addTree(treeId);
      tw.setRecursive(true);

      while (tw.next()) {
        String path = tw.getPathString();
        CanonicalTreeParser hTree = null;
        if (hIdx != -1) {
          hTree = tw.getTree(hIdx, CanonicalTreeParser.class);
        }
        if (!ignorePaths.contains(path)) {
          // add all other tree entries
          if (hTree != null) {
            final DirCacheEntry entry = new DirCacheEntry(path);
            entry.setObjectId(hTree.getEntryObjectId());
            entry.setFileMode(hTree.getEntryFileMode());
            list.add(entry);
          }
        }
      }
    }
    return list;
  }
예제 #7
0
 /**
  * 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());
 }
예제 #8
0
  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();
  }
예제 #10
0
 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;
 }
예제 #11
0
  /**
   * Compute the current projects that will be missing after the given branch is checked out
   *
   * @param branch
   * @param currentProjects
   * @return non-null but possibly empty array of missing projects
   */
  private IProject[] getMissingProjects(String branch, IProject[] currentProjects) {
    if (delete || currentProjects.length == 0) return new IProject[0];

    ObjectId targetTreeId;
    ObjectId currentTreeId;
    try {
      targetTreeId = repository.resolve(branch + "^{tree}"); // $NON-NLS-1$
      currentTreeId = repository.resolve(Constants.HEAD + "^{tree}"); // $NON-NLS-1$
    } catch (IOException e) {
      return new IProject[0];
    }
    if (targetTreeId == null || currentTreeId == null) return new IProject[0];

    Map<File, IProject> locations = new HashMap<File, IProject>();
    for (IProject project : currentProjects) {
      IPath location = project.getLocation();
      if (location == null) continue;
      location = location.append(IProjectDescription.DESCRIPTION_FILE_NAME);
      locations.put(location.toFile(), project);
    }

    List<IProject> toBeClosed = new ArrayList<IProject>();
    File root = repository.getWorkTree();
    TreeWalk walk = new TreeWalk(repository);
    try {
      walk.addTree(targetTreeId);
      walk.addTree(currentTreeId);
      walk.addTree(new FileTreeIterator(repository));
      walk.setRecursive(true);
      walk.setFilter(
          AndTreeFilter.create(
              PathSuffixFilter.create(IProjectDescription.DESCRIPTION_FILE_NAME),
              TreeFilter.ANY_DIFF));
      while (walk.next()) {
        AbstractTreeIterator targetIter = walk.getTree(0, AbstractTreeIterator.class);
        if (targetIter != null) continue;

        AbstractTreeIterator currentIter = walk.getTree(1, AbstractTreeIterator.class);
        AbstractTreeIterator workingIter = walk.getTree(2, AbstractTreeIterator.class);
        if (currentIter == null || workingIter == null) continue;

        IProject project = locations.get(new File(root, walk.getPathString()));
        if (project != null) toBeClosed.add(project);
      }
    } catch (IOException e) {
      return new IProject[0];
    } finally {
      walk.release();
    }
    return toBeClosed.toArray(new IProject[toBeClosed.size()]);
  }
예제 #12
0
 public List<String> readElementsAt(Repository repository, String commit) throws IOException {
   RevWalk revWalk = new RevWalk(repository);
   RevCommit revCommit = revWalk.parseCommit(ObjectId.fromString(commit));
   RevTree tree = revCommit.getTree();
   List<String> items = new ArrayList<>();
   TreeWalk treeWalk = new TreeWalk(repository);
   treeWalk.addTree(tree);
   treeWalk.setRecursive(true);
   treeWalk.setPostOrderTraversal(true);
   while (treeWalk.next()) {
     items.add(treeWalk.getPathString());
   }
   return items;
 }
예제 #13
0
 /**
  * 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.
 }
예제 #14
0
 /**
  * Returns the list of files in the specified folder at the specified commit. If the repository
  * does not exist or is empty, an empty list is returned.
  *
  * @param repository
  * @param path if unspecified, root folder is assumed.
  * @param commit if null, HEAD is assumed.
  * @return list of files in specified path
  */
 public static List<PathModel> getFilesInPath(
     Repository repository, String path, RevCommit commit) {
   List<PathModel> list = new ArrayList<PathModel>();
   if (!hasCommits(repository)) {
     return list;
   }
   if (commit == null) {
     commit = getCommit(repository, null);
   }
   final TreeWalk tw = new TreeWalk(repository);
   try {
     tw.addTree(commit.getTree());
     if (!(path == null)) {
       PathFilter f = PathFilter.create(path);
       tw.setFilter(f);
       tw.setRecursive(false);
       boolean foundFolder = false;
       while (tw.next()) {
         if (!foundFolder && tw.isSubtree()) {
           tw.enterSubtree();
         }
         if (tw.getPathString().equals(path)) {
           foundFolder = true;
           continue;
         }
         if (foundFolder) {
           list.add(getPathModel(tw, path, commit));
         }
       }
     } else {
       tw.setRecursive(false);
       while (tw.next()) {
         list.add(getPathModel(tw, null, commit));
       }
     }
   } catch (IOException e) {
     // error(e, repository, "{0} failed to get files for commit {1}", commit.getName());
     Logger.error(e, e.getMessage());
   } finally {
     tw.release();
   }
   Collections.sort(list);
   return list;
 }
예제 #15
0
  /**
   * Refreshes all resources that changed in the index since the last call to this method. This is
   * suitable for incremental updates on index changed events
   *
   * <p>For bare repositories this does nothing.
   */
  private void refreshIndexDelta() {
    if (repository.isBare()) return;

    try {
      DirCache currentIndex = repository.readDirCache();
      DirCache oldIndex = lastIndex;

      lastIndex = currentIndex;

      if (oldIndex == null) {
        refresh(); // full refresh in case we have no data to compare.
        return;
      }

      Set<String> paths = new TreeSet<String>();
      TreeWalk walk = new TreeWalk(repository);

      try {
        walk.addTree(new DirCacheIterator(oldIndex));
        walk.addTree(new DirCacheIterator(currentIndex));
        walk.setFilter(new InterIndexDiffFilter());

        while (walk.next()) {
          if (walk.isSubtree()) walk.enterSubtree();
          else paths.add(walk.getPathString());
        }
      } finally {
        walk.release();
      }

      if (!paths.isEmpty()) refreshFiles(paths);

    } catch (IOException ex) {
      Activator.error(
          MessageFormat.format(CoreText.IndexDiffCacheEntry_errorCalculatingIndexDelta, repository),
          ex);
      scheduleReloadJob(
          "Exception while calculating index delta, doing full reload instead"); //$NON-NLS-1$
    }
  }
예제 #16
0
  @Override
  public List<String> getSnapshotFiles(String commitUid) {

    try {

      RevCommit lastCommit = revWalk.parseCommit(repository.resolve(commitUid));

      treeWalk.reset();
      treeWalk.addTree(lastCommit.getTree());
      treeWalk.setRecursive(true);

      List<String> files = new ArrayList<String>();
      while (treeWalk.next()) {
        String path = repositoryPath + "/" + treeWalk.getPathString();
        files.add(StringUtils.sha1(path));
      }

      return files;

    } catch (IOException e) {
      throw new VisMinerAPIException(e.getMessage(), e);
    }
  }
예제 #17
0
  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));
        }
      }
    }
  }
예제 #18
0
  public static List<PathChangeModel> getFilesInCommit(Repository repository, RevCommit commit) {
    List<PathChangeModel> list = new ArrayList<PathChangeModel>();
    if (!hasCommits(repository)) {
      return list;
    }
    RevWalk rw = new RevWalk(repository);
    try {
      if (commit == null) {
        ObjectId object = getDefaultBranch(repository);
        commit = rw.parseCommit(object);
      }

      if (commit.getParentCount() == 0) {
        TreeWalk tw = new TreeWalk(repository);
        tw.reset();
        tw.setRecursive(true);
        tw.addTree(commit.getTree());
        while (tw.next()) {
          list.add(
              new PathChangeModel(
                  tw.getPathString(),
                  tw.getPathString(),
                  0,
                  tw.getRawMode(0),
                  commit.getId().getName(),
                  ChangeType.ADD));
        }
        tw.release();
      } else {
        RevCommit parent = rw.parseCommit(commit.getParent(0).getId());
        DiffFormatter df = new DiffFormatter(DisabledOutputStream.INSTANCE);
        df.setRepository(repository);
        df.setDiffComparator(RawTextComparator.DEFAULT);
        df.setDetectRenames(true);
        List<DiffEntry> diffs = df.scan(parent.getTree(), commit.getTree());
        for (DiffEntry diff : diffs) {
          if (diff.getChangeType().equals(ChangeType.DELETE)) {
            list.add(
                new PathChangeModel(
                    diff.getOldPath(),
                    diff.getOldPath(),
                    0,
                    diff.getNewMode().getBits(),
                    commit.getId().getName(),
                    diff.getChangeType()));
          } else {
            list.add(
                new PathChangeModel(
                    diff.getNewPath(),
                    diff.getNewPath(),
                    0,
                    diff.getNewMode().getBits(),
                    commit.getId().getName(),
                    diff.getChangeType()));
          }
        }
      }
    } catch (Throwable t) {
      // todo
      Logger.error(t, t.getMessage());
    } finally {
      rw.dispose();
    }
    return list;
  }
예제 #19
0
 private static void assertModes(final String path, final FileMode mode0, final TreeWalk tw)
     throws Exception {
   assertTrue("has " + path, tw.next());
   assertEquals(path, tw.getPathString());
   assertEquals(mode0, tw.getFileMode(0));
 }
예제 #20
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);
    }
  }
  /**
   * Deletes a ticket from the repository.
   *
   * @param ticket
   * @return true if successful
   */
  @Override
  protected synchronized boolean deleteTicketImpl(
      RepositoryModel repository, TicketModel ticket, String deletedBy) {
    if (ticket == null) {
      throw new RuntimeException("must specify a ticket!");
    }

    boolean success = false;
    Repository db = repositoryManager.getRepository(ticket.repository);
    try {
      RefModel ticketsBranch = getTicketsBranch(db);

      if (ticketsBranch == null) {
        throw new RuntimeException(BRANCH + " does not exist!");
      }
      String ticketPath = toTicketPath(ticket.number);

      try {
        ObjectId treeId = db.resolve(BRANCH + "^{tree}");

        // Create the in-memory index of the new/updated ticket
        DirCache index = DirCache.newInCore();
        DirCacheBuilder builder = index.builder();

        // Traverse HEAD to add all other paths
        try (TreeWalk treeWalk = new TreeWalk(db)) {
          int hIdx = -1;
          if (treeId != null) {
            hIdx = treeWalk.addTree(treeId);
          }
          treeWalk.setRecursive(true);
          while (treeWalk.next()) {
            String path = treeWalk.getPathString();
            CanonicalTreeParser hTree = null;
            if (hIdx != -1) {
              hTree = treeWalk.getTree(hIdx, CanonicalTreeParser.class);
            }
            if (!path.startsWith(ticketPath)) {
              // add entries from HEAD for all other paths
              if (hTree != null) {
                final DirCacheEntry entry = new DirCacheEntry(path);
                entry.setObjectId(hTree.getEntryObjectId());
                entry.setFileMode(hTree.getEntryFileMode());

                // add to temporary in-core index
                builder.add(entry);
              }
            }
          }
        }

        // finish temporary in-core index used for this commit
        builder.finish();

        success = commitIndex(db, index, deletedBy, "- " + ticket.number);

      } catch (Throwable t) {
        log.error(
            MessageFormat.format(
                "Failed to delete ticket {0,number,0} from {1}", ticket.number, db.getDirectory()),
            t);
      }
    } finally {
      db.close();
    }
    return success;
  }
예제 #22
0
  private DirCache createTemporaryIndex(ObjectId headId, DirCache index, RevWalk rw)
      throws IOException {
    ObjectInserter inserter = null;

    // get DirCacheBuilder for existing index
    DirCacheBuilder existingBuilder = index.builder();

    // get DirCacheBuilder for newly created in-core index to build a
    // temporary index for this commit
    DirCache inCoreIndex = DirCache.newInCore();
    DirCacheBuilder tempBuilder = inCoreIndex.builder();

    onlyProcessed = new boolean[only.size()];
    boolean emptyCommit = true;

    try (TreeWalk treeWalk = new TreeWalk(repo)) {
      treeWalk.setOperationType(OperationType.CHECKIN_OP);
      int dcIdx = treeWalk.addTree(new DirCacheBuildIterator(existingBuilder));
      FileTreeIterator fti = new FileTreeIterator(repo);
      fti.setDirCacheIterator(treeWalk, 0);
      int fIdx = treeWalk.addTree(fti);
      int hIdx = -1;
      if (headId != null) hIdx = treeWalk.addTree(rw.parseTree(headId));
      treeWalk.setRecursive(true);

      String lastAddedFile = null;
      while (treeWalk.next()) {
        String path = treeWalk.getPathString();
        // check if current entry's path matches a specified path
        int pos = lookupOnly(path);

        CanonicalTreeParser hTree = null;
        if (hIdx != -1) hTree = treeWalk.getTree(hIdx, CanonicalTreeParser.class);

        DirCacheIterator dcTree = treeWalk.getTree(dcIdx, DirCacheIterator.class);

        if (pos >= 0) {
          // include entry in commit

          FileTreeIterator fTree = treeWalk.getTree(fIdx, FileTreeIterator.class);

          // check if entry refers to a tracked file
          boolean tracked = dcTree != null || hTree != null;
          if (!tracked) continue;

          // for an unmerged path, DirCacheBuildIterator will yield 3
          // entries, we only want to add one
          if (path.equals(lastAddedFile)) continue;

          lastAddedFile = path;

          if (fTree != null) {
            // create a new DirCacheEntry with data retrieved from
            // disk
            final DirCacheEntry dcEntry = new DirCacheEntry(path);
            long entryLength = fTree.getEntryLength();
            dcEntry.setLength(entryLength);
            dcEntry.setLastModified(fTree.getEntryLastModified());
            dcEntry.setFileMode(fTree.getIndexFileMode(dcTree));

            boolean objectExists =
                (dcTree != null && fTree.idEqual(dcTree))
                    || (hTree != null && fTree.idEqual(hTree));
            if (objectExists) {
              dcEntry.setObjectId(fTree.getEntryObjectId());
            } else {
              if (FileMode.GITLINK.equals(dcEntry.getFileMode()))
                dcEntry.setObjectId(fTree.getEntryObjectId());
              else {
                // insert object
                if (inserter == null) inserter = repo.newObjectInserter();
                long contentLength = fTree.getEntryContentLength();
                InputStream inputStream = fTree.openEntryStream();
                try {
                  dcEntry.setObjectId(
                      inserter.insert(Constants.OBJ_BLOB, contentLength, inputStream));
                } finally {
                  inputStream.close();
                }
              }
            }

            // add to existing index
            existingBuilder.add(dcEntry);
            // add to temporary in-core index
            tempBuilder.add(dcEntry);

            if (emptyCommit
                && (hTree == null
                    || !hTree.idEqual(fTree)
                    || hTree.getEntryRawMode() != fTree.getEntryRawMode()))
              // this is a change
              emptyCommit = false;
          } else {
            // if no file exists on disk, neither add it to
            // index nor to temporary in-core index

            if (emptyCommit && hTree != null)
              // this is a change
              emptyCommit = false;
          }

          // keep track of processed path
          onlyProcessed[pos] = true;
        } else {
          // add entries from HEAD for all other paths
          if (hTree != null) {
            // create a new DirCacheEntry with data retrieved from
            // HEAD
            final DirCacheEntry dcEntry = new DirCacheEntry(path);
            dcEntry.setObjectId(hTree.getEntryObjectId());
            dcEntry.setFileMode(hTree.getEntryFileMode());

            // add to temporary in-core index
            tempBuilder.add(dcEntry);
          }

          // preserve existing entry in index
          if (dcTree != null) existingBuilder.add(dcTree.getDirCacheEntry());
        }
      }
    }

    // there must be no unprocessed paths left at this point; otherwise an
    // untracked or unknown path has been specified
    for (int i = 0; i < onlyProcessed.length; i++)
      if (!onlyProcessed[i])
        throw new JGitInternalException(
            MessageFormat.format(JGitText.get().entryNotFoundByPath, only.get(i)));

    // there must be at least one change
    if (emptyCommit) throw new JGitInternalException(JGitText.get().emptyCommit);

    // update index
    existingBuilder.commit();
    // finish temporary in-core index used for this commit
    tempBuilder.finish();
    return inCoreIndex;
  }
예제 #23
0
 protected PathInfo(TreeWalk tw) {
   fileMode = tw.getFileMode(0);
   path = tw.getPathString();
   objectId = tw.getObjectId(0);
 }