Example #1
0
  /**
   * Parses an array of Git commits and returns an array of commits that affected the specified
   * object.
   *
   * @param repository the Git repository
   * @param commitIds the Git commit IDs to parse
   * @param path the object affected
   * @return an array of {@link GitCommit} objects representing the commits
   */
  public NSArray<GitCommit> commitsWithIds(NSArray<ObjectId> commitIds, String path) {
    try {
      RevWalk rw = new RevWalk(repository);

      try {
        rw.sort(RevSort.COMMIT_TIME_DESC);

        if (path != null) {
          rw.setTreeFilter(
              AndTreeFilter.create(PathSuffixFilter.create(path), TreeFilter.ANY_DIFF));
        } else {
          rw.setTreeFilter(TreeFilter.ALL);
        }

        for (ObjectId commitId : commitIds) {
          rw.markStart(rw.parseCommit(commitId));
        }

        NSMutableArray<GitCommit> commits = new NSMutableArray<GitCommit>();

        for (RevCommit commit : rw) {
          commits.add(new GitCommit(commit));
        }

        return commits;
      } finally {
        rw.release();
      }
    } catch (Exception e) {
      log.error("An exception occurred while parsing the commit: ", e);
      return null;
    }
  }
  /**
   * Returns a list of commits for the repository or a path within the repository. Caller may
   * specify ending revision with objectId. Caller may specify offset and maxCount to achieve
   * pagination of results. If the repository does not exist or is empty, an empty list is returned.
   *
   * @param repository
   * @param objectId if unspecified, HEAD is assumed.
   * @param path if unspecified, commits for repository are returned. If specified, commits for the
   *     path are returned.
   * @param offset
   * @param maxCount if < 0, all commits are returned.
   * @return a paged list of commits
   */
  public static List<RevCommit> getRevLog(
      Repository repository, String objectId, String path, int offset, int maxCount) {
    List<RevCommit> list = new ArrayList<RevCommit>();
    if (maxCount == 0) {
      return list;
    }
    if (!hasCommits(repository)) {
      return list;
    }
    try {
      // resolve branch
      ObjectId branchObject;
      if (objectId == null) {
        branchObject = getDefaultBranch(repository);
      } else {
        branchObject = repository.resolve(objectId);
      }

      RevWalk rw = new RevWalk(repository);
      rw.markStart(rw.parseCommit(branchObject));
      if (!(path == null)) {
        TreeFilter filter =
            AndTreeFilter.create(
                PathFilterGroup.createFromStrings(Collections.singleton(path)),
                TreeFilter.ALL); // TreeFilter.ANY_DIFF
        rw.setTreeFilter(filter);
      }
      Iterable<RevCommit> revlog = rw;
      if (offset > 0) {
        int count = 0;
        for (RevCommit rev : revlog) {
          count++;
          if (count > offset) {
            list.add(rev);
            if (maxCount > 0 && list.size() == maxCount) {
              break;
            }
          }
        }
      } else {
        for (RevCommit rev : revlog) {
          list.add(rev);
          if (maxCount > 0 && list.size() == maxCount) {
            break;
          }
        }
      }
      rw.dispose();
    } catch (Throwable t) {
      // todo
      Logger.error(t, t.getMessage());
    }
    return list;
  }
  private boolean handleGetCommitBody(
      HttpServletRequest request,
      HttpServletResponse response,
      Repository db,
      String ref,
      String pattern)
      throws IOException, ServletException, CoreException {
    ObjectId refId = db.resolve(ref);
    if (refId == null) {
      String msg = NLS.bind("Failed to get commit body for ref {0}", ref);
      return statusHandler.handleRequest(
          request,
          response,
          new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, msg, null));
    }
    RevWalk walk = new RevWalk(db);
    walk.setTreeFilter(
        AndTreeFilter.create(
            PathFilterGroup.createFromStrings(Collections.singleton(pattern)),
            TreeFilter.ANY_DIFF));
    RevCommit revCommit = walk.parseCommit(refId);
    walk.dispose();

    Commit commit = new Commit(null /* not needed */, db, revCommit, pattern);
    ObjectStream stream = commit.toObjectStream();
    if (stream == null) {
      String msg = NLS.bind("Commit body for ref {0} not found", ref);
      return statusHandler.handleRequest(
          request,
          response,
          new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_FOUND, msg, null));
    }
    IOUtilities.pipe(stream, response.getOutputStream(), true, false);

    return true;
  }
  @Override
  public void execute() throws BuildException {
    if (_property == null) {
      throw new BuildException("Property attribute is required", getLocation());
    }

    if (_path == null) {
      throw new BuildException("Path attribute is required", getLocation());
    }

    File gitDir = PathUtil.getGitDir(_gitDir, getProject(), getLocation());

    String relativePath = PathUtil.toRelativePath(gitDir, _path);

    if (_useCache) {
      String hash = _hashes.get(relativePath);

      if (hash != null) {
        Project currentProject = getProject();

        currentProject.setNewProperty(_property, hash);

        return;
      }
    }

    try (Repository repository = RepositoryCache.open(FileKey.exact(gitDir, FS.DETECTED))) {

      RevWalk revWalk = new RevWalk(repository);

      revWalk.setRetainBody(false);

      revWalk.markStart(revWalk.parseCommit(repository.resolve(Constants.HEAD)));

      if (_ignoreFileName == null) {
        revWalk.setRevFilter(MaxCountRevFilter.create(1));
      } else {
        revWalk.setRevFilter(MaxCountRevFilter.create(2));
      }

      revWalk.setTreeFilter(
          AndTreeFilter.create(PathFilter.create(relativePath), TreeFilter.ANY_DIFF));

      RevCommit revCommit = revWalk.next();

      if (revCommit == null) {
        throw new IllegalStateException("Unable to find any commit under " + _path);
      }

      if (hasIgnoreFile(repository, revCommit, relativePath)) {
        RevCommit secondRevCommit = revWalk.next();

        if (secondRevCommit != null) {
          revCommit = secondRevCommit;
        }
      }

      Project currentProject = getProject();

      String hash = revCommit.name();

      currentProject.setNewProperty(_property, hash);

      if (_useCache) {
        _hashes.put(relativePath, hash);
      }

      revWalk.dispose();
    } catch (Exception e) {
      throw new BuildException("Unable to get head hash for path " + _path, e);
    }
  }
Example #5
0
  /**
   * Process the EGit history associated with a given project.
   *
   * @param selectedProject selected project, presumably an object contribution selection
   * @throws CoreException
   * @throws IOException
   */
  public void processHistory(IProject selectedProject, IProgressMonitor monitor)
      throws CoreException, IOException {

    // find the repository mapping for the project
    // if none found, return
    RepositoryMapping repositoryMapping = RepositoryMapping.getMapping((IResource) selectedProject);
    if (repositoryMapping == null) {
      CertWareLog.logWarning(
          String.format("%s %s", "Missing repository for project", selectedProject.getName()));
      return;
    }

    // build the commit history model, load it from the tree walk
    final CommitHistory commitHistory = ScoFactory.eINSTANCE.createCommitHistory();
    Repository repo = repositoryMapping.getRepository();
    RevWalk revWalk = new RevWalk(repo);
    ObjectId headObject = repo.resolve("HEAD");
    revWalk.markStart(revWalk.parseCommit(headObject));

    final Set<String> repositoryPaths =
        Collections.singleton(repositoryMapping.getRepoRelativePath(selectedProject));
    revWalk.setTreeFilter(PathFilterGroup.createFromStrings(repositoryPaths));

    for (RevCommit commit : revWalk) {
      String commitName = commit.getName();
      ArtifactCommit artifactCommit = ScoFactory.eINSTANCE.createArtifactCommit();
      artifactCommit.setCommitIdentifier(commitName);
      commitHistory.getCommitRecord().add(artifactCommit);
    }

    revWalk.dispose();

    // use the Git provider to find the file history, then converge into the model
    GitProvider provider = (GitProvider) RepositoryProvider.getProvider(selectedProject);
    IFileHistoryProvider fileHistoryProvider = provider.getFileHistoryProvider();
    IResource[] projectMembers = selectedProject.members();

    monitor.beginTask("Processing project resources", projectMembers.length);
    for (IResource resource : projectMembers) {
      processResource(resource, fileHistoryProvider, commitHistory, monitor);
      monitor.worked(1);
      if (monitor.isCanceled()) {
        return;
      }
    }

    // model complete with commit history and associated file sizes
    // write the resulting model to an SCO file
    // expecting preference to have no extension, so add it if necessary
    IPreferenceStore store = Activator.getDefault().getPreferenceStore();
    String fileName = store.getString(PreferenceConstants.P_FILENAME_SCO);
    if (fileName.endsWith(ICertWareConstants.SCO_EXTENSION) == false) {
      fileName = fileName + '.' + ICertWareConstants.SCO_EXTENSION;
    }

    // fully specify the path to the new file given the container project
    final String modelFile =
        selectedProject.getFullPath().toPortableString() + IPath.SEPARATOR + fileName;

    // create the resource in a workspace modify operation
    WorkspaceModifyOperation operation =
        new WorkspaceModifyOperation() {
          @Override
          protected void execute(IProgressMonitor progressMonitor) {
            try {
              // create a resource set and resource for a new file
              ResourceSet resourceSet = new ResourceSetImpl();
              URI fileURI = URI.createPlatformResourceURI(modelFile, true);
              Resource resource = resourceSet.createResource(fileURI);
              resource.getContents().add(commitHistory);

              // save the contents of the resource to the file system
              Map<Object, Object> options = new HashMap<Object, Object>();
              options.put(XMLResource.OPTION_ENCODING, FILE_ENCODING);
              resource.save(options);
            } catch (Exception e) {
              CertWareLog.logError(String.format("%s %s", "Saving SCO file", modelFile), e);
            }
          }
        };

    // modify the workspace
    try {
      operation.run(monitor);
    } catch (Exception e) {
      CertWareLog.logError(
          String.format("%s %s", "Modifying workspace for", selectedProject.getName()), e);
    }

    monitor.done();
  }