private PushResult pushVia(Transport tn) throws IOException, NotSupportedException, TransportException, PermissionBackendException { tn.applyConfig(config); tn.setCredentialsProvider(credentialsProvider); List<RemoteRefUpdate> todo = generateUpdates(tn); if (todo.isEmpty()) { // If we have no commands selected, we have nothing to do. // Calling JGit at this point would just redo the work we // already did, and come up with the same answer. Instead // send back an empty result. return new PushResult(); } repLog.info("Push to " + uri + " references: " + todo); return tn.push(NullProgressMonitor.INSTANCE, todo); }
private void updateReferenceWithNameChange( Repository repository, String currentRefName, ObjectId currentObjectId, String newRefName, ObjectId targetObjectId, Timestamp timestamp) throws IOException { BatchRefUpdate batchRefUpdate = repository.getRefDatabase().newBatchUpdate(); batchRefUpdate.addCommand(new ReceiveCommand(ObjectId.zeroId(), targetObjectId, newRefName)); batchRefUpdate.addCommand( new ReceiveCommand(currentObjectId, ObjectId.zeroId(), currentRefName)); batchRefUpdate.setRefLogMessage("rebase edit", false); batchRefUpdate.setRefLogIdent(getRefLogIdent(timestamp)); try (RevWalk revWalk = new RevWalk(repository)) { batchRefUpdate.execute(revWalk, NullProgressMonitor.INSTANCE); } for (ReceiveCommand cmd : batchRefUpdate.getCommands()) { if (cmd.getResult() != ReceiveCommand.Result.OK) { throw new IOException("failed: " + cmd); } } }
public void unstarAll(Project.NameKey project, Change.Id changeId) throws OrmException { try (Repository repo = repoManager.openRepository(allUsers); RevWalk rw = new RevWalk(repo)) { BatchRefUpdate batchUpdate = repo.getRefDatabase().newBatchUpdate(); batchUpdate.setAllowNonFastForwards(true); batchUpdate.setRefLogIdent(serverIdent); batchUpdate.setRefLogMessage("Unstar change " + changeId.get(), true); for (Account.Id accountId : byChangeFromIndex(changeId).keySet()) { String refName = RefNames.refsStarredChanges(changeId, accountId); Ref ref = repo.getRefDatabase().getRef(refName); batchUpdate.addCommand(new ReceiveCommand(ref.getObjectId(), ObjectId.zeroId(), refName)); } batchUpdate.execute(rw, NullProgressMonitor.INSTANCE); for (ReceiveCommand command : batchUpdate.getCommands()) { if (command.getResult() != ReceiveCommand.Result.OK) { throw new IOException( String.format( "Unstar change %d failed, ref %s could not be deleted: %s", changeId.get(), command.getRefName(), command.getResult())); } } indexer.index(dbProvider.get(), project, changeId); } catch (IOException e) { throw new OrmException(String.format("Unstar change %d failed", changeId.get()), e); } }
private void executeNoteDbUpdate(RevWalk rw, ObjectInserter ins, BatchRefUpdate bru) throws IOException { if (bru.getCommands().isEmpty()) { logDebug("No commands, skipping flush and ref update"); return; } ins.flush(); bru.setAllowNonFastForwards(true); bru.execute(rw, NullProgressMonitor.INSTANCE); for (ReceiveCommand cmd : bru.getCommands()) { // TODO(dborowitz): LOCK_FAILURE for NoteDb primary should be retried. if (cmd.getResult() != ReceiveCommand.Result.OK) { throw new IOException("Update failed: " + bru); } } }
public void deleteAllDraftsFromAllUsers(Change.Id changeId) throws IOException { try (Repository repo = repoManager.openRepository(allUsers); RevWalk rw = new RevWalk(repo)) { BatchRefUpdate bru = repo.getRefDatabase().newBatchUpdate(); for (Ref ref : getDraftRefs(repo, changeId)) { bru.addCommand(new ReceiveCommand(ref.getObjectId(), ObjectId.zeroId(), ref.getName())); } bru.setRefLogMessage("Delete drafts from NoteDb", false); bru.execute(rw, NullProgressMonitor.INSTANCE); for (ReceiveCommand cmd : bru.getCommands()) { if (cmd.getResult() != ReceiveCommand.Result.OK) { throw new IOException( String.format( "Failed to delete draft comment ref %s at %s: %s (%s)", cmd.getRefName(), cmd.getOldId(), cmd.getResult(), cmd.getMessage())); } } } }
@Override public void to(Path path) throws Git.Err { LOG.info(() -> String.format("Cloning %s into %s...", url, path.toString())); CloneCommand cloner = org.eclipse.jgit.api.Git.cloneRepository() .setURI(url) .setCredentialsProvider(new GitCredentialsProvider( CredentialHandlers.handlerMap() )) .setProgressMonitor( enableOutput ? new TextProgressMonitor() : NullProgressMonitor.INSTANCE ) .setDirectory(path.toFile()); branchName.ifPresent(cloner::setBranch); try { cloner.call(); } catch (GitAPIException e) { throw new Git.Err(url, path.toString(), e); } }
/** * Show changes between index and working tree. * * @param formatter diff formatter * @return list of diff entries * @throws IOException if any i/o errors occurs */ private List<DiffEntry> indexToWorkingTree(DiffFormatter formatter) throws IOException { DirCache dirCache = null; ObjectReader reader = repository.newObjectReader(); List<DiffEntry> diff; try { dirCache = repository.lockDirCache(); DirCacheIterator iterA = new DirCacheIterator(dirCache); FileTreeIterator iterB = new FileTreeIterator(repository); // Seems bug in DiffFormatter when work with working. Disable detect // renames by formatter and do it later. formatter.setDetectRenames(false); diff = formatter.scan(iterA, iterB); if (!params.isNoRenames()) { // Detect renames. RenameDetector renameDetector = createRenameDetector(); ContentSource.Pair sourcePairReader = new ContentSource.Pair(ContentSource.create(reader), ContentSource.create(iterB)); renameDetector.addAll(diff); diff = renameDetector.compute(sourcePairReader, NullProgressMonitor.INSTANCE); } } finally { reader.close(); if (dirCache != null) { dirCache.unlock(); } } return diff; }
/** * Show changes between specified revision and working tree. * * @param commitId id of commit * @param formatter diff formatter * @return list of diff entries * @throws IOException if any i/o errors occurs */ private List<DiffEntry> commitToWorkingTree(String commitId, DiffFormatter formatter) throws IOException { ObjectId commitA = repository.resolve(commitId); if (commitA == null) { File heads = new File(repository.getWorkTree().getPath() + "/.git/refs/heads"); if (heads.exists() && heads.list().length == 0) { return Collections.emptyList(); } throw new IllegalArgumentException("Invalid commit id " + commitId); } RevTree treeA; try (RevWalk revWalkA = new RevWalk(repository)) { treeA = revWalkA.parseTree(commitA); } List<DiffEntry> diff; try (ObjectReader reader = repository.newObjectReader()) { CanonicalTreeParser iterA = new CanonicalTreeParser(); iterA.reset(reader, treeA); FileTreeIterator iterB = new FileTreeIterator(repository); // Seems bug in DiffFormatter when work with working. Disable detect // renames by formatter and do it later. formatter.setDetectRenames(false); diff = formatter.scan(iterA, iterB); if (!params.isNoRenames()) { // Detect renames. RenameDetector renameDetector = createRenameDetector(); ContentSource.Pair sourcePairReader = new ContentSource.Pair(ContentSource.create(reader), ContentSource.create(iterB)); renameDetector.addAll(diff); diff = renameDetector.compute(sourcePairReader, NullProgressMonitor.INSTANCE); } } return diff; }
private void executeRefUpdates(boolean dryrun) throws IOException, RestApiException { if (getRefUpdates().isEmpty()) { logDebug("No ref updates to execute"); return; } // May not be opened if the caller added ref updates but no new objects. // TODO(dborowitz): Really? initRepository(); batchRefUpdate = repoView.getRepository().getRefDatabase().newBatchUpdate(); batchRefUpdate.setPushCertificate(pushCert); batchRefUpdate.setRefLogMessage(refLogMessage, true); batchRefUpdate.setAllowNonFastForwards(true); repoView.getCommands().addTo(batchRefUpdate); if (user.isIdentifiedUser()) { batchRefUpdate.setRefLogIdent(user.asIdentifiedUser().newRefLogIdent(when, tz)); } logDebug("Executing batch of {} ref updates", batchRefUpdate.getCommands().size()); if (dryrun) { return; } // Force BatchRefUpdate to read newly referenced objects using a new RevWalk, rather than one // that might have access to unflushed objects. try (RevWalk updateRw = new RevWalk(repoView.getRepository())) { batchRefUpdate.execute(updateRw, NullProgressMonitor.INSTANCE); } boolean ok = true; for (ReceiveCommand cmd : batchRefUpdate.getCommands()) { if (cmd.getResult() != ReceiveCommand.Result.OK) { ok = false; break; } } if (!ok) { throw new RestApiException("BatchRefUpdate failed: " + batchRefUpdate); } }
private void allowSubmoduleSubscription(Branch.NameKey subbranch, Branch.NameKey superBranch) throws OrmException { try (Repository git = mgr.openRepository(subbranch.getParentKey()); RevWalk rw = new RevWalk(git)) { BatchRefUpdate bru = git.getRefDatabase().newBatchUpdate(); try (MetaDataUpdate md = new MetaDataUpdate(GitReferenceUpdated.DISABLED, subbranch.getParentKey(), git, bru)) { md.getCommitBuilder().setAuthor(serverUser); md.getCommitBuilder().setCommitter(serverUser); md.setMessage("Added superproject subscription during upgrade"); ProjectConfig pc = ProjectConfig.read(md); SubscribeSection s = null; for (SubscribeSection s1 : pc.getSubscribeSections(subbranch)) { if (s1.getProject().equals(superBranch.getParentKey())) { s = s1; } } if (s == null) { s = new SubscribeSection(superBranch.getParentKey()); pc.addSubscribeSection(s); } RefSpec newRefSpec = new RefSpec(subbranch.get() + ":" + superBranch.get()); if (!s.getMatchingRefSpecs().contains(newRefSpec)) { // For the migration we use only exact RefSpecs, we're not trying to // generalize it. s.addMatchingRefSpec(newRefSpec); } pc.commit(md); } bru.execute(rw, NullProgressMonitor.INSTANCE); } catch (ConfigInvalidException | IOException e) { throw new OrmException(e); } }
private void execute(Repository git, BatchRefUpdate bru) throws IOException { try (RevWalk rw = new RevWalk(git)) { bru.execute(rw, NullProgressMonitor.INSTANCE); } for (ReceiveCommand cmd : bru.getCommands()) { if (cmd.getResult() != ReceiveCommand.Result.OK) { throw new IOException("Failed to initialize " + allProjectsName + " refs:\n" + bru); } } }
@Override protected void executeCommands() { if (getRepository().getRefDatabase() instanceof RefTreeDatabase) { List<ReceiveCommand> toApply = filterCommands(ReceiveCommand.Result.NOT_ATTEMPTED); if (toApply.isEmpty()) { return; } final BatchRefUpdate batch = ((RefTreeDatabase) getRepository().getRefDatabase()).getBootstrap().newBatchUpdate(); batch.setAllowNonFastForwards(true); batch.setAtomic(false); batch.setRefLogIdent(getRefLogIdent()); batch.setRefLogMessage("push", true); //$NON-NLS-1$ batch.addCommand(toApply); try { batch.setPushCertificate(getPushCertificate()); batch.execute(getRevWalk(), NullProgressMonitor.INSTANCE); } catch (IOException err) { for (ReceiveCommand cmd : toApply) { if (cmd.getResult() == ReceiveCommand.Result.NOT_ATTEMPTED) { cmd.setResult(ReceiveCommand.Result.REJECTED_OTHER_REASON, MessageFormat.format( JGitText.get().lockError, err.getMessage())); } } } } else { super.executeCommands(); } }
@Override protected void run() throws GitException { Repository repository = getRepository(); DiffFormatter formatter = new DiffFormatter(out); formatter.setRepository(repository); ObjectReader or = null; String workTreePath = repository.getWorkTree().getAbsolutePath(); try { Collection<PathFilter> pathFilters = Utils.getPathFilters(repository.getWorkTree(), roots); if (!pathFilters.isEmpty()) { formatter.setPathFilter(PathFilterGroup.create(pathFilters)); } if (repository.getConfig().get(WorkingTreeOptions.KEY).getAutoCRLF() != CoreConfig.AutoCRLF.FALSE) { // work-around for autocrlf formatter.setDiffComparator(new AutoCRLFComparator()); } or = repository.newObjectReader(); AbstractTreeIterator firstTree = getIterator(firstCommit, or); AbstractTreeIterator secondTree = getIterator(secondCommit, or); List<DiffEntry> diffEntries; if (secondTree instanceof WorkingTreeIterator) { // remote when fixed in JGit, see ExportDiffTest.testDiffRenameDetectionProblem formatter.setDetectRenames(false); diffEntries = formatter.scan(firstTree, secondTree); formatter.setDetectRenames(true); RenameDetector detector = formatter.getRenameDetector(); detector.reset(); detector.addAll(diffEntries); diffEntries = detector.compute(new ContentSource.Pair(ContentSource.create(or), ContentSource.create((WorkingTreeIterator) secondTree)), NullProgressMonitor.INSTANCE); } else { formatter.setDetectRenames(true); diffEntries = formatter.scan(firstTree, secondTree); } for (DiffEntry ent : diffEntries) { if (monitor.isCanceled()) { break; } listener.notifyFile(new File(workTreePath + File.separator + ent.getNewPath()), ent.getNewPath()); formatter.format(ent); } formatter.flush(); } catch (IOException ex) { throw new GitException(ex); } finally { if (or != null) { or.release(); } formatter.release(); } }
/** * Fetches each bundle into a newly cloned repository, then it applies the bundle, and returns the * resulting tree id. * * <p>Omits NoteDb meta refs. */ protected Map<Branch.NameKey, ObjectId> fetchFromBundles(BinaryResult bundles) throws Exception { assertThat(bundles.getContentType()).isEqualTo("application/x-zip"); FileSystem fs = Jimfs.newFileSystem(); Path previewPath = fs.getPath("preview.zip"); try (OutputStream out = Files.newOutputStream(previewPath)) { bundles.writeTo(out); } Map<Branch.NameKey, ObjectId> ret = new HashMap<>(); try (FileSystem zipFs = FileSystems.newFileSystem(previewPath, null); DirectoryStream<Path> dirStream = Files.newDirectoryStream(Iterables.getOnlyElement(zipFs.getRootDirectories()))) { for (Path p : dirStream) { if (!Files.isRegularFile(p)) { continue; } String bundleName = p.getFileName().toString(); int len = bundleName.length(); assertThat(bundleName).endsWith(".git"); String repoName = bundleName.substring(0, len - 4); Project.NameKey proj = new Project.NameKey(repoName); TestRepository<?> localRepo = cloneProject(proj); try (InputStream bundleStream = Files.newInputStream(p); TransportBundleStream tbs = new TransportBundleStream( localRepo.getRepository(), new URIish(bundleName), bundleStream)) { FetchResult fr = tbs.fetch( NullProgressMonitor.INSTANCE, Arrays.asList(new RefSpec("refs/*:refs/preview/*"))); for (Ref r : fr.getAdvertisedRefs()) { String refName = r.getName(); if (RefNames.isNoteDbMetaRef(refName)) { continue; } RevCommit c = localRepo.getRevWalk().parseCommit(r.getObjectId()); ret.put(new Branch.NameKey(proj, refName), c.getTree().copy()); } } } } assertThat(ret).isNotEmpty(); return ret; }
@Override protected void migrateData(ReviewDb db, UpdateUI ui) throws OrmException, SQLException { ListMultimap<Account.Id, AccountSshKey> imports = MultimapBuilder.hashKeys().arrayListValues().build(); try (Statement stmt = ((JdbcSchema) db).getConnection().createStatement(); ResultSet rs = stmt.executeQuery( "SELECT " + "account_id, " + "seq, " + "ssh_public_key, " + "valid " + "FROM account_ssh_keys")) { while (rs.next()) { Account.Id accountId = new Account.Id(rs.getInt(1)); int seq = rs.getInt(2); String sshPublicKey = rs.getString(3); AccountSshKey key = new AccountSshKey(new AccountSshKey.Id(accountId, seq), sshPublicKey); boolean valid = toBoolean(rs.getString(4)); if (!valid) { key.setInvalid(); } imports.put(accountId, key); } } if (imports.isEmpty()) { return; } try (Repository git = repoManager.openRepository(allUsersName); RevWalk rw = new RevWalk(git)) { BatchRefUpdate bru = git.getRefDatabase().newBatchUpdate(); for (Map.Entry<Account.Id, Collection<AccountSshKey>> e : imports.asMap().entrySet()) { try (MetaDataUpdate md = new MetaDataUpdate(GitReferenceUpdated.DISABLED, allUsersName, git, bru)) { md.getCommitBuilder().setAuthor(serverUser); md.getCommitBuilder().setCommitter(serverUser); VersionedAuthorizedKeys authorizedKeys = new VersionedAuthorizedKeys(new SimpleSshKeyCreator(), e.getKey()); authorizedKeys.load(md); authorizedKeys.setKeys(fixInvalidSequenceNumbers(e.getValue())); authorizedKeys.commit(md); } } bru.execute(rw, NullProgressMonitor.INSTANCE); } catch (ConfigInvalidException | IOException ex) { throw new OrmException(ex); } }
/** * Execute a batch ref update, throwing a checked exception if not all updates succeeded. * * @param bru batch update; should already have been executed. * @throws LockFailureException if the transaction was aborted due to lock failure; see {@link * #checkResults(BatchRefUpdate)} for details. * @throws IOException if any result was not {@code OK}. */ public static void executeChecked(BatchRefUpdate bru, RevWalk rw) throws IOException { bru.execute(rw, NullProgressMonitor.INSTANCE); checkResults(bru); }