@NotNull private String createRemoteFile( @NotNull ObjectId id, @NotNull ObjectLoader loader, @NotNull Uploader uploader) throws IOException { // Create LFS stream. final String hash; final String cached = cacheSha256.get(id.name()); long size = 0; if (cached == null) { final MessageDigest md = createSha256(); try (InputStream istream = loader.openStream()) { byte[] buffer = new byte[0x10000]; while (true) { int read = istream.read(buffer); if (read <= 0) break; md.update(buffer, 0, read); size += read; } } hash = new String(Hex.encodeHex(md.digest(), true)); cacheSha256.put(id.name(), hash); cache.commit(); } else { hash = cached; } uploader.upload(id, new Meta(hash, size)); return hash; }
protected void assertCurrentRevision(String changeId, int expectedNum, ObjectId expectedId) throws Exception { ChangeInfo c = get(changeId, CURRENT_REVISION); assertThat(c.currentRevision).isEqualTo(expectedId.name()); assertThat(c.revisions.get(expectedId.name())._number).isEqualTo(expectedNum); try (Repository repo = repoManager.openRepository(new Project.NameKey(c.project))) { Ref ref = repo.getRef(new PatchSet.Id(new Change.Id(c._number), expectedNum).toRefName()); assertThat(ref).isNotNull(); assertThat(ref.getObjectId()).isEqualTo(expectedId); } }
@NotNull private String createLocalFile(@NotNull ObjectId id, @NotNull ObjectLoader loader) throws IOException { // Create LFS stream. final File tmpFile = new File(tempPath, UUID.randomUUID().toString()); final MessageDigest md = createSha256(); try (InputStream istream = loader.openStream(); OutputStream ostream = new FileOutputStream(tmpFile)) { byte[] buffer = new byte[0x10000]; while (true) { int size = istream.read(buffer); if (size <= 0) break; ostream.write(buffer, 0, size); md.update(buffer, 0, size); } } final String hash = new String(Hex.encodeHex(md.digest(), true)); cacheSha256.putIfAbsent(id.name(), hash); cache.commit(); // Rename file. final File lfsFile = new File( basePath, "lfs/objects/" + hash.substring(0, 2) + "/" + hash.substring(2, 4) + "/" + hash); makeParentDirs(lfsFile.getParentFile()); if (lfsFile.exists()) { if (!tmpFile.delete()) { log.warn("Can't delete temporary file: {}", lfsFile.getAbsolutePath()); } } else if (!tmpFile.renameTo(lfsFile)) { throw new IOException("Can't rename file: " + tmpFile + " -> " + lfsFile); } return hash; }
private DhtRef doPeel(final Ref leaf) throws MissingObjectException, IOException { RevWalk rw = new RevWalk(getRepository()); try { DhtReader ctx = (DhtReader) rw.getObjectReader(); RevObject obj = rw.parseAny(leaf.getObjectId()); RefData.Builder d = RefData.newBuilder(((DhtRef) leaf).getRefData()); ChunkKey oKey = ctx.findChunk(leaf.getObjectId()); if (oKey != null) d.getTargetBuilder().setChunkKey(oKey.asString()); else d.getTargetBuilder().clearChunkKey(); if (obj instanceof RevTag) { ObjectId pId = rw.peel(obj); d.getPeeledBuilder().setObjectName(pId.name()); ChunkKey pKey = ctx.findChunk(pId); if (pKey != null) d.getPeeledBuilder().setChunkKey(pKey.asString()); else d.getPeeledBuilder().clearChunkKey(); } else { d.clearPeeled(); } d.setIsPeeled(true); d.setSequence(d.getSequence() + 1); return new DhtObjectIdRef(leaf.getName(), d.build()); } finally { rw.release(); } }
@Test public void testAbbreviateIsActuallyUnique() throws Exception { // This test is far more difficult. We have to manually craft // an input that contains collisions at a particular prefix, // but this is computationally difficult. Instead we force an // index file to have what we want. // ObjectId id = id("9d5b926ed164e8ee88d3b8b1e525d699adda01ba"); byte[] idBuf = toByteArray(id); List<PackedObjectInfo> objects = new ArrayList<PackedObjectInfo>(); for (int i = 0; i < 256; i++) { idBuf[9] = (byte) i; objects.add(new PackedObjectInfo(ObjectId.fromRaw(idBuf))); } String packName = "pack-" + id.name(); File packDir = new File(db.getObjectDatabase().getDirectory(), "pack"); File idxFile = new File(packDir, packName + ".idx"); File packFile = new File(packDir, packName + ".pack"); FileUtils.mkdir(packDir, true); OutputStream dst = new SafeBufferedOutputStream(new FileOutputStream(idxFile)); try { PackIndexWriter writer = new PackIndexWriterV2(dst); writer.write(objects, new byte[OBJECT_ID_LENGTH]); } finally { dst.close(); } new FileOutputStream(packFile).close(); assertEquals(id.abbreviate(20), reader.abbreviate(id, 2)); AbbreviatedObjectId abbrev8 = id.abbreviate(8); Collection<ObjectId> matches = reader.resolve(abbrev8); assertNotNull(matches); assertEquals(objects.size(), matches.size()); for (PackedObjectInfo info : objects) assertTrue("contains " + info.name(), matches.contains(info)); try { db.resolve(abbrev8.name()); fail("did not throw AmbiguousObjectException"); } catch (AmbiguousObjectException err) { assertEquals(abbrev8, err.getAbbreviatedObjectId()); matches = err.getCandidates(); assertNotNull(matches); assertEquals(objects.size(), matches.size()); for (PackedObjectInfo info : objects) assertTrue("contains " + info.name(), matches.contains(info)); } assertEquals(id, db.resolve(id.abbreviate(20).name())); }
private void setMerged(Change c, ChangeMessage msg, ObjectId mergeResultRev) throws OrmException, IOException { logDebug("Setting change {} merged", c.getId()); ChangeUpdate update = null; final PatchSetApproval submitter; PatchSet merged; try { db.changes().beginTransaction(c.getId()); // We must pull the patchset out of commits, because the patchset ID is // modified when using the cherry-pick merge strategy. CodeReviewCommit commit = commits.get(c.getId()); PatchSet.Id mergedId = commit.change().currentPatchSetId(); merged = db.patchSets().get(mergedId); c = setMergedPatchSet(c.getId(), mergedId); submitter = approvalsUtil.getSubmitter(db, commit.notes(), mergedId); ChangeControl control = commit.getControl(); update = updateFactory.create(control, c.getLastUpdatedOn()); // TODO(yyonas): we need to be able to change the author of the message // is not the person for whom the change was made. addMergedMessage // did this in the past. if (msg != null) { cmUtil.addChangeMessage(db, update, msg); } db.commit(); } finally { db.rollback(); } update.commit(); indexer.index(db, c); try { mergedSenderFactory .create(c.getId(), submitter != null ? submitter.getAccountId() : null) .sendAsync(); } catch (Exception e) { log.error("Cannot email merged notification for " + c.getId(), e); } if (submitter != null && mergeResultRev != null) { try { hooks.doChangeMergedHook( c, accountCache.get(submitter.getAccountId()).getAccount(), merged, db, mergeResultRev.name()); } catch (OrmException ex) { logError("Cannot run hook for submitted patch set " + c.getId(), ex); } } }
public ObjectId mergeBase(ObjectId id1, ObjectId id2) { try { String result; try { result = launchCommand("merge-base", id1.name(), id2.name()); } catch (GitException ge) { return null; } BufferedReader rdr = new BufferedReader(new StringReader(result)); String line; while ((line = rdr.readLine()) != null) { // Add the SHA1 return ObjectId.fromString(line); } } catch (Exception e) { throw new GitException("Error parsing merge base", e); } return null; }
/** * Creates a new branch * * @param refName starting point for the new branch * @param newRefName * @throws IOException */ public void createBranch(String refName, String newRefName) throws IOException { RefUpdate updateRef; updateRef = repository.updateRef(newRefName); Ref startRef = repository.getRef(refName); ObjectId startAt = repository.resolve(refName); String startBranch; if (startRef != null) startBranch = refName; else startBranch = startAt.name(); startBranch = Repository.shortenRefName(startBranch); updateRef.setNewObjectId(startAt); updateRef.setRefLogMessage("branch: Created from " + startBranch, false); // $NON-NLS-1$ updateRef.update(); }
@Override public String toString() { StringBuilder r = new StringBuilder(); r.append("Commit"); if (commitId != null) r.append("[" + commitId.name() + "]"); r.append("={\n"); r.append("tree "); r.append(treeId != null ? treeId.name() : "NOT_SET"); r.append("\n"); for (ObjectId p : parentIds) { r.append("parent "); r.append(p.name()); r.append("\n"); } r.append("author "); r.append(author != null ? author.toString() : "NOT_SET"); r.append("\n"); r.append("committer "); r.append(committer != null ? committer.toString() : "NOT_SET"); r.append("\n"); if (encoding != null && encoding != Constants.CHARSET) { r.append("encoding "); r.append(encoding.name()); r.append("\n"); } r.append("\n"); r.append(message != null ? message : ""); r.append("}"); return r.toString(); }
@Override public ChangeKind getChangeKind( ProjectState project, Repository repo, ObjectId prior, ObjectId next) { try { return new Loader().load(new Key(project, repo, prior, next, useRecursiveMerge)); } catch (IOException e) { log.warn( "Cannot check trivial rebase of new patch set " + next.name() + " in " + project.getProject().getName(), e); return ChangeKind.REWORK; } }
@Test(groups = {"UT"}) public void insertTest() throws IOException { final String expectedId = "7fdc3a7439847844b4fccc4b9e4700ab72c7e11e"; String strdata = "this is a blob !"; byte[] rawdata = strdata.getBytes(Charset.defaultCharset()); when(dbMock.has((AnyObjectId) Mockito.anyObject())).thenReturn(true); undertest.insert(Constants.OBJ_BLOB, rawdata); when(dbMock.has((AnyObjectId) Mockito.anyObject())).thenReturn(false); ObjectId id = undertest.insert(Constants.OBJ_BLOB, rawdata); assertNotNull(id); assertEquals(id.name(), expectedId); Objectify ofy = ObjectifyService.begin(); AppengineObject obj = ofy.get(AppengineObject.class, expectedId); assertNotNull(obj); assertEquals(obj.getObjectId(), expectedId); }
public void createSubmoduleCombinations() throws GitException, IOException { Map<IndexEntry, Collection<Revision>> moduleBranches = new HashMap<IndexEntry, Collection<Revision>>(); for (IndexEntry submodule : git.getSubmodules("HEAD")) { File subdir = new File(workspace, submodule.getFile()); IGitAPI subGit = new GitAPI(git.getGitExe(), new FilePath(subdir), listener, git.getEnvironment()); GitUtils gu = new GitUtils(listener, subGit); Collection<Revision> items = gu.filterTipBranches(gu.getAllBranchRevisions()); filterRevisions(submodule.getFile(), items); moduleBranches.put(submodule, items); } // Remove any uninteresting branches for (IndexEntry entry : moduleBranches.keySet()) { listener.getLogger().print("Submodule " + entry.getFile() + " branches"); for (Revision br : moduleBranches.get(entry)) { listener.getLogger().print(" " + br.toString()); } listener.getLogger().print("\n"); } // Make all the possible combinations List<Map<IndexEntry, Revision>> combinations = createCombinations(moduleBranches); listener .getLogger() .println("There are " + combinations.size() + " submodule/revision combinations possible"); // Create a map which is SHA1 -> Submodule IDs that were present Map<ObjectId, List<IndexEntry>> entriesMap = new HashMap<ObjectId, List<IndexEntry>>(); // Knock out already-defined configurations for (ObjectId sha1 : git.revListAll()) { // What's the submodule configuration List<IndexEntry> entries = git.getSubmodules(sha1.name()); entriesMap.put(sha1, entries); } for (List<IndexEntry> entries : entriesMap.values()) { for (Iterator<Map<IndexEntry, Revision>> it = combinations.iterator(); it.hasNext(); ) { Map<IndexEntry, Revision> item = it.next(); if (matches(item, entries)) { it.remove(); break; } } } listener .getLogger() .println("There are " + combinations.size() + " configurations that could be generated."); ObjectId headSha1 = git.revParse("HEAD"); // Make up the combinations for (Map<IndexEntry, Revision> combination : combinations) { // By default, use the head sha1 ObjectId sha1 = headSha1; int min = Integer.MAX_VALUE; // But let's see if we can find the most appropriate place to create the branch for (ObjectId sha : entriesMap.keySet()) { List<IndexEntry> entries = entriesMap.get(sha); int value = difference(combination, entries); if (value > 0 && value < min) { min = value; sha1 = sha; } if (min == 1) { break; // look no further } } git.checkout(sha1.name()); makeCombination(combination); } }
public List<ChangeData> byCommit(ObjectId id) throws OrmException { return query(commit(schema(indexes), id.name())); }
private static File nameFor(ObjectDirectory odb, ObjectId name, String t) { File packdir = new File(odb.getDirectory(), "pack"); return new File(packdir, "pack-" + name.name() + t); }
/** * Convert an ObjectId into a hex string representation. * * @param i the id to convert. May be null. * @return the hex string conversion of this id's content. */ public static final String toString(final ObjectId i) { return i != null ? i.name() : ZEROID_STR; }
static { ZEROID = new ObjectId(0, 0, 0, 0, 0); ZEROID_STR = ZEROID.name(); }
public Map<String, Object> toSoyData(ObjectId treeId, TreeWalk tw) throws MissingObjectException, IOException { ReadmeHelper readme = new ReadmeHelper(reader, view, MarkdownConfig.get(cfg), rootTree, requestUri); List<Object> entries = Lists.newArrayList(); GitilesView.Builder urlBuilder = GitilesView.path().copyFrom(view); while (tw.next()) { FileType type = FileType.forEntry(tw); String name = tw.getNameString(); GitilesView.Type viewType = view.getType(); if (viewType == GitilesView.Type.PATH) { urlBuilder.setPathPart(view.getPathPart() + "/" + name); } else if (viewType == GitilesView.Type.REVISION) { // Got here from a tag pointing at a tree. urlBuilder.setPathPart(name); } else { throw new IllegalStateException( String.format("Cannot render TreeSoyData from %s view", viewType)); } String url = urlBuilder.toUrl(); if (type == FileType.TREE) { name += "/"; url += "/"; } Map<String, String> entry = Maps.newHashMapWithExpectedSize(4); entry.put("type", type.toString()); entry.put("name", name); entry.put("url", url); if (type == FileType.SYMLINK) { String target = new String(reader.open(tw.getObjectId(0)).getCachedBytes(), UTF_8); entry.put("targetName", getTargetDisplayName(target)); String targetUrl = resolveTargetUrl(view, target); if (targetUrl != null) { entry.put("targetUrl", targetUrl); } } else { readme.considerEntry(tw); } entries.add(entry); } Map<String, Object> data = Maps.newHashMapWithExpectedSize(3); data.put("sha", treeId.name()); data.put("entries", entries); if (view.getType() == GitilesView.Type.PATH && view.getRevision().getPeeledType() == OBJ_COMMIT) { data.put("logUrl", GitilesView.log().copyFrom(view).toUrl()); data.put( "archiveUrl", GitilesView.archive() .copyFrom(view) .setPathPart(Strings.emptyToNull(view.getPathPart())) .setExtension(archiveFormat.getDefaultSuffix()) .toUrl()); data.put("archiveType", archiveFormat.getShortName()); } if (readme.isPresent()) { data.put("readmePath", readme.getPath()); data.put("readmeHtml", readme.render()); } return data; }
@Override public Document execute( Repository repository, Git git, CallSpecification spec, DocumentWriter writer, Values values) throws GitAPIException, IOException { if (spec.parameterCount() == 0) { // This is the top-level "/branches" node writer.setPrimaryType(GitLexicon.TREES); // Generate the child references to the branches and tags. Branches are likely used more // often, so list them first... addBranchesAsChildren(git, spec, writer); addTagsAsChildren(git, spec, writer); addCommitsAsChildren(git, spec, writer, pageSize); } else if (spec.parameterCount() == 1) { // This is a particular branch/tag/commit node ... String branchOrTagOrObjectId = spec.parameter(0); ObjectId objId = resolveBranchOrTagOrCommitId(repository, branchOrTagOrObjectId); RevWalk walker = new RevWalk(repository); walker.setRetainBody(true); // we need to parse the commit for the top-level try { RevCommit commit = walker.parseCommit(objId); // Add the properties for this node ... String committer = commit.getCommitterIdent().getName(); String author = commit.getAuthorIdent().getName(); DateTime committed = values.dateFrom(commit.getCommitTime()); writer.setPrimaryType(GitLexicon.FOLDER); writer.addProperty(JcrLexicon.CREATED, committed); writer.addProperty(JcrLexicon.CREATED_BY, committer); writer.addProperty(GitLexicon.OBJECT_ID, objId.name()); writer.addProperty(GitLexicon.AUTHOR, author); writer.addProperty(GitLexicon.COMMITTER, committer); writer.addProperty(GitLexicon.COMMITTED, committed); writer.addProperty(GitLexicon.TITLE, commit.getShortMessage()); writer.addProperty( GitLexicon.HISTORY, GitHistory.referenceToHistory(objId, branchOrTagOrObjectId, values)); writer.addProperty(GitLexicon.DETAIL, GitCommitDetails.referenceToCommit(objId, values)); // Add the top-level children of the directory ... addInformationForPath(repository, git, writer, commit, "", spec, values); } finally { walker.dispose(); } } else { // This is a folder or file within the directory structure ... String branchOrTagOrObjectId = spec.parameter(0); String path = spec.parametersAsPath(1); ObjectId objId = resolveBranchOrTagOrCommitId(repository, branchOrTagOrObjectId); RevWalk walker = new RevWalk(repository); walker.setRetainBody(false); // we don't need top-level commit information try { // Get the commit information ... RevCommit commit = walker.parseCommit(objId); // Add the top-level children of the directory ... addInformationForPath(repository, git, writer, commit, path, spec, values); } finally { walker.dispose(); } } return writer.document(); }