Search in sources :

Example 56 with Repository

use of org.eclipse.jgit.lib.Repository in project camel by apache.

the class GitProducerTest method remoteAddTest.

@Test
public void remoteAddTest() throws Exception {
    Repository repository = getTestRepository();
    File gitDir = new File(gitLocalRepo, ".git");
    assertEquals(gitDir.exists(), true);
    Git git = new Git(repository);
    List<RemoteConfig> remoteConfigList = git.remoteList().call();
    assertTrue(remoteConfigList.size() == 0);
    Object result = template.requestBody("direct:remoteAdd", "");
    assertTrue(result instanceof RemoteConfig);
    RemoteConfig remoteConfig = (RemoteConfig) result;
    remoteConfigList = git.remoteList().call();
    assertTrue(remoteConfigList.size() == 1);
    assertEquals(remoteConfigList.get(0).getName(), remoteConfig.getName());
    assertEquals(remoteConfigList.get(0).getURIs(), remoteConfig.getURIs());
    git.close();
}
Also used : Repository(org.eclipse.jgit.lib.Repository) Git(org.eclipse.jgit.api.Git) RemoteConfig(org.eclipse.jgit.transport.RemoteConfig) File(java.io.File) Test(org.junit.Test)

Example 57 with Repository

use of org.eclipse.jgit.lib.Repository in project che by eclipse.

the class JGitConnection method commit.

@Override
public Revision commit(CommitParams params) throws GitException {
    try {
        // Check repository state
        RepositoryState repositoryState = repository.getRepositoryState();
        if (!repositoryState.canCommit()) {
            throw new GitException(format(MESSAGE_COMMIT_NOT_POSSIBLE, repositoryState.getDescription()));
        }
        if (params.isAmend() && !repositoryState.canAmend()) {
            throw new GitException(format(MESSAGE_COMMIT_AMEND_NOT_POSSIBLE, repositoryState.getDescription()));
        }
        // Check committer
        GitUser committer = getUser();
        if (committer == null) {
            throw new GitException("Committer can't be null");
        }
        String committerName = committer.getName();
        String committerEmail = committer.getEmail();
        if (committerName == null || committerEmail == null) {
            throw new GitException("Git user name and (or) email wasn't set", ErrorCodes.NO_COMMITTER_NAME_OR_EMAIL_DEFINED);
        }
        // Check commit message
        String message = params.getMessage();
        if (message == null) {
            throw new GitException("Message wasn't set");
        }
        Status status = status(StatusFormat.SHORT);
        List<String> specified = params.getFiles();
        List<String> staged = new ArrayList<>();
        staged.addAll(status.getAdded());
        staged.addAll(status.getChanged());
        staged.addAll(status.getRemoved());
        List<String> changed = new ArrayList<>(staged);
        changed.addAll(status.getModified());
        changed.addAll(status.getMissing());
        List<String> specifiedStaged = specified.stream().filter(path -> staged.stream().anyMatch(s -> s.startsWith(path))).collect(Collectors.toList());
        List<String> specifiedChanged = specified.stream().filter(path -> changed.stream().anyMatch(c -> c.startsWith(path))).collect(Collectors.toList());
        // Check that there are changes present for commit, if 'isAmend' is disabled
        if (!params.isAmend()) {
            // Check that there are staged changes present for commit, or any changes if 'isAll' is enabled
            if (status.isClean()) {
                throw new GitException("Nothing to commit, working directory clean");
            } else if (!params.isAll() && (specified.isEmpty() ? staged.isEmpty() : specifiedStaged.isEmpty())) {
                throw new GitException("No changes added to commit");
            }
        } else {
            /*
                By default Jgit doesn't allow to commit not changed specified paths. According to setAllowEmpty method documentation,
                setting this flag to true must allow such commit, but it won't because Jgit has a bug:
                https://bugs.eclipse.org/bugs/show_bug.cgi?id=510685. As a workaround, specified paths of the commit command will contain
                only changed and specified paths. If other changes are present, but the list of changed and specified paths is empty,
                throw exception to prevent committing other paths. TODO Remove this check when the bug will be fixed.
                */
            if (!specified.isEmpty() && !(params.isAll() ? changed.isEmpty() : staged.isEmpty()) && specifiedChanged.isEmpty()) {
                throw new GitException(format("Changes are present but not changed path%s specified for commit.", specified.size() > 1 ? "s were" : " was"));
            }
        }
        // TODO add 'setAllowEmpty(params.isAmend())' when https://bugs.eclipse.org/bugs/show_bug.cgi?id=510685 will be fixed
        CommitCommand commitCommand = getGit().commit().setCommitter(committerName, committerEmail).setAuthor(committerName, committerEmail).setMessage(message).setAll(params.isAll()).setAmend(params.isAmend());
        if (!params.isAll()) {
            // TODO change to 'specified.forEach(commitCommand::setOnly)' when https://bugs.eclipse.org/bugs/show_bug.cgi?id=510685 will be fixed. See description above.
            specifiedChanged.forEach(commitCommand::setOnly);
        }
        // Check if repository is configured with Gerrit Support
        String gerritSupportConfigValue = repository.getConfig().getString(ConfigConstants.CONFIG_GERRIT_SECTION, null, ConfigConstants.CONFIG_KEY_CREATECHANGEID);
        boolean isGerritSupportConfigured = gerritSupportConfigValue != null ? Boolean.valueOf(gerritSupportConfigValue) : false;
        commitCommand.setInsertChangeId(isGerritSupportConfigured);
        RevCommit result = commitCommand.call();
        GitUser gitUser = newDto(GitUser.class).withName(committerName).withEmail(committerEmail);
        return newDto(Revision.class).withBranch(getCurrentBranch()).withId(result.getId().getName()).withMessage(result.getFullMessage()).withCommitTime(MILLISECONDS.convert(result.getCommitTime(), SECONDS)).withCommitter(gitUser);
    } catch (GitAPIException exception) {
        throw new GitException(exception.getMessage(), exception);
    }
}
Also used : RebaseStatus(org.eclipse.che.api.git.shared.RebaseResponse.RebaseStatus) Status(org.eclipse.che.api.git.shared.Status) InvalidRefNameException(org.eclipse.jgit.api.errors.InvalidRefNameException) Arrays(java.util.Arrays) LsFilesParams(org.eclipse.che.api.git.params.LsFilesParams) RevObject(org.eclipse.jgit.revwalk.RevObject) RebaseResponse(org.eclipse.che.api.git.shared.RebaseResponse) RemoteConfig(org.eclipse.jgit.transport.RemoteConfig) RepositoryState(org.eclipse.jgit.lib.RepositoryState) PullParams(org.eclipse.che.api.git.params.PullParams) SshTransport(org.eclipse.jgit.transport.SshTransport) RevWalk(org.eclipse.jgit.revwalk.RevWalk) CloneParams(org.eclipse.che.api.git.params.CloneParams) RevTag(org.eclipse.jgit.revwalk.RevTag) ResetCommand(org.eclipse.jgit.api.ResetCommand) PathFilter(org.eclipse.jgit.treewalk.filter.PathFilter) Map(java.util.Map) URIish(org.eclipse.jgit.transport.URIish) PullResponse(org.eclipse.che.api.git.shared.PullResponse) TrueFileFilter(org.apache.commons.io.filefilter.TrueFileFilter) UnauthorizedException(org.eclipse.che.api.core.UnauthorizedException) RebaseStatus(org.eclipse.che.api.git.shared.RebaseResponse.RebaseStatus) GitConflictException(org.eclipse.che.api.git.exception.GitConflictException) EnumSet(java.util.EnumSet) TagCommand(org.eclipse.jgit.api.TagCommand) RepositoryCache(org.eclipse.jgit.lib.RepositoryCache) Result(org.eclipse.jgit.lib.RefUpdate.Result) GitAPIException(org.eclipse.jgit.api.errors.GitAPIException) TreeFilter(org.eclipse.jgit.treewalk.filter.TreeFilter) GitConnection(org.eclipse.che.api.git.GitConnection) RefSpec(org.eclipse.jgit.transport.RefSpec) SSLHandshakeException(javax.net.ssl.SSLHandshakeException) RebaseResult(org.eclipse.jgit.api.RebaseResult) CommitCommand(org.eclipse.jgit.api.CommitCommand) Config(org.eclipse.che.api.git.Config) RefUpdate(org.eclipse.jgit.lib.RefUpdate) OpenSshConfig(org.eclipse.jgit.transport.OpenSshConfig) Set(java.util.Set) Status(org.eclipse.che.api.git.shared.Status) Constants(org.eclipse.jgit.lib.Constants) MILLISECONDS(java.util.concurrent.TimeUnit.MILLISECONDS) TransportCommand(org.eclipse.jgit.api.TransportCommand) Nullable(org.eclipse.che.commons.annotation.Nullable) RevTree(org.eclipse.jgit.revwalk.RevTree) DirectoryFileFilter(org.apache.commons.io.filefilter.DirectoryFileFilter) RemoteUpdateParams(org.eclipse.che.api.git.params.RemoteUpdateParams) PersonIdent(org.eclipse.jgit.lib.PersonIdent) GitInvalidRefNameException(org.eclipse.che.api.git.exception.GitInvalidRefNameException) StatusFormat(org.eclipse.che.api.git.shared.StatusFormat) FileUtils(org.eclipse.jgit.util.FileUtils) Stream(java.util.stream.Stream) CredentialsLoader(org.eclipse.che.api.git.CredentialsLoader) Session(com.jcraft.jsch.Session) PushResult(org.eclipse.jgit.transport.PushResult) DirCache(org.eclipse.jgit.dircache.DirCache) GitRefNotFoundException(org.eclipse.che.api.git.exception.GitRefNotFoundException) FS(org.eclipse.jgit.util.FS) JSchException(com.jcraft.jsch.JSchException) Revision(org.eclipse.che.api.git.shared.Revision) FilenameFilter(java.io.FilenameFilter) RevCommit(org.eclipse.jgit.revwalk.RevCommit) LogCommand(org.eclipse.jgit.api.LogCommand) LogPage(org.eclipse.che.api.git.LogPage) Strings.isNullOrEmpty(com.google.common.base.Strings.isNullOrEmpty) PROVIDER_NAME(org.eclipse.che.api.git.shared.ProviderInfo.PROVIDER_NAME) ArrayList(java.util.ArrayList) LogParams(org.eclipse.che.api.git.params.LogParams) SetupUpstreamMode(org.eclipse.jgit.api.CreateBranchCommand.SetupUpstreamMode) ListMode(org.eclipse.jgit.api.ListBranchCommand.ListMode) ResetParams(org.eclipse.che.api.git.params.ResetParams) PushResponse(org.eclipse.che.api.git.shared.PushResponse) DiffCommitFile(org.eclipse.che.api.git.shared.DiffCommitFile) PushCommand(org.eclipse.jgit.api.PushCommand) RefAlreadyExistsException(org.eclipse.jgit.api.errors.RefAlreadyExistsException) PathFilterGroup(org.eclipse.jgit.treewalk.filter.PathFilterGroup) TreeWalk(org.eclipse.jgit.treewalk.TreeWalk) DiffPage(org.eclipse.che.api.git.DiffPage) ErrorCodes(org.eclipse.che.api.core.ErrorCodes) BranchListMode(org.eclipse.che.api.git.shared.BranchListMode) Tag(org.eclipse.che.api.git.shared.Tag) AddRequest(org.eclipse.che.api.git.shared.AddRequest) FileOutputStream(java.io.FileOutputStream) MergeResult(org.eclipse.che.api.git.shared.MergeResult) ProviderInfo(org.eclipse.che.api.git.shared.ProviderInfo) IOException(java.io.IOException) File(java.io.File) RefNotFoundException(org.eclipse.jgit.api.errors.RefNotFoundException) DiffParams(org.eclipse.che.api.git.params.DiffParams) DiffFormatter(org.eclipse.jgit.diff.DiffFormatter) ServerException(org.eclipse.che.api.core.ServerException) StoredConfig(org.eclipse.jgit.lib.StoredConfig) Repository(org.eclipse.jgit.lib.Repository) IOFileFilter(org.apache.commons.io.filefilter.IOFileFilter) PushParams(org.eclipse.che.api.git.params.PushParams) LineConsumerFactory(org.eclipse.che.api.core.util.LineConsumerFactory) FetchParams(org.eclipse.che.api.git.params.FetchParams) URISyntaxException(java.net.URISyntaxException) LoggerFactory(org.slf4j.LoggerFactory) GitRefAlreadyExistsException(org.eclipse.che.api.git.exception.GitRefAlreadyExistsException) AddCommand(org.eclipse.jgit.api.AddCommand) UserCredential(org.eclipse.che.api.git.UserCredential) CheckoutConflictException(org.eclipse.jgit.api.errors.CheckoutConflictException) NullOutputStream(org.eclipse.jgit.util.io.NullOutputStream) FetchResult(org.eclipse.jgit.transport.FetchResult) CommitParams(org.eclipse.che.api.git.params.CommitParams) ProxyAuthenticator(org.eclipse.che.commons.proxy.ProxyAuthenticator) ResetType(org.eclipse.jgit.api.ResetCommand.ResetType) RemoteAddParams(org.eclipse.che.api.git.params.RemoteAddParams) AUTHENTICATE_URL(org.eclipse.che.api.git.shared.ProviderInfo.AUTHENTICATE_URL) PosixFilePermission(java.nio.file.attribute.PosixFilePermission) GitException(org.eclipse.che.api.git.exception.GitException) ImmutableMap(com.google.common.collect.ImmutableMap) Collection(java.util.Collection) DtoFactory.newDto(org.eclipse.che.dto.server.DtoFactory.newDto) Collectors(java.util.stream.Collectors) String.format(java.lang.String.format) List(java.util.List) Branch(org.eclipse.che.api.git.shared.Branch) RemoteReference(org.eclipse.che.api.git.shared.RemoteReference) Ref(org.eclipse.jgit.lib.Ref) TagCreateParams(org.eclipse.che.api.git.params.TagCreateParams) Optional(java.util.Optional) ListBranchCommand(org.eclipse.jgit.api.ListBranchCommand) Pattern(java.util.regex.Pattern) RmCommand(org.eclipse.jgit.api.RmCommand) GitUrlUtils(org.eclipse.che.api.git.GitUrlUtils) Remote(org.eclipse.che.api.git.shared.Remote) System.lineSeparator(java.lang.System.lineSeparator) JSch(com.jcraft.jsch.JSch) UsernamePasswordCredentialsProvider(org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider) CanonicalTreeParser(org.eclipse.jgit.treewalk.CanonicalTreeParser) LineConsumer(org.eclipse.che.api.core.util.LineConsumer) CloneCommand(org.eclipse.jgit.api.CloneCommand) HashMap(java.util.HashMap) RebaseCommand(org.eclipse.jgit.api.RebaseCommand) LIST_ALL(org.eclipse.che.api.git.shared.BranchListMode.LIST_ALL) LIST_LOCAL(org.eclipse.che.api.git.shared.BranchListMode.LIST_LOCAL) FetchCommand(org.eclipse.jgit.api.FetchCommand) Inject(javax.inject.Inject) HashSet(java.util.HashSet) RmParams(org.eclipse.che.api.git.params.RmParams) LIST_REMOTE(org.eclipse.che.api.git.shared.BranchListMode.LIST_REMOTE) Files(com.google.common.io.Files) SshKeyProvider(org.eclipse.che.plugin.ssh.key.script.SshKeyProvider) SshSessionFactory(org.eclipse.jgit.transport.SshSessionFactory) ResolveMerger(org.eclipse.jgit.merge.ResolveMerger) BatchingProgressMonitor(org.eclipse.jgit.lib.BatchingProgressMonitor) AndTreeFilter(org.eclipse.jgit.treewalk.filter.AndTreeFilter) EmptyTreeIterator(org.eclipse.jgit.treewalk.EmptyTreeIterator) ObjectLoader(org.eclipse.jgit.lib.ObjectLoader) AddParams(org.eclipse.che.api.git.params.AddParams) GitUserResolver(org.eclipse.che.api.git.GitUserResolver) Logger(org.slf4j.Logger) Iterator(java.util.Iterator) CreateBranchCommand(org.eclipse.jgit.api.CreateBranchCommand) ConfigConstants(org.eclipse.jgit.lib.ConfigConstants) ShowFileContentResponse(org.eclipse.che.api.git.shared.ShowFileContentResponse) CheckoutCommand(org.eclipse.jgit.api.CheckoutCommand) ObjectId(org.eclipse.jgit.lib.ObjectId) TransportException(org.eclipse.jgit.api.errors.TransportException) OWNER_READ(java.nio.file.attribute.PosixFilePermission.OWNER_READ) RemoteRefUpdate(org.eclipse.jgit.transport.RemoteRefUpdate) LsRemoteCommand(org.eclipse.jgit.api.LsRemoteCommand) CheckoutParams(org.eclipse.che.api.git.params.CheckoutParams) TrackingRefUpdate(org.eclipse.jgit.transport.TrackingRefUpdate) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Git(org.eclipse.jgit.api.Git) DetachedHeadException(org.eclipse.jgit.api.errors.DetachedHeadException) DiffEntry(org.eclipse.jgit.diff.DiffEntry) OWNER_WRITE(java.nio.file.attribute.PosixFilePermission.OWNER_WRITE) GitUser(org.eclipse.che.api.git.shared.GitUser) Collections(java.util.Collections) JschConfigSessionFactory(org.eclipse.jgit.transport.JschConfigSessionFactory) SECONDS(java.util.concurrent.TimeUnit.SECONDS) GitException(org.eclipse.che.api.git.exception.GitException) ArrayList(java.util.ArrayList) RepositoryState(org.eclipse.jgit.lib.RepositoryState) GitUser(org.eclipse.che.api.git.shared.GitUser) GitAPIException(org.eclipse.jgit.api.errors.GitAPIException) Revision(org.eclipse.che.api.git.shared.Revision) CommitCommand(org.eclipse.jgit.api.CommitCommand) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 58 with Repository

use of org.eclipse.jgit.lib.Repository in project gerrit by GerritCodeReview.

the class RelatedChangesSorter method collectById.

private Map<String, PatchSetData> collectById(List<ChangeData> in) throws OrmException, IOException {
    Project.NameKey project = in.get(0).change().getProject();
    Map<String, PatchSetData> result = Maps.newHashMapWithExpectedSize(in.size() * 3);
    try (Repository repo = repoManager.openRepository(project);
        RevWalk rw = new RevWalk(repo)) {
        rw.setRetainBody(true);
        for (ChangeData cd : in) {
            checkArgument(cd.change().getProject().equals(project), "Expected change %s in project %s, found %s", cd.getId(), project, cd.change().getProject());
            for (PatchSet ps : cd.patchSets()) {
                String id = ps.getRevision().get();
                RevCommit c = rw.parseCommit(ObjectId.fromString(id));
                PatchSetData psd = PatchSetData.create(cd, ps, c);
                result.put(id, psd);
            }
        }
    }
    return result;
}
Also used : Project(com.google.gerrit.reviewdb.client.Project) Repository(org.eclipse.jgit.lib.Repository) PatchSet(com.google.gerrit.reviewdb.client.PatchSet) RevWalk(org.eclipse.jgit.revwalk.RevWalk) ChangeData(com.google.gerrit.server.query.change.ChangeData) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 59 with Repository

use of org.eclipse.jgit.lib.Repository in project gerrit by GerritCodeReview.

the class Revert method revert.

private Change.Id revert(BatchUpdate.Factory updateFactory, ChangeControl ctl, String message) throws OrmException, IOException, RestApiException, UpdateException {
    Change.Id changeIdToRevert = ctl.getChange().getId();
    PatchSet.Id patchSetId = ctl.getChange().currentPatchSetId();
    PatchSet patch = psUtil.get(db.get(), ctl.getNotes(), patchSetId);
    if (patch == null) {
        throw new ResourceNotFoundException(changeIdToRevert.toString());
    }
    Project.NameKey project = ctl.getProject().getNameKey();
    CurrentUser user = ctl.getUser();
    try (Repository git = repoManager.openRepository(project);
        ObjectInserter oi = git.newObjectInserter();
        ObjectReader reader = oi.newReader();
        RevWalk revWalk = new RevWalk(reader)) {
        RevCommit commitToRevert = revWalk.parseCommit(ObjectId.fromString(patch.getRevision().get()));
        if (commitToRevert.getParentCount() == 0) {
            throw new ResourceConflictException("Cannot revert initial commit");
        }
        Timestamp now = TimeUtil.nowTs();
        PersonIdent committerIdent = new PersonIdent(serverIdent, now);
        PersonIdent authorIdent = user.asIdentifiedUser().newCommitterIdent(now, committerIdent.getTimeZone());
        RevCommit parentToCommitToRevert = commitToRevert.getParent(0);
        revWalk.parseHeaders(parentToCommitToRevert);
        CommitBuilder revertCommitBuilder = new CommitBuilder();
        revertCommitBuilder.addParentId(commitToRevert);
        revertCommitBuilder.setTreeId(parentToCommitToRevert.getTree());
        revertCommitBuilder.setAuthor(authorIdent);
        revertCommitBuilder.setCommitter(authorIdent);
        Change changeToRevert = ctl.getChange();
        if (message == null) {
            message = MessageFormat.format(ChangeMessages.get().revertChangeDefaultMessage, changeToRevert.getSubject(), patch.getRevision().get());
        }
        ObjectId computedChangeId = ChangeIdUtil.computeChangeId(parentToCommitToRevert.getTree(), commitToRevert, authorIdent, committerIdent, message);
        revertCommitBuilder.setMessage(ChangeIdUtil.insertId(message, computedChangeId, true));
        Change.Id changeId = new Change.Id(seq.nextChangeId());
        ObjectId id = oi.insert(revertCommitBuilder);
        RevCommit revertCommit = revWalk.parseCommit(id);
        ChangeInserter ins = changeInserterFactory.create(changeId, revertCommit, ctl.getChange().getDest().get()).setTopic(changeToRevert.getTopic());
        ins.setMessage("Uploaded patch set 1.");
        Set<Account.Id> reviewers = new HashSet<>();
        reviewers.add(changeToRevert.getOwner());
        reviewers.addAll(approvalsUtil.getReviewers(db.get(), ctl.getNotes()).all());
        reviewers.remove(user.getAccountId());
        ins.setReviewers(reviewers);
        try (BatchUpdate bu = updateFactory.create(db.get(), project, user, now)) {
            bu.setRepository(git, revWalk, oi);
            bu.insertChange(ins);
            bu.addOp(changeId, new NotifyOp(ctl.getChange(), ins));
            bu.addOp(changeToRevert.getId(), new PostRevertedMessageOp(computedChangeId));
            bu.execute();
        }
        return changeId;
    } catch (RepositoryNotFoundException e) {
        throw new ResourceNotFoundException(changeIdToRevert.toString(), e);
    }
}
Also used : CurrentUser(com.google.gerrit.server.CurrentUser) CommitBuilder(org.eclipse.jgit.lib.CommitBuilder) Timestamp(java.sql.Timestamp) BatchUpdate(com.google.gerrit.server.update.BatchUpdate) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) ObjectReader(org.eclipse.jgit.lib.ObjectReader) ResourceNotFoundException(com.google.gerrit.extensions.restapi.ResourceNotFoundException) RevCommit(org.eclipse.jgit.revwalk.RevCommit) HashSet(java.util.HashSet) ObjectId(org.eclipse.jgit.lib.ObjectId) PatchSet(com.google.gerrit.reviewdb.client.PatchSet) Change(com.google.gerrit.reviewdb.client.Change) RepositoryNotFoundException(org.eclipse.jgit.errors.RepositoryNotFoundException) RevWalk(org.eclipse.jgit.revwalk.RevWalk) Project(com.google.gerrit.reviewdb.client.Project) Repository(org.eclipse.jgit.lib.Repository) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) PersonIdent(org.eclipse.jgit.lib.PersonIdent) GerritPersonIdent(com.google.gerrit.server.GerritPersonIdent) ObjectId(org.eclipse.jgit.lib.ObjectId)

Example 60 with Repository

use of org.eclipse.jgit.lib.Repository in project gerrit by GerritCodeReview.

the class WalkSorter method sortProject.

private List<PatchSetData> sortProject(Project.NameKey project, Collection<ChangeData> in) throws OrmException, IOException {
    try (Repository repo = repoManager.openRepository(project);
        RevWalk rw = new RevWalk(repo)) {
        rw.setRetainBody(retainBody);
        ListMultimap<RevCommit, PatchSetData> byCommit = byCommit(rw, in);
        if (byCommit.isEmpty()) {
            return ImmutableList.of();
        } else if (byCommit.size() == 1) {
            return ImmutableList.of(byCommit.values().iterator().next());
        }
        // Walk from all patch set SHA-1s, and terminate as soon as we've found
        // everything we're looking for. This is equivalent to just sorting the
        // list of commits by the RevWalk's configured order.
        //
        // Partially topo sort the list, ensuring no parent is emitted before a
        // direct child that is also in the input set. This preserves the stable,
        // expected sort in the case where many commits share the same timestamp,
        // e.g. a quick rebase. It also avoids JGit's topo sort, which slurps all
        // interesting commits at the beginning, which is a problem since we don't
        // know which commits to mark as uninteresting. Finding a reasonable set
        // of commits to mark uninteresting (the "rootmost" set) is at least as
        // difficult as just implementing this partial topo sort ourselves.
        //
        // (This is slightly less efficient than JGit's topo sort, which uses a
        // private in-degree field in RevCommit rather than multimaps. We assume
        // the input size is small enough that this is not an issue.)
        Set<RevCommit> commits = byCommit.keySet();
        ListMultimap<RevCommit, RevCommit> children = collectChildren(commits);
        ListMultimap<RevCommit, RevCommit> pending = MultimapBuilder.hashKeys().arrayListValues().build();
        Deque<RevCommit> todo = new ArrayDeque<>();
        RevFlag done = rw.newFlag("done");
        markStart(rw, commits);
        int expected = commits.size();
        int found = 0;
        RevCommit c;
        List<PatchSetData> result = new ArrayList<>(expected);
        while (found < expected && (c = rw.next()) != null) {
            if (!commits.contains(c)) {
                continue;
            }
            todo.clear();
            todo.add(c);
            int i = 0;
            while (!todo.isEmpty()) {
                // Sanity check: we can't pop more than N pending commits, otherwise
                // we have an infinite loop due to programmer error or something.
                checkState(++i <= commits.size(), "Too many pending steps while sorting %s", commits);
                RevCommit t = todo.removeFirst();
                if (t.has(done)) {
                    continue;
                }
                boolean ready = true;
                for (RevCommit child : children.get(t)) {
                    if (!child.has(done)) {
                        pending.put(child, t);
                        ready = false;
                    }
                }
                if (ready) {
                    found += emit(t, byCommit, result, done);
                    todo.addAll(pending.get(t));
                }
            }
        }
        return result;
    }
}
Also used : ArrayList(java.util.ArrayList) RevWalk(org.eclipse.jgit.revwalk.RevWalk) ArrayDeque(java.util.ArrayDeque) Repository(org.eclipse.jgit.lib.Repository) RevFlag(org.eclipse.jgit.revwalk.RevFlag) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Aggregations

Repository (org.eclipse.jgit.lib.Repository)326 IOException (java.io.IOException)103 RevWalk (org.eclipse.jgit.revwalk.RevWalk)102 Test (org.junit.Test)81 RevCommit (org.eclipse.jgit.revwalk.RevCommit)76 ObjectId (org.eclipse.jgit.lib.ObjectId)72 File (java.io.File)43 TestRepository (org.eclipse.jgit.junit.TestRepository)40 Change (com.google.gerrit.reviewdb.client.Change)39 OrmException (com.google.gwtorm.server.OrmException)39 Ref (org.eclipse.jgit.lib.Ref)35 Project (com.google.gerrit.reviewdb.client.Project)32 ArrayList (java.util.ArrayList)31 ObjectInserter (org.eclipse.jgit.lib.ObjectInserter)27 InMemoryRepository (org.eclipse.jgit.internal.storage.dfs.InMemoryRepository)26 PatchSet (com.google.gerrit.reviewdb.client.PatchSet)24 Map (java.util.Map)23 ConfigInvalidException (org.eclipse.jgit.errors.ConfigInvalidException)23 RepositoryModel (com.gitblit.models.RepositoryModel)20 AbstractDaemonTest (com.google.gerrit.acceptance.AbstractDaemonTest)20