Пример #1
0
 @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;
 }
Пример #2
0
 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);
   }
 }
Пример #3
0
 @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;
 }
Пример #4
0
  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();
    }
  }
Пример #5
0
  @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()));
  }
Пример #6
0
  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);
      }
    }
  }
Пример #7
0
  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;
  }
Пример #8
0
 /**
  * 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();
 }
Пример #9
0
  @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);
  }
Пример #12
0
  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);
    }
  }
Пример #13
0
 public List<ChangeData> byCommit(ObjectId id) throws OrmException {
   return query(commit(schema(indexes), id.name()));
 }
Пример #14
0
 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);
 }
Пример #15
0
 /**
  * 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;
 }
Пример #16
0
 static {
   ZEROID = new ObjectId(0, 0, 0, 0, 0);
   ZEROID_STR = ZEROID.name();
 }
Пример #17
0
  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;
  }
Пример #18
0
  @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();
  }