@Test
  public void testAddUnstagedChanges()
      throws IOException, NoHeadException, NoMessageException, ConcurrentRefUpdateException,
          JGitInternalException, WrongRepositoryStateException, NoFilepatternException {
    File file = new File(db.getWorkTree(), "a.txt");
    FileUtils.createNewFile(file);
    PrintWriter writer = new PrintWriter(file);
    writer.print("content");
    writer.close();

    Git git = new Git(db);
    git.add().addFilepattern("a.txt").call();
    RevCommit commit = git.commit().setMessage("initial commit").call();
    TreeWalk tw = TreeWalk.forPath(db, "a.txt", commit.getTree());
    assertEquals("6b584e8ece562ebffc15d38808cd6b98fc3d97ea", tw.getObjectId(0).getName());

    writer = new PrintWriter(file);
    writer.print("content2");
    writer.close();
    commit = git.commit().setMessage("second commit").call();
    tw = TreeWalk.forPath(db, "a.txt", commit.getTree());
    assertEquals("6b584e8ece562ebffc15d38808cd6b98fc3d97ea", tw.getObjectId(0).getName());

    commit = git.commit().setAll(true).setMessage("third commit").setAll(true).call();
    tw = TreeWalk.forPath(db, "a.txt", commit.getTree());
    assertEquals("db00fd65b218578127ea51f3dffac701f12f486a", tw.getObjectId(0).getName());
  }
예제 #2
0
  @Nullable
  private static MarkdownFile findFile(RevWalk rw, RevTree root, String path) throws IOException {
    if (Strings.isNullOrEmpty(path)) {
      path = INDEX_MD;
    }

    ObjectReader reader = rw.getObjectReader();
    try (TreeWalk tw = TreeWalk.forPath(reader, path, root)) {
      if (tw == null) {
        return null;
      }
      if ((tw.getRawMode(0) & TYPE_MASK) == TYPE_TREE) {
        if (findIndexFile(tw)) {
          path = tw.getPathString();
        } else {
          return null;
        }
      }
      if ((tw.getRawMode(0) & TYPE_MASK) == TYPE_FILE) {
        if (!path.endsWith(".md")) {
          return null;
        }
        return new MarkdownFile(path, tw.getObjectId(0));
      }
      return null;
    }
  }
예제 #3
0
  private String getRepositoryContent(Repository repository, RevCommit revCommit, String fileName)
      throws IOException {
    TreeWalk treewalk = TreeWalk.forPath(repository, fileName, revCommit.getTree());

    if (treewalk != null) {
      return new String(repository.open(treewalk.getObjectId(0)).getBytes());
    } else {
      return null;
    }
  }
예제 #4
0
 private static byte[] read(Repository db, AnyObjectId treeish, String path)
     throws MissingObjectException, IncorrectObjectTypeException, IOException {
   try (ObjectReader or = db.newObjectReader()) {
     TreeWalk tree = TreeWalk.forPath(or, path, asTree(or, treeish));
     if (tree == null)
       throw new FileNotFoundException(
           MessageFormat.format(JGitText.get().entryNotFoundByPath, path));
     return read(or, tree.getObjectId(0));
   }
 }
예제 #5
0
  protected ObjectId getObjectId(String fileName) throws IOException {
    if (revision == null) {
      return null;
    }

    TreeWalk tw = TreeWalk.forPath(reader, fileName, revision.getTree());
    if (tw != null) {
      return tw.getObjectId(0);
    }

    return null;
  }
예제 #6
0
 /**
  * Checks if a file with the given path exists in the HEAD tree
  *
  * @param path
  * @return true if the file exists
  * @throws IOException
  */
 private boolean inHead(String path) throws IOException {
   ObjectId headId = db.resolve(Constants.HEAD);
   RevWalk rw = new RevWalk(db);
   TreeWalk tw = null;
   try {
     tw = TreeWalk.forPath(db, path, rw.parseTree(headId));
     return tw != null;
   } finally {
     rw.release();
     rw.dispose();
     if (tw != null) tw.release();
   }
 }
예제 #7
0
  protected byte[] readFile(String fileName) throws IOException {
    if (revision == null) {
      return new byte[] {};
    }

    TreeWalk tw = TreeWalk.forPath(reader, fileName, revision.getTree());
    if (tw != null) {
      ObjectLoader obj = reader.open(tw.getObjectId(0), Constants.OBJ_BLOB);
      return obj.getCachedBytes(Integer.MAX_VALUE);

    } else {
      return new byte[] {};
    }
  }
예제 #8
0
  @Override
  public byte[] getData(String commitName, String filePath) {

    try {

      RevCommit revCommit = revWalk.parseCommit(ObjectId.fromString(commitName));
      RevTree tree = revCommit.getTree();
      TreeWalk treeWalk = TreeWalk.forPath(reader, filePath, tree);

      if (treeWalk == null) return null;
      else return reader.open(treeWalk.getObjectId(0)).getBytes();

    } catch (IOException e) {
      throw new VisMinerAPIException(e.getMessage(), e);
    }
  }
예제 #9
0
 private void fillTreeItemWithGitDirectory(
     RepositoryMapping m, TreeItem treeItem, boolean isAlternative) {
   if (m.getGitDir() == null)
     treeItem.setText(2, UIText.ExistingOrNewPage_SymbolicValueEmptyMapping);
   else {
     IPath relativePath = new Path(m.getGitDir());
     if (isAlternative) {
       IPath withoutLastSegment = relativePath.removeLastSegments(1);
       IPath path;
       if (withoutLastSegment.isEmpty()) path = Path.fromPortableString("."); // $NON-NLS-1$
       else path = withoutLastSegment;
       treeItem.setText(0, path.toString());
     }
     treeItem.setText(2, relativePath.toOSString());
     try {
       IProject project = m.getContainer().getProject();
       Repository repo =
           new RepositoryBuilder().setGitDir(m.getGitDirAbsolutePath().toFile()).build();
       File workTree = repo.getWorkTree();
       IPath workTreePath = Path.fromOSString(workTree.getAbsolutePath());
       if (workTreePath.isPrefixOf(project.getLocation())) {
         IPath makeRelativeTo = project.getLocation().makeRelativeTo(workTreePath);
         String repoRelativePath =
             makeRelativeTo.append("/.project").toPortableString(); // $NON-NLS-1$
         ObjectId headCommitId = repo.resolve(Constants.HEAD);
         if (headCommitId != null) {
           // Not an empty repo
           RevWalk revWalk = new RevWalk(repo);
           RevCommit headCommit = revWalk.parseCommit(headCommitId);
           RevTree headTree = headCommit.getTree();
           TreeWalk projectInRepo = TreeWalk.forPath(repo, repoRelativePath, headTree);
           if (projectInRepo != null) {
             // the .project file is tracked by this repo
             treeItem.setChecked(true);
           }
           revWalk.dispose();
         }
       }
       repo.close();
     } catch (IOException e1) {
       Activator.logError(UIText.ExistingOrNewPage_FailedToDetectRepositoryMessage, e1);
     }
   }
 }
예제 #10
0
  void updateSubmoduleSubscriptions(ReviewDb db, Branch.NameKey destBranch)
      throws SubmoduleException {
    if (urlProvider.get() == null) {
      logAndThrowSubmoduleException(
          "Cannot establish canonical web url used "
              + "to access gerrit. It should be provided in gerrit.config file.");
    }
    try (Repository repo = repoManager.openRepository(destBranch.getParentKey());
        RevWalk rw = new RevWalk(repo)) {

      ObjectId id = repo.resolve(destBranch.get());
      RevCommit commit = rw.parseCommit(id);

      Set<SubmoduleSubscription> oldSubscriptions =
          Sets.newHashSet(db.submoduleSubscriptions().bySuperProject(destBranch));

      Set<SubmoduleSubscription> newSubscriptions;
      TreeWalk tw = TreeWalk.forPath(repo, GIT_MODULES, commit.getTree());
      if (tw != null
          && (FileMode.REGULAR_FILE.equals(tw.getRawMode(0))
              || FileMode.EXECUTABLE_FILE.equals(tw.getRawMode(0)))) {
        BlobBasedConfig bbc = new BlobBasedConfig(null, repo, commit, GIT_MODULES);

        String thisServer = new URI(urlProvider.get()).getHost();

        newSubscriptions =
            subSecParserFactory.create(bbc, thisServer, destBranch).parseAllSections();
      } else {
        newSubscriptions = Collections.emptySet();
      }

      Set<SubmoduleSubscription> alreadySubscribeds = new HashSet<>();
      for (SubmoduleSubscription s : newSubscriptions) {
        if (oldSubscriptions.contains(s)) {
          alreadySubscribeds.add(s);
        }
      }

      oldSubscriptions.removeAll(newSubscriptions);
      newSubscriptions.removeAll(alreadySubscribeds);

      if (!oldSubscriptions.isEmpty()) {
        db.submoduleSubscriptions().delete(oldSubscriptions);
      }
      if (!newSubscriptions.isEmpty()) {
        db.submoduleSubscriptions().insert(newSubscriptions);
      }

    } catch (OrmException e) {
      logAndThrowSubmoduleException(
          "Database problem at update of subscriptions table from " + GIT_MODULES + " file.", e);
    } catch (ConfigInvalidException e) {
      logAndThrowSubmoduleException(
          "Problem at update of subscriptions table: " + GIT_MODULES + " config file is invalid.",
          e);
    } catch (IOException e) {
      logAndThrowSubmoduleException(
          "Problem at update of subscriptions table from " + GIT_MODULES + ".", e);
    } catch (URISyntaxException e) {
      logAndThrowSubmoduleException(
          "Incorrect gerrit canonical web url provided in gerrit.config file.", e);
    }
  }
예제 #11
0
  @Override
  protected void doGet(final HttpServletRequest req, final HttpServletResponse rsp)
      throws IOException {
    String keyStr = req.getPathInfo();

    // We shouldn't have to do this extra decode pass, but somehow we
    // are now receiving our "^1" suffix as "%5E1", which confuses us
    // downstream. Other times we get our embedded "," as "%2C", which
    // is equally bad. And yet when these happen a "%2F" is left as-is,
    // rather than escaped as "%252F", which makes me feel really really
    // uncomfortable with a blind decode right here.
    //
    keyStr = URLDecoder.decode(keyStr, "UTF-8");

    if (!keyStr.startsWith("/")) {
      rsp.sendError(HttpServletResponse.SC_NOT_FOUND);
      return;
    }
    keyStr = keyStr.substring(1);

    final Patch.Key patchKey;
    final int side;
    {
      final int c = keyStr.lastIndexOf('^');
      if (c == 0) {
        rsp.sendError(HttpServletResponse.SC_NOT_FOUND);
        return;
      }

      if (c < 0) {
        side = 0;

      } else {
        try {
          side = Integer.parseInt(keyStr.substring(c + 1));
          keyStr = keyStr.substring(0, c);
        } catch (NumberFormatException e) {
          rsp.sendError(HttpServletResponse.SC_NOT_FOUND);
          return;
        }
      }

      try {
        patchKey = Patch.Key.parse(keyStr);
      } catch (NumberFormatException e) {
        rsp.sendError(HttpServletResponse.SC_NOT_FOUND);
        return;
      }
    }

    final Change.Id changeId = patchKey.getParentKey().getParentKey();
    final Project project;
    final PatchSet patchSet;
    try {
      final ReviewDb db = requestDb.get();
      final ChangeControl control = changeControl.validateFor(changeId);

      project = control.getProject();
      patchSet = db.patchSets().get(patchKey.getParentKey());
      if (patchSet == null) {
        rsp.sendError(HttpServletResponse.SC_NOT_FOUND);
        return;
      }
    } catch (NoSuchChangeException e) {
      rsp.sendError(HttpServletResponse.SC_NOT_FOUND);
      return;
    } catch (OrmException e) {
      getServletContext().log("Cannot query database", e);
      rsp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
      return;
    }

    final Repository repo;
    try {
      repo = repoManager.openRepository(project.getNameKey());
    } catch (RepositoryNotFoundException e) {
      getServletContext().log("Cannot open repository", e);
      rsp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
      return;
    }

    final ObjectLoader blobLoader;
    final RevCommit fromCommit;
    final String suffix;
    final String path = patchKey.getFileName();
    try {
      final ObjectReader reader = repo.newObjectReader();
      try {
        final RevWalk rw = new RevWalk(reader);
        final RevCommit c;
        final TreeWalk tw;

        c = rw.parseCommit(ObjectId.fromString(patchSet.getRevision().get()));
        if (side == 0) {
          fromCommit = c;
          suffix = "new";

        } else if (1 <= side && side - 1 < c.getParentCount()) {
          fromCommit = rw.parseCommit(c.getParent(side - 1));
          if (c.getParentCount() == 1) {
            suffix = "old";
          } else {
            suffix = "old" + side;
          }

        } else {
          rsp.sendError(HttpServletResponse.SC_NOT_FOUND);
          return;
        }

        tw = TreeWalk.forPath(reader, path, fromCommit.getTree());
        if (tw == null) {
          rsp.sendError(HttpServletResponse.SC_NOT_FOUND);
          return;
        }

        if (tw.getFileMode(0).getObjectType() == Constants.OBJ_BLOB) {
          blobLoader = reader.open(tw.getObjectId(0), Constants.OBJ_BLOB);

        } else {
          rsp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
          return;
        }
      } finally {
        reader.release();
      }
    } catch (IOException e) {
      getServletContext().log("Cannot read repository", e);
      rsp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
      return;
    } catch (RuntimeException e) {
      getServletContext().log("Cannot read repository", e);
      rsp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
      return;
    } finally {
      repo.close();
    }

    final byte[] raw = blobLoader.isLarge() ? null : blobLoader.getCachedBytes();
    final long when = fromCommit.getCommitTime() * 1000L;

    rsp.setDateHeader("Last-Modified", when);
    rsp.setDateHeader("Expires", 0L);
    rsp.setHeader("Pragma", "no-cache");
    rsp.setHeader("Cache-Control", "no-cache, must-revalidate");

    OutputStream out;
    ZipOutputStream zo;

    final MimeType contentType = registry.getMimeType(path, raw);
    if (!registry.isSafeInline(contentType)) {
      // The content may not be safe to transmit inline, as a browser might
      // interpret it as HTML or JavaScript hosted by this site. Such code
      // might then run in the site's security domain, and may be able to use
      // the user's cookies to perform unauthorized actions.
      //
      // Usually, wrapping the content into a ZIP file forces the browser to
      // save the content to the local system instead.
      //

      rsp.setContentType(ZIP.toString());
      rsp.setHeader(
          "Content-Disposition",
          "attachment; filename=\"" + safeFileName(path, suffix) + ".zip" + "\"");

      zo = new ZipOutputStream(rsp.getOutputStream());

      final ZipEntry e = new ZipEntry(safeFileName(path, rand(req, suffix)));
      e.setComment(fromCommit.name() + ":" + path);
      e.setSize(blobLoader.getSize());
      e.setTime(when);
      zo.putNextEntry(e);
      out = zo;

    } else {
      rsp.setContentType(contentType.toString());
      rsp.setHeader("Content-Length", "" + blobLoader.getSize());

      out = rsp.getOutputStream();
      zo = null;
    }

    if (raw != null) {
      out.write(raw);
    } else {
      blobLoader.copyTo(out);
    }

    if (zo != null) {
      zo.closeEntry();
    }
    out.close();
  }