Example usage for org.eclipse.jgit.lib Repository updateRef

List of usage examples for org.eclipse.jgit.lib Repository updateRef

Introduction

In this page you can find the example usage for org.eclipse.jgit.lib Repository updateRef.

Prototype

@NonNull
public RefUpdate updateRef(String ref) throws IOException 

Source Link

Document

Create a command to update, create or delete a ref in this repository.

Usage

From source file:com.google.gerrit.server.change.CherryPickChange.java

License:Apache License

private Change createNewChange(Repository git, RevWalk revWalk, Change.Key changeKey, Project.NameKey project,
        Ref destRef, CodeReviewCommit cherryPickCommit, RefControl refControl, IdentifiedUser identifiedUser,
        String topic) throws OrmException, InvalidChangeOperationException, IOException {
    Change change = new Change(changeKey, new Change.Id(db.get().nextChangeId()), identifiedUser.getAccountId(),
            new Branch.NameKey(project, destRef.getName()), TimeUtil.nowTs());
    change.setTopic(topic);//from w  w  w.  ja  v a  2 s .c  o  m
    ChangeInserter ins = changeInserterFactory.create(refControl.getProjectControl(), change, cherryPickCommit);
    PatchSet newPatchSet = ins.getPatchSet();

    CommitValidators commitValidators = commitValidatorsFactory.create(refControl, new NoSshInfo(), git);
    CommitReceivedEvent commitReceivedEvent = new CommitReceivedEvent(
            new ReceiveCommand(ObjectId.zeroId(), cherryPickCommit.getId(), newPatchSet.getRefName()),
            refControl.getProjectControl().getProject(), refControl.getRefName(), cherryPickCommit,
            identifiedUser);

    try {
        commitValidators.validateForGerritCommits(commitReceivedEvent);
    } catch (CommitValidationException e) {
        throw new InvalidChangeOperationException(e.getMessage());
    }

    final RefUpdate ru = git.updateRef(newPatchSet.getRefName());
    ru.setExpectedOldObjectId(ObjectId.zeroId());
    ru.setNewObjectId(cherryPickCommit);
    ru.disableRefLog();
    if (ru.update(revWalk) != RefUpdate.Result.NEW) {
        throw new IOException(String.format("Failed to create ref %s in %s: %s", newPatchSet.getRefName(),
                change.getDest().getParentKey().get(), ru.getResult()));
    }

    ins.insert();

    return change;
}

From source file:com.google.gerrit.server.change.CreateChange.java

License:Apache License

private static void updateRef(Repository git, RevWalk rw, RevCommit c, Change change, PatchSet newPatchSet)
        throws IOException {
    RefUpdate ru = git.updateRef(newPatchSet.getRefName());
    ru.setExpectedOldObjectId(ObjectId.zeroId());
    ru.setNewObjectId(c);// www  . j a  va  2s .  c  o  m
    ru.disableRefLog();
    if (ru.update(rw) != RefUpdate.Result.NEW) {
        throw new IOException(String.format("Failed to create ref %s in %s: %s", newPatchSet.getRefName(),
                change.getDest().getParentKey().get(), ru.getResult()));
    }
}

From source file:com.google.gerrit.server.edit.ChangeEditModifier.java

License:Apache License

private RefUpdate.Result update(Repository repo, IdentifiedUser me, String refName, RevWalk rw,
        ObjectId oldObjectId, ObjectId newEdit) throws IOException {
    RefUpdate ru = repo.updateRef(refName);
    ru.setExpectedOldObjectId(oldObjectId);
    ru.setNewObjectId(newEdit);/*from  w  w w  . j  ava2 s. c o  m*/
    ru.setRefLogIdent(getRefLogIdent(me));
    ru.setRefLogMessage("inline edit (amend)", false);
    ru.setForceUpdate(true);
    RefUpdate.Result res = ru.update(rw);
    if (res != RefUpdate.Result.NEW && res != RefUpdate.Result.FORCED) {
        throw new IOException("update failed: " + ru);
    }
    return res;
}

From source file:com.google.gerrit.server.git.VersionedMetaData.java

License:Apache License

/**
 * Open a batch of updates to the same metadata ref.
 * <p>//from  w  w w  .  j  a  va  2 s  .  com
 * This allows making multiple commits to a single metadata ref, at the end of
 * which is a single ref update. For batching together updates to multiple
 * refs (each consisting of one or more commits against their respective
 * refs), create the {@link MetaDataUpdate} with a {@link BatchRefUpdate}.
 * <p>
 * A ref update produced by this {@link BatchMetaDataUpdate} is only committed
 * if there is no associated {@link BatchRefUpdate}. As a result, the
 * configured ref updated event is not fired if there is an associated batch.
 *
 * @param update helper info about the update.
 * @throws IOException if the update failed.
 */
public BatchMetaDataUpdate openUpdate(final MetaDataUpdate update) throws IOException {
    final Repository db = update.getRepository();

    reader = db.newObjectReader();
    inserter = db.newObjectInserter();
    final RevWalk rw = new RevWalk(reader);
    final RevTree tree = revision != null ? rw.parseTree(revision) : null;
    newTree = readTree(tree);
    return new BatchMetaDataUpdate() {
        AnyObjectId src = revision;
        AnyObjectId srcTree = tree;

        @Override
        public void write(CommitBuilder commit) throws IOException {
            write(VersionedMetaData.this, commit);
        }

        private boolean doSave(VersionedMetaData config, CommitBuilder commit) throws IOException {
            DirCache nt = config.newTree;
            ObjectReader r = config.reader;
            ObjectInserter i = config.inserter;
            try {
                config.newTree = newTree;
                config.reader = reader;
                config.inserter = inserter;
                return config.onSave(commit);
            } catch (ConfigInvalidException e) {
                throw new IOException(
                        "Cannot update " + getRefName() + " in " + db.getDirectory() + ": " + e.getMessage(),
                        e);
            } finally {
                config.newTree = nt;
                config.reader = r;
                config.inserter = i;
            }
        }

        @Override
        public void write(VersionedMetaData config, CommitBuilder commit) throws IOException {
            if (!doSave(config, commit)) {
                return;
            }

            // Reuse tree from parent commit unless there are contents in newTree or
            // there is no tree for a parent commit.
            ObjectId res = newTree.getEntryCount() != 0 || srcTree == null ? newTree.writeTree(inserter)
                    : srcTree.copy();
            if (res.equals(srcTree) && !update.allowEmpty() && (commit.getTreeId() == null)) {
                // If there are no changes to the content, don't create the commit.
                return;
            }

            // If changes are made to the DirCache and those changes are written as
            // a commit and then the tree ID is set for the CommitBuilder, then
            // those previous DirCache changes will be ignored and the commit's
            // tree will be replaced with the ID in the CommitBuilder. The same is
            // true if you explicitly set tree ID in a commit and then make changes
            // to the DirCache; that tree ID will be ignored and replaced by that of
            // the tree for the updated DirCache.
            if (commit.getTreeId() == null) {
                commit.setTreeId(res);
            } else {
                // In this case, the caller populated the tree without using DirCache.
                res = commit.getTreeId();
            }

            if (src != null) {
                commit.addParentId(src);
            }

            if (update.insertChangeId()) {
                ObjectId id = ChangeIdUtil.computeChangeId(res, getRevision(), commit.getAuthor(),
                        commit.getCommitter(), commit.getMessage());
                commit.setMessage(ChangeIdUtil.insertId(commit.getMessage(), id));
            }

            src = inserter.insert(commit);
            srcTree = res;
        }

        @Override
        public RevCommit createRef(String refName) throws IOException {
            if (Objects.equals(src, revision)) {
                return revision;
            }
            return updateRef(ObjectId.zeroId(), src, refName);
        }

        @Override
        public void removeRef(String refName) throws IOException {
            RefUpdate ru = db.updateRef(refName);
            ru.setForceUpdate(true);
            if (revision != null) {
                ru.setExpectedOldObjectId(revision);
            }
            RefUpdate.Result result = ru.delete();
            switch (result) {
            case FORCED:
                update.fireGitRefUpdatedEvent(ru);
                return;
            default:
                throw new IOException(
                        "Cannot delete " + ru.getName() + " in " + db.getDirectory() + ": " + ru.getResult());
            }
        }

        @Override
        public RevCommit commit() throws IOException {
            return commitAt(revision);
        }

        @Override
        public RevCommit commitAt(ObjectId expected) throws IOException {
            if (Objects.equals(src, expected)) {
                return revision;
            }
            return updateRef(MoreObjects.firstNonNull(expected, ObjectId.zeroId()), src, getRefName());
        }

        @Override
        public void close() {
            newTree = null;

            rw.close();
            if (inserter != null) {
                inserter.close();
                inserter = null;
            }

            if (reader != null) {
                reader.close();
                reader = null;
            }
        }

        private RevCommit updateRef(AnyObjectId oldId, AnyObjectId newId, String refName) throws IOException {
            BatchRefUpdate bru = update.getBatch();
            if (bru != null) {
                bru.addCommand(new ReceiveCommand(oldId.toObjectId(), newId.toObjectId(), refName));
                inserter.flush();
                revision = rw.parseCommit(newId);
                return revision;
            }

            RefUpdate ru = db.updateRef(refName);
            ru.setExpectedOldObjectId(oldId);
            ru.setNewObjectId(src);
            ru.setRefLogIdent(update.getCommitBuilder().getAuthor());
            String message = update.getCommitBuilder().getMessage();
            if (message == null) {
                message = "meta data update";
            }
            try (BufferedReader reader = new BufferedReader(new StringReader(message))) {
                // read the subject line and use it as reflog message
                ru.setRefLogMessage("commit: " + reader.readLine(), true);
            }
            inserter.flush();
            RefUpdate.Result result = ru.update();
            switch (result) {
            case NEW:
            case FAST_FORWARD:
                revision = rw.parseCommit(ru.getNewObjectId());
                update.fireGitRefUpdatedEvent(ru);
                return revision;
            default:
                throw new IOException(
                        "Cannot update " + ru.getName() + " in " + db.getDirectory() + ": " + ru.getResult());
            }
        }
    };
}

From source file:com.google.gerrit.server.patch.AutoMerger.java

License:Apache License

private RevCommit commit(Repository repo, RevWalk rw, ObjectInserter ins, String refName, ObjectId tree,
        RevCommit merge) throws IOException {
    rw.parseHeaders(merge);//from   w ww.j a  v a  2  s.com
    // For maximum stability, choose a single ident using the committer time of
    // the input commit, using the server name and timezone.
    PersonIdent ident = new PersonIdent(gerritIdent, merge.getCommitterIdent().getWhen(),
            gerritIdent.getTimeZone());
    CommitBuilder cb = new CommitBuilder();
    cb.setAuthor(ident);
    cb.setCommitter(ident);
    cb.setTreeId(tree);
    cb.setMessage("Auto-merge of " + merge.name() + '\n');
    for (RevCommit p : merge.getParents()) {
        cb.addParentId(p);
    }
    ObjectId commitId;
    commitId = ins.insert(cb);
    if (save) {
        ins.flush();

        RefUpdate ru = repo.updateRef(refName);
        ru.setNewObjectId(commitId);
        ru.disableRefLog();
        ru.forceUpdate();
    }
    return rw.parseCommit(commitId);
}

From source file:com.google.gerrit.server.patch.PatchListLoader.java

License:Apache License

public static RevTree automerge(Repository repo, RevWalk rw, RevCommit b, ThreeWayMergeStrategy mergeStrategy,
        boolean save) throws IOException {
    String hash = b.name();//from  w  ww.j  a v  a2  s . c om
    String refName = RefNames.REFS_CACHE_AUTOMERGE + hash.substring(0, 2) + "/" + hash.substring(2);
    Ref ref = repo.getRefDatabase().exactRef(refName);
    if (ref != null && ref.getObjectId() != null) {
        return rw.parseTree(ref.getObjectId());
    }

    ResolveMerger m = (ResolveMerger) mergeStrategy.newMerger(repo, true);
    try (ObjectInserter ins = repo.newObjectInserter()) {
        DirCache dc = DirCache.newInCore();
        m.setDirCache(dc);
        m.setObjectInserter(new ObjectInserter.Filter() {
            @Override
            protected ObjectInserter delegate() {
                return ins;
            }

            @Override
            public void flush() {
            }

            @Override
            public void close() {
            }
        });

        boolean couldMerge;
        try {
            couldMerge = m.merge(b.getParents());
        } catch (IOException e) {
            // It is not safe to continue further down in this method as throwing
            // an exception most likely means that the merge tree was not created
            // and m.getMergeResults() is empty. This would mean that all paths are
            // unmerged and Gerrit UI would show all paths in the patch list.
            log.warn("Error attempting automerge " + refName, e);
            return null;
        }

        ObjectId treeId;
        if (couldMerge) {
            treeId = m.getResultTreeId();

        } else {
            RevCommit ours = b.getParent(0);
            RevCommit theirs = b.getParent(1);
            rw.parseBody(ours);
            rw.parseBody(theirs);
            String oursMsg = ours.getShortMessage();
            String theirsMsg = theirs.getShortMessage();

            String oursName = String.format("HEAD   (%s %s)", ours.abbreviate(6).name(),
                    oursMsg.substring(0, Math.min(oursMsg.length(), 60)));
            String theirsName = String.format("BRANCH (%s %s)", theirs.abbreviate(6).name(),
                    theirsMsg.substring(0, Math.min(theirsMsg.length(), 60)));

            MergeFormatter fmt = new MergeFormatter();
            Map<String, MergeResult<? extends Sequence>> r = m.getMergeResults();
            Map<String, ObjectId> resolved = new HashMap<>();
            for (Map.Entry<String, MergeResult<? extends Sequence>> entry : r.entrySet()) {
                MergeResult<? extends Sequence> p = entry.getValue();
                try (TemporaryBuffer buf = new TemporaryBuffer.LocalFile(null, 10 * 1024 * 1024)) {
                    fmt.formatMerge(buf, p, "BASE", oursName, theirsName, "UTF-8");
                    buf.close();

                    try (InputStream in = buf.openInputStream()) {
                        resolved.put(entry.getKey(), ins.insert(Constants.OBJ_BLOB, buf.length(), in));
                    }
                }
            }

            DirCacheBuilder builder = dc.builder();
            int cnt = dc.getEntryCount();
            for (int i = 0; i < cnt;) {
                DirCacheEntry entry = dc.getEntry(i);
                if (entry.getStage() == 0) {
                    builder.add(entry);
                    i++;
                    continue;
                }

                int next = dc.nextEntry(i);
                String path = entry.getPathString();
                DirCacheEntry res = new DirCacheEntry(path);
                if (resolved.containsKey(path)) {
                    // For a file with content merge conflict that we produced a result
                    // above on, collapse the file down to a single stage 0 with just
                    // the blob content, and a randomly selected mode (the lowest stage,
                    // which should be the merge base, or ours).
                    res.setFileMode(entry.getFileMode());
                    res.setObjectId(resolved.get(path));

                } else if (next == i + 1) {
                    // If there is exactly one stage present, shouldn't be a conflict...
                    res.setFileMode(entry.getFileMode());
                    res.setObjectId(entry.getObjectId());

                } else if (next == i + 2) {
                    // Two stages suggests a delete/modify conflict. Pick the higher
                    // stage as the automatic result.
                    entry = dc.getEntry(i + 1);
                    res.setFileMode(entry.getFileMode());
                    res.setObjectId(entry.getObjectId());

                } else { // 3 stage conflict, no resolve above
                    // Punt on the 3-stage conflict and show the base, for now.
                    res.setFileMode(entry.getFileMode());
                    res.setObjectId(entry.getObjectId());
                }
                builder.add(res);
                i = next;
            }
            builder.finish();
            treeId = dc.writeTree(ins);
        }
        ins.flush();

        if (save) {
            RefUpdate update = repo.updateRef(refName);
            update.setNewObjectId(treeId);
            update.disableRefLog();
            update.forceUpdate();
        }

        return rw.lookupTree(treeId);
    }
}

From source file:com.google.gerrit.server.project.CreateProject.java

License:Apache License

private void createEmptyCommits(Repository repo, Project.NameKey project, List<String> refs)
        throws IOException {
    try (ObjectInserter oi = repo.newObjectInserter()) {
        CommitBuilder cb = new CommitBuilder();
        cb.setTreeId(oi.insert(Constants.OBJ_TREE, new byte[] {}));
        cb.setAuthor(metaDataUpdateFactory.getUserPersonIdent());
        cb.setCommitter(serverIdent);/*from  w  w  w .j a  v a  2  s . co  m*/
        cb.setMessage("Initial empty repository\n");

        ObjectId id = oi.insert(cb);
        oi.flush();

        for (String ref : refs) {
            RefUpdate ru = repo.updateRef(ref);
            ru.setNewObjectId(id);
            Result result = ru.update();
            switch (result) {
            case NEW:
                referenceUpdated.fire(project, ru, ReceiveCommand.Type.CREATE);
                break;
            default: {
                throw new IOException(String.format("Failed to create ref \"%s\": %s", ref, result.name()));
            }
            }
        }
    } catch (IOException e) {
        log.error("Cannot create empty commit for " + project.get(), e);
        throw e;
    }
}

From source file:com.google.gerrit.server.project.DeleteRef.java

License:Apache License

private void deleteSingleRef(Repository r) throws IOException, ResourceConflictException {
    String ref = refsToDelete.get(0);
    if (prefix != null && !ref.startsWith(prefix)) {
        ref = prefix + ref;//from w w w .  j a  va2 s . co m
    }
    RefUpdate.Result result;
    RefUpdate u = r.updateRef(ref);
    u.setExpectedOldObjectId(r.exactRef(ref).getObjectId());
    u.setNewObjectId(ObjectId.zeroId());
    u.setForceUpdate(true);
    refDeletionValidator.validateRefOperation(resource.getName(), identifiedUser.get(), u);
    int remainingLockFailureCalls = MAX_LOCK_FAILURE_CALLS;
    for (;;) {
        try {
            result = u.delete();
        } catch (LockFailedException e) {
            result = RefUpdate.Result.LOCK_FAILURE;
        } catch (IOException e) {
            log.error("Cannot delete " + ref, e);
            throw e;
        }
        if (result == RefUpdate.Result.LOCK_FAILURE && --remainingLockFailureCalls > 0) {
            try {
                Thread.sleep(SLEEP_ON_LOCK_FAILURE_MS);
            } catch (InterruptedException ie) {
                // ignore
            }
        } else {
            break;
        }
    }

    switch (result) {
    case NEW:
    case NO_CHANGE:
    case FAST_FORWARD:
    case FORCED:
        referenceUpdated.fire(resource.getNameKey(), u, ReceiveCommand.Type.DELETE,
                identifiedUser.get().getAccount());
        break;

    case REJECTED_CURRENT_BRANCH:
        log.error("Cannot delete " + ref + ": " + result.name());
        throw new ResourceConflictException("cannot delete current branch");

    case IO_FAILURE:
    case LOCK_FAILURE:
    case NOT_ATTEMPTED:
    case REJECTED:
    case RENAMED:
    default:
        log.error("Cannot delete " + ref + ": " + result.name());
        throw new ResourceConflictException("cannot delete: " + result.name());
    }
}

From source file:com.google.gerrit.server.project.DeleteRef.java

License:Apache License

private ReceiveCommand createDeleteCommand(ProjectResource project, Repository r, String refName)
        throws OrmException, IOException, ResourceConflictException {
    Ref ref = r.getRefDatabase().getRef(refName);
    ReceiveCommand command;//  w ww .j  av a2s  .com
    if (ref == null) {
        command = new ReceiveCommand(ObjectId.zeroId(), ObjectId.zeroId(), refName);
        command.setResult(Result.REJECTED_OTHER_REASON,
                "it doesn't exist or you do not have permission to delete it");
        return command;
    }
    command = new ReceiveCommand(ref.getObjectId(), ObjectId.zeroId(), ref.getName());

    if (!project.getControl().controlForRef(refName).canDelete()) {
        command.setResult(Result.REJECTED_OTHER_REASON,
                "it doesn't exist or you do not have permission to delete it");
    }

    if (!refName.startsWith(R_TAGS)) {
        Branch.NameKey branchKey = new Branch.NameKey(project.getNameKey(), ref.getName());
        if (!queryProvider.get().setLimit(1).byBranchOpen(branchKey).isEmpty()) {
            command.setResult(Result.REJECTED_OTHER_REASON, "it has open changes");
        }
    }

    RefUpdate u = r.updateRef(refName);
    u.setForceUpdate(true);
    u.setExpectedOldObjectId(r.exactRef(refName).getObjectId());
    u.setNewObjectId(ObjectId.zeroId());
    refDeletionValidator.validateRefOperation(project.getName(), identifiedUser.get(), u);
    return command;
}

From source file:com.google.gerrit.server.project.PerformCreateProject.java

License:Apache License

public Project createProject() throws ProjectCreationFailedException {
    validateParameters();/*from   w  w w.j  av  a 2  s  .  c o m*/
    final Project.NameKey nameKey = createProjectArgs.getProject();
    try {
        final String head = createProjectArgs.permissionsOnly ? RefNames.REFS_CONFIG
                : createProjectArgs.branch.get(0);
        final Repository repo = repoManager.createRepository(nameKey);
        try {
            NewProjectCreatedListener.Event event = new NewProjectCreatedListener.Event() {
                @Override
                public String getProjectName() {
                    return nameKey.get();
                }

                @Override
                public String getHeadName() {
                    return head;
                }
            };
            for (NewProjectCreatedListener l : createdListener) {
                try {
                    l.onNewProjectCreated(event);
                } catch (RuntimeException e) {
                    log.warn("Failure in NewProjectCreatedListener", e);
                }
            }

            final RefUpdate u = repo.updateRef(Constants.HEAD);
            u.disableRefLog();
            u.link(head);

            createProjectConfig();

            if (!createProjectArgs.permissionsOnly && createProjectArgs.createEmptyCommit) {
                createEmptyCommits(repo, nameKey, createProjectArgs.branch);
            }

            return projectCache.get(nameKey).getProject();
        } finally {
            repo.close();
        }
    } catch (RepositoryCaseMismatchException e) {
        throw new ProjectCreationFailedException(
                "Cannot create " + nameKey.get() + " because the name is already occupied by another project."
                        + " The other project has the same name, only spelled in a" + " different case.",
                e);
    } catch (RepositoryNotFoundException badName) {
        throw new ProjectCreationFailedException("Cannot create " + nameKey, badName);
    } catch (IllegalStateException err) {
        try {
            final Repository repo = repoManager.openRepository(nameKey);
            try {
                if (repo.getObjectDatabase().exists()) {
                    throw new ProjectCreationFailedException("project \"" + nameKey + "\" exists");
                }
                throw err;
            } finally {
                repo.close();
            }
        } catch (IOException ioErr) {
            final String msg = "Cannot create " + nameKey;
            log.error(msg, err);
            throw new ProjectCreationFailedException(msg, ioErr);
        }
    } catch (Exception e) {
        final String msg = "Cannot create " + nameKey;
        log.error(msg, e);
        throw new ProjectCreationFailedException(msg, e);
    }
}