@Override protected void run () throws GitException { Repository repository = getRepository(); Ref currentRef = repository.getTags().get(tagName); if (currentRef == null) { throw new GitException.MissingObjectException(tagName, GitObjectType.TAG); } String fullName = currentRef.getName(); try { RefUpdate update = repository.updateRef(fullName); update.setRefLogMessage("tag deleted", false); update.setForceUpdate(true); Result deleteResult = update.delete(); switch (deleteResult) { case IO_FAILURE: case LOCK_FAILURE: case REJECTED: throw new GitException.RefUpdateException("Cannot delete tag " + tagName, GitRefUpdateResult.valueOf(deleteResult.name())); } } catch (IOException ex) { throw new GitException(ex); } }
@VisibleForTesting static void doRefUpdate(org.eclipse.jgit.lib.Repository jGitRepository, RevWalk revWalk, String ref, ObjectId commitId) throws IOException { if (ref.startsWith(Constants.R_TAGS)) { final Ref oldRef = jGitRepository.exactRef(ref); if (oldRef != null) { throw new StorageException("tag ref exists already: " + ref); } } final RefUpdate refUpdate = jGitRepository.updateRef(ref); refUpdate.setNewObjectId(commitId); final Result res = refUpdate.update(revWalk); switch (res) { case NEW: case FAST_FORWARD: // Expected break; default: throw new StorageException("unexpected refUpdate state: " + res); } }
@Override public void tagDelete(String name) throws GitException { try { Ref tagRef = repository.findRef(name); if (tagRef == null) { throw new GitException("Tag " + name + " not found. "); } RefUpdate updateRef = repository.updateRef(tagRef.getName()); updateRef.setRefLogMessage("tag deleted", false); updateRef.setForceUpdate(true); Result deleteResult = updateRef.delete(); if (deleteResult != Result.FORCED && deleteResult != Result.FAST_FORWARD) { throw new GitException(format(ERROR_TAG_DELETE, name, deleteResult)); } } catch (IOException exception) { throw new GitException(exception.getMessage(), exception); } }
@Override public RefUpdate.Result call() throws Exception { Ref ref = repo.exactRef(refName); afterReadRef.run(); ObjectId oldId; if (ref == null) { oldId = ObjectId.zeroId(); } else { oldId = ref.getObjectId(); int next = parse(rw, oldId); if (next >= value) { // a concurrent write updated the ref already to this or a higher value return RefUpdate.Result.NO_CHANGE; } } return store(repo, rw, oldId, value); }
private RefUpdate.Result store(Repository repo, RevWalk rw, @Nullable ObjectId oldId, int val) throws IOException { ObjectId newId; try (ObjectInserter ins = repo.newObjectInserter()) { newId = ins.insert(OBJ_BLOB, Integer.toString(val).getBytes(UTF_8)); ins.flush(); } RefUpdate ru = repo.updateRef(refName); if (oldId != null) { ru.setExpectedOldObjectId(oldId); } ru.disableRefLog(); ru.setNewObjectId(newId); ru.setForceUpdate(true); // Required for non-commitish updates. RefUpdate.Result result = ru.update(rw); if (refUpdated(result)) { gitRefUpdated.fire(projectName, ru, null); } return result; }
public static void deleteUserBranch( Repository repo, Project.NameKey project, GitReferenceUpdated gitRefUpdated, @Nullable IdentifiedUser user, PersonIdent refLogIdent, Account.Id accountId) throws IOException { String refName = RefNames.refsUsers(accountId); Ref ref = repo.exactRef(refName); if (ref == null) { return; } RefUpdate ru = repo.updateRef(refName); ru.setExpectedOldObjectId(ref.getObjectId()); ru.setNewObjectId(ObjectId.zeroId()); ru.setForceUpdate(true); ru.setRefLogIdent(refLogIdent); ru.setRefLogMessage("Delete Account", true); Result result = ru.delete(); if (result != Result.FORCED) { throw new IOException(String.format("Failed to delete ref %s: %s", refName, result.name())); } gitRefUpdated.fire(project, ru, user != null ? user.getAccount() : null); }
public void createUserBranch( Repository repo, ObjectInserter oi, ObjectId emptyTree, Account.Id accountId, Timestamp registeredOn) throws IOException { ObjectId id = createInitialEmptyCommit(oi, emptyTree, registeredOn); String refName = RefNames.refsUsers(accountId); RefUpdate ru = repo.updateRef(refName); ru.setExpectedOldObjectId(ObjectId.zeroId()); ru.setNewObjectId(id); ru.setRefLogIdent(serverIdent); ru.setRefLogMessage(CREATE_ACCOUNT_MSG, false); Result result = ru.update(); if (result != Result.NEW) { throw new IOException(String.format("Failed to update ref %s: %s", refName, result.name())); } }
@Test public void pushForMasterWithMessage() throws Exception { PushOneCommit.Result r = pushTo("refs/for/master/%m=my_test_message"); r.assertOkStatus(); r.assertChange(Change.Status.NEW, null); ChangeInfo ci = get(r.getChangeId(), MESSAGES, ALL_REVISIONS); Collection<ChangeMessageInfo> changeMessages = ci.messages; assertThat(changeMessages).hasSize(1); for (ChangeMessageInfo cm : changeMessages) { assertThat(cm.message).isEqualTo("Uploaded patch set 1.\nmy test message"); } Collection<RevisionInfo> revisions = ci.revisions.values(); assertThat(revisions).hasSize(1); for (RevisionInfo ri : revisions) { assertThat(ri.description).isEqualTo("my test message"); } }
@Test public void pushForMasterWithInvalidPercentEncodedMessage() throws Exception { PushOneCommit.Result r = pushTo("refs/for/master/%m=not_percent_decodable_%%oops%20"); r.assertOkStatus(); r.assertChange(Change.Status.NEW, null); ChangeInfo ci = get(r.getChangeId(), MESSAGES, ALL_REVISIONS); Collection<ChangeMessageInfo> changeMessages = ci.messages; assertThat(changeMessages).hasSize(1); for (ChangeMessageInfo cm : changeMessages) { assertThat(cm.message).isEqualTo("Uploaded patch set 1.\nnot percent decodable %%oops%20"); } Collection<RevisionInfo> revisions = ci.revisions.values(); assertThat(revisions).hasSize(1); for (RevisionInfo ri : revisions) { assertThat(ri.description).isEqualTo("not percent decodable %%oops%20"); } }
@Test public void pushNewPatchsetToRefsChanges() throws Exception { PushOneCommit.Result r = pushTo("refs/for/master"); r.assertOkStatus(); PushOneCommit push = pushFactory.create( db, admin.getIdent(), testRepo, PushOneCommit.SUBJECT, "b.txt", "anotherContent", r.getChangeId()); r = push.to("refs/changes/" + r.getChange().change().getId().get()); r.assertOkStatus(); }
@Test public void pushNewPatchsetToPatchSetLockedChange() throws Exception { PushOneCommit.Result r = pushTo("refs/for/master"); r.assertOkStatus(); PushOneCommit push = pushFactory.create( db, admin.getIdent(), testRepo, PushOneCommit.SUBJECT, "b.txt", "anotherContent", r.getChangeId()); revision(r).review(new ReviewInput().label("Patch-Set-Lock", 1)); r = push.to("refs/for/master"); r.assertErrorStatus("cannot add patch set to " + r.getChange().change().getChangeId() + "."); }
@Test public void createNewChangeForAllNotInTarget() throws Exception { enableCreateNewChangeForAllNotInTarget(); PushOneCommit push = pushFactory.create( db, admin.getIdent(), testRepo, PushOneCommit.SUBJECT, "a.txt", "content"); PushOneCommit.Result r = push.to("refs/for/master"); r.assertOkStatus(); push = pushFactory.create( db, admin.getIdent(), testRepo, PushOneCommit.SUBJECT, "b.txt", "anotherContent"); r = push.to("refs/for/master"); r.assertOkStatus(); gApi.projects().name(project.get()).branch("otherBranch").create(new BranchInput()); PushOneCommit.Result r2 = push.to("refs/for/otherBranch"); r2.assertOkStatus(); assertTwoChangesWithSameRevision(r); }
@Test public void pushChangeBasedOnChangeOfOtherUserWithCreateNewChangeForAllNotInTarget() throws Exception { enableCreateNewChangeForAllNotInTarget(); // create a change as admin PushOneCommit push = pushFactory.create( db, admin.getIdent(), testRepo, PushOneCommit.SUBJECT, "a.txt", "content"); PushOneCommit.Result r = push.to("refs/for/master"); r.assertOkStatus(); RevCommit commitChange1 = r.getCommit(); // create a second change as user (depends on the change from admin) TestRepository<?> userRepo = cloneProject(project, user); GitUtil.fetch(userRepo, r.getPatchSet().getRefName() + ":change"); userRepo.reset("change"); push = pushFactory.create( db, user.getIdent(), userRepo, PushOneCommit.SUBJECT, "b.txt", "anotherContent"); r = push.to("refs/for/master"); r.assertOkStatus(); // assert that no new change was created for the commit of the predecessor change assertThat(query(commitChange1.name())).hasSize(1); }
@Test public void pushSameCommitTwiceUsingMagicBranchBaseOption() throws Exception { grant(project, "refs/heads/master", Permission.PUSH); PushOneCommit.Result rBase = pushTo("refs/heads/master"); rBase.assertOkStatus(); gApi.projects().name(project.get()).branch("foo").create(new BranchInput()); PushOneCommit push = pushFactory.create( db, admin.getIdent(), testRepo, PushOneCommit.SUBJECT, "b.txt", "anotherContent"); PushOneCommit.Result r = push.to("refs/for/master"); r.assertOkStatus(); PushResult pr = GitUtil.pushHead(testRepo, "refs/for/foo%base=" + rBase.getCommit().name(), false, false); // BatchUpdate implementations differ in how they hook into progress monitors. We mostly just // care that there is a new change. assertThat(pr.getMessages()).containsMatch("changes: new: 1,( refs: 1)? done"); assertTwoChangesWithSameRevision(r); }
@Test public void pushSameCommitTwice() throws Exception { ProjectConfig config = projectCache.checkedGet(project).getConfig(); config.getProject().setCreateNewChangeForAllNotInTarget(InheritableBoolean.TRUE); saveProjectConfig(project, config); PushOneCommit push = pushFactory.create( db, admin.getIdent(), testRepo, PushOneCommit.SUBJECT, "a.txt", "content"); PushOneCommit.Result r = push.to("refs/for/master"); r.assertOkStatus(); push = pushFactory.create( db, admin.getIdent(), testRepo, PushOneCommit.SUBJECT, "b.txt", "anotherContent"); r = push.to("refs/for/master"); r.assertOkStatus(); assertPushRejected( pushHead(testRepo, "refs/for/master", false), "refs/for/master", "commit(s) already exists (as current patchset)"); }
@Test public void pushSameCommitTwiceWhenIndexFailed() throws Exception { ProjectConfig config = projectCache.checkedGet(project).getConfig(); config.getProject().setCreateNewChangeForAllNotInTarget(InheritableBoolean.TRUE); saveProjectConfig(project, config); PushOneCommit push = pushFactory.create( db, admin.getIdent(), testRepo, PushOneCommit.SUBJECT, "a.txt", "content"); PushOneCommit.Result r = push.to("refs/for/master"); r.assertOkStatus(); push = pushFactory.create( db, admin.getIdent(), testRepo, PushOneCommit.SUBJECT, "b.txt", "anotherContent"); r = push.to("refs/for/master"); r.assertOkStatus(); indexer.delete(r.getChange().getId()); assertPushRejected( pushHead(testRepo, "refs/for/master", false), "refs/for/master", "commit(s) already exists (as current patchset)"); }
@Test public void cantAutoCloseChangeAlreadyMergedToBranch() throws Exception { PushOneCommit.Result r1 = createChange(); Change.Id id1 = r1.getChange().getId(); PushOneCommit.Result r2 = createChange(); Change.Id id2 = r2.getChange().getId(); // Merge change 1 behind Gerrit's back. try (Repository repo = repoManager.openRepository(project)) { TestRepository<?> tr = new TestRepository<>(repo); tr.branch("refs/heads/master").update(r1.getCommit()); } assertThat(gApi.changes().id(id1.get()).info().status).isEqualTo(ChangeStatus.NEW); assertThat(gApi.changes().id(id2.get()).info().status).isEqualTo(ChangeStatus.NEW); r2 = amendChange(r2.getChangeId()); r2.assertOkStatus(); // Change 1 is still new despite being merged into the branch, because // ReceiveCommits only considers commits between the branch tip (which is // now the merged change 1) and the push tip (new patch set of change 2). assertThat(gApi.changes().id(id1.get()).info().status).isEqualTo(ChangeStatus.NEW); assertThat(gApi.changes().id(id2.get()).info().status).isEqualTo(ChangeStatus.NEW); }
@Test public void pushNewPatchsetOverridingStickyLabel() throws Exception { ProjectConfig cfg = projectCache.checkedGet(project).getConfig(); LabelType codeReview = Util.codeReview(); codeReview.setCopyMaxScore(true); cfg.getLabelSections().put(codeReview.getName(), codeReview); saveProjectConfig(cfg); PushOneCommit.Result r = pushTo("refs/for/master%l=Code-Review+2"); r.assertOkStatus(); PushOneCommit push = pushFactory.create( db, admin.getIdent(), testRepo, PushOneCommit.SUBJECT, "b.txt", "anotherContent", r.getChangeId()); r = push.to("refs/for/master%l=Code-Review+1"); r.assertOkStatus(); }
@Test public void mergedOptionWithNewCommitWithSameChangeIdFails() throws Exception { PushOneCommit.Result r = pushTo("refs/for/master"); r.assertOkStatus(); gApi.changes().id(r.getChangeId()).current().review(ReviewInput.approve()); gApi.changes().id(r.getChangeId()).current().submit(); RevCommit c2 = testRepo .amend(r.getCommit()) .message("New subject") .insertChangeId(r.getChangeId().substring(1)) .create(); testRepo.reset(c2); String ref = "refs/for/master%merged"; PushResult pr = pushHead(testRepo, ref, false); RemoteRefUpdate rru = pr.getRemoteUpdate(ref); assertThat(rru.getStatus()).isEqualTo(RemoteRefUpdate.Status.REJECTED_OTHER_REASON); assertThat(rru.getMessage()).contains("not merged into branch"); }
@Test public void publishCommentsOnPushOnlyPublishesDraftsOnUpdatedChanges() throws Exception { PushOneCommit.Result r1 = createChange(); PushOneCommit.Result r2 = createChange(); String id1 = r1.getChangeId(); String id2 = r2.getChangeId(); addDraft(id1, r1.getCommit().name(), newDraft(FILE_NAME, 1, "comment1")); CommentInfo c2 = addDraft(id2, r2.getCommit().name(), newDraft(FILE_NAME, 1, "comment2")); assertThat(getPublishedComments(id1)).isEmpty(); assertThat(getPublishedComments(id2)).isEmpty(); r2 = amendChange(id2, "refs/for/master%publish-comments"); assertThat(getPublishedComments(id1)).isEmpty(); assertThat(gApi.changes().id(id1).drafts()).hasSize(1); Collection<CommentInfo> cs2 = getPublishedComments(id2); assertThat(cs2.stream().map(c -> c.message)).containsExactly("comment2"); assertThat(cs2.stream().map(c -> c.id)).containsExactly(c2.id); assertThat(getLastMessage(id1)).doesNotMatch("[Cc]omment"); assertThat(getLastMessage(id2)).isEqualTo("Uploaded patch set 2.\n\n(1 comment)"); }
@Test public void publishCommentsOnPushWithPreference() throws Exception { PushOneCommit.Result r = createChange(); addDraft(r.getChangeId(), r.getCommit().name(), newDraft(FILE_NAME, 1, "comment1")); r = amendChange(r.getChangeId()); assertThat(getPublishedComments(r.getChangeId())).isEmpty(); GeneralPreferencesInfo prefs = gApi.accounts().id(admin.id.get()).getPreferences(); prefs.publishCommentsOnPush = true; gApi.accounts().id(admin.id.get()).setPreferences(prefs); r = amendChange(r.getChangeId()); assertThat(getPublishedComments(r.getChangeId()).stream().map(c -> c.message)) .containsExactly("comment1"); }
@Sandboxed @Test public void pushWithDraftOptionToExistingNewChangeGetsChangeEdit() throws Exception { String changeId = createChange().getChangeId(); EditInfoSubject.assertThat(getEdit(changeId)).isAbsent(); ChangeInfo changeInfo = gApi.changes().id(changeId).get(); ChangeStatus originalChangeStatus = changeInfo.status; PushOneCommit.Result result = amendChange(changeId, "refs/drafts/master"); result.assertOkStatus(); changeInfo = gApi.changes().id(changeId).get(); assertThat(changeInfo.status).isEqualTo(originalChangeStatus); assertThat(changeInfo.isPrivate).isNull(); assertThat(changeInfo.revisions).hasSize(1); EditInfoSubject.assertThat(getEdit(changeId)).isPresent(); }
private void setHEAD() throws Exception { try (ObjectInserter oi = repository.newObjectInserter()) { final CommitBuilder commit = new CommitBuilder(); commit.setTreeId(oi.insert(Constants.OBJ_TREE, new byte[] {})); commit.setAuthor(author); commit.setCommitter(committer); commit.setMessage("test\n"); ObjectId commitId = oi.insert(commit); final RefUpdate ref = repository.updateRef(Constants.HEAD); ref.setNewObjectId(commitId); Result result = ref.forceUpdate(); assertWithMessage(Constants.HEAD + " did not change: " + ref.getResult()) .that(result) .isAnyOf(Result.FAST_FORWARD, Result.FORCED, Result.NEW, Result.NO_CHANGE); } }
@Override public Ref call() throws GitAPIException, RefNotFoundException, CheckoutConflictException, InvalidRefNameException, RefAlreadyExistsException { this.checkCallable(); try { this.processOptions(); this.checkoutStartPoint(); RefUpdate update = this.getRepository().updateRef(Constants.HEAD); Result r = update.link(this.getBranchName()); if (!EnumSet.of(Result.NEW, Result.FORCED).contains(r)) { throw new JGitInternalException(MessageFormat.format( JGitText.get().checkoutUnexpectedResult, r.name())); } this.setCallable(false); return this.getRepository().getRef(Constants.HEAD); } catch (IOException e) { throw new JGitInternalException(e.getMessage(), e); } }
@Override public boolean onOptionsItemSelected(MenuItem item) { Log.i(TAG, "onOptionsItemSelected " + item); switch (item.getItemId()) { case android.R.id.home: return homewardsWith(this, manageRepoIntent(repo())); case DELETE_ID: try { RefUpdate update = repo().updateRef(tagRef.getName()); update.setForceUpdate(true); // update.setNewObjectId(head); // update.setForceUpdate(force || remote); Result result = update.delete(); Toast.makeText(this, "Tag deletion : " + result.name(), Toast.LENGTH_SHORT).show(); finish(); } catch (IOException e) { Log.e(TAG, "Couldn't delete " + revTag.getName(), e); throw new RuntimeException(e); } return true; } return super.onOptionsItemSelected(item); }
/** * Deletes the specified branch ref. * * @param repository * @param branch * @return true if successful */ public static boolean deleteBranchRef(Repository repository, String branch) { String branchName = branch; if (!branchName.startsWith(Constants.R_HEADS)) { branchName = Constants.R_HEADS + branch; } try { RefUpdate refUpdate = repository.updateRef(branchName, false); refUpdate.setForceUpdate(true); RefUpdate.Result result = refUpdate.delete(); switch (result) { case NEW: case FORCED: case NO_CHANGE: case FAST_FORWARD: return true; default: LOGGER.error(MessageFormat.format("{0} failed to delete to {1} returned result {2}", repository.getDirectory().getAbsolutePath(), branchName, result)); } } catch (Throwable t) { error(t, repository, "{0} failed to delete {1}", branchName); } return false; }
/** {@inheritDoc} */ public void prune(RemoteConfig repository) throws GitException { try (Repository gitRepo = getRepository()) { String remote = repository.getName(); String prefix = "refs/remotes/" + remote + "/"; Set<String> branches = listRemoteBranches(remote); for (Ref r : new ArrayList<>(gitRepo.getAllRefs().values())) { if (r.getName().startsWith(prefix) && !branches.contains(r.getName())) { // delete this ref RefUpdate update = gitRepo.updateRef(r.getName()); update.setRefLogMessage("remote branch pruned", false); update.setForceUpdate(true); Result res = update.delete(); } } } catch (URISyntaxException | IOException e) { throw new GitException(e); } }
@Override public Ref call() throws GitAPIException, RefNotFoundException, CheckoutConflictException, InvalidRefNameException, RefAlreadyExistsException { this.checkCallable(); try { this.processOptions(); this.checkoutStartPoint(); RefUpdate update = this.getRepository().updateRef(Constants.HEAD); Result r = update.link(this.getBranchName()); if (EnumSet.of(Result.NEW, Result.FORCED).contains(r) == false) { throw new JGitInternalException(MessageFormat.format( JGitText.get().checkoutUnexpectedResult, r.name())); } this.setCallable(false); return this.getRepository().getRef(Constants.HEAD); } catch (IOException e) { throw new JGitInternalException(e.getMessage(), e); } }
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { String stableBranch = "refs/remotes/origin/" + settings.get(CreateChangeBranchDialog.PROP_STABLE_BRANCH); String simpleBranchName = "changes/" + settings.get(CreateChangeBranchDialog.PROP_STABLE_BRANCH) + "/" + settings.get(CreateChangeBranchDialog.PROP_CHANGE_BRANCH_NAME); String changeBranch = "refs/heads/" + simpleBranchName; try { Ref stable = repository.getRef(stableBranch); AnyObjectId oid = stable.getLeaf().getObjectId(); RefUpdate refUpdate = repository.updateRef(changeBranch); refUpdate.setNewObjectId(oid); Result res = refUpdate.update(); switch (res) { case FAST_FORWARD: case NEW: case FORCED: case NO_CHANGE: case RENAMED: //we are fine; break; default: throw new RuntimeException("Cannot create change branch: " + res.toString()); } //configure for pull StoredConfig config = repository.getConfig(); config.setString("branch", simpleBranchName, "remote", "origin"); //$NON-NLS-1$//$NON-NLS-2$ config.setString("branch", simpleBranchName, "merge", "refs/heads/" + settings.get(CreateChangeBranchDialog.PROP_STABLE_BRANCH)); //$NON-NLS-1$//$NON-NLS-2$ config.setBoolean("branch", simpleBranchName, "rebase", true); //$NON-NLS-1$//$NON-NLS-2$ if ((Boolean)settings.get(CreateChangeBranchDialog.PROP_CHECKOUT)) { new SwitchToChangeBranchCommand().execute(event, repository, changeBranch); } } catch (Exception e) { RepositoryUtils.handleException(e); } }
private void updateRef() throws IOException, InterruptedException, RuntimeException, MissingObjectException, IncorrectObjectTypeException, CorruptObjectException { if (baseCommit != null && oursCommit.getTree().equals(baseCommit.getTree())) { // If the trees are identical, there is no change in the notes. // Avoid saving this commit as it has no new information. return; } int remainingLockFailureCalls = JgitUtils.MAX_LOCK_FAILURE_CALLS; RefUpdate refUpdate = JgitUtils.updateRef(repo, oursCommit, baseCommit, ref); for (;;) { Result result = refUpdate.update(); if (result == Result.LOCK_FAILURE) { if (--remainingLockFailureCalls > 0) { Thread.sleep(JgitUtils.SLEEP_ON_LOCK_FAILURE_MS); } else { throw new RuntimeException("Failed to lock the ref: " + ref); } } else if (result == Result.REJECTED) { RevCommit theirsCommit = revWalk.parseCommit(refUpdate.getOldObjectId()); NoteMap theirs = NoteMap.read(revWalk.getObjectReader(), theirsCommit); NoteMapMerger merger = new NoteMapMerger(repo); NoteMap merged = merger.merge(base, ours, theirs); RevCommit mergeCommit = createCommit(merged, author, "Merged note records\n", theirsCommit, oursCommit); refUpdate = JgitUtils.updateRef(repo, mergeCommit, theirsCommit, ref); remainingLockFailureCalls = JgitUtils.MAX_LOCK_FAILURE_CALLS; } else if (result == Result.IO_FAILURE) { throw new RuntimeException("Couldn't create notes because of IO_FAILURE"); } else { break; } } }
@VisibleForTesting static RetryerBuilder<RefUpdate.Result> retryerBuilder() { return RetryerBuilder.<RefUpdate.Result>newBuilder() .retryIfResult(Predicates.equalTo(RefUpdate.Result.LOCK_FAILURE)) .withWaitStrategy( WaitStrategies.join( WaitStrategies.exponentialWait(5, TimeUnit.SECONDS), WaitStrategies.randomWait(50, TimeUnit.MILLISECONDS))) .withStopStrategy(StopStrategies.stopAfterDelay(30, TimeUnit.SECONDS)); }
@VisibleForTesting RepoSequence( GitRepositoryManager repoManager, GitReferenceUpdated gitRefUpdated, Project.NameKey projectName, String name, Seed seed, int batchSize, Runnable afterReadRef, Retryer<RefUpdate.Result> retryer) { this.repoManager = checkNotNull(repoManager, "repoManager"); this.gitRefUpdated = checkNotNull(gitRefUpdated, "gitRefUpdated"); this.projectName = checkNotNull(projectName, "projectName"); checkArgument( name != null && !name.startsWith(REFS) && !name.startsWith(REFS_SEQUENCES.substring(REFS.length())), "name should be a suffix to follow \"refs/sequences/\", got: %s", name); this.refName = RefNames.REFS_SEQUENCES + name; this.seed = checkNotNull(seed, "seed"); checkArgument(batchSize > 0, "expected batchSize > 0, got: %s", batchSize); this.batchSize = batchSize; this.afterReadRef = checkNotNull(afterReadRef, "afterReadRef"); this.retryer = checkNotNull(retryer, "retryer"); counterLock = new ReentrantLock(true); }
@Override public RefUpdate.Result call() throws Exception { Ref ref = repo.exactRef(refName); afterReadRef.run(); ObjectId oldId; if (ref == null) { oldId = ObjectId.zeroId(); next = seed.get(); } else { oldId = ref.getObjectId(); next = parse(rw, oldId); } return store(repo, rw, oldId, next + count); }
@Test public void autoclose() throws Exception { // Create a change PushOneCommit.Result r = pushTo("refs/for/master"); r.assertOkStatus(); // Force push it, closing it String master = "refs/heads/master"; assertPushOk(pushHead(testRepo, master, false), master); // Attempt to push amended commit to same change String url = canonicalWebUrl.get() + "#/c/" + project.get() + "/+/" + r.getChange().getId(); r = amendChange(r.getChangeId(), "refs/for/master"); r.assertErrorStatus("change " + url + " closed"); }
@Test public void pushForMasterWithTopic() throws Exception { // specify topic in ref String topic = "my/topic"; PushOneCommit.Result r = pushTo("refs/for/master/" + topic); r.assertOkStatus(); r.assertChange(Change.Status.NEW, topic); // specify topic as option r = pushTo("refs/for/master%topic=" + topic); r.assertOkStatus(); r.assertChange(Change.Status.NEW, topic); }
@Test public void pushForMasterWithTopicOption() throws Exception { String topicOption = "topic=myTopic"; List<String> pushOptions = new ArrayList<>(); pushOptions.add(topicOption); PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo); push.setPushOptions(pushOptions); PushOneCommit.Result r = push.to("refs/for/master"); r.assertOkStatus(); r.assertChange(Change.Status.NEW, "myTopic"); r.assertPushOptions(pushOptions); }