@Test
  public void testUsingHiddenDeltaBaseFails() throws Exception {
    byte[] delta = {0x1, 0x1, 0x1, 'c'};
    TestRepository<Repository> s = new TestRepository<Repository>(src);
    RevCommit N =
        s.commit()
            .parent(B)
            .add("q", s.blob(BinaryDelta.apply(dst.open(b).getCachedBytes(), delta)))
            .create();

    final TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(1024);
    packHeader(pack, 3);
    copy(pack, src.open(N));
    copy(pack, src.open(s.parseBody(N).getTree()));
    pack.write((Constants.OBJ_REF_DELTA) << 4 | 4);
    b.copyRawTo(pack);
    deflate(pack, delta);
    digest(pack);

    final TemporaryBuffer.Heap inBuf = new TemporaryBuffer.Heap(1024);
    final PacketLineOut inPckLine = new PacketLineOut(inBuf);
    inPckLine.writeString(
        ObjectId.zeroId().name()
            + ' '
            + N.name()
            + ' '
            + "refs/heads/s"
            + '\0'
            + BasePackPushConnection.CAPABILITY_REPORT_STATUS);
    inPckLine.end();
    pack.writeTo(inBuf, PM);

    final TemporaryBuffer.Heap outBuf = new TemporaryBuffer.Heap(1024);
    final ReceivePack rp = new ReceivePack(dst);
    rp.setCheckReceivedObjects(true);
    rp.setCheckReferencedObjectsAreReachable(true);
    rp.setAdvertiseRefsHook(new HidePrivateHook());
    try {
      receive(rp, inBuf, outBuf);
      fail("Expected UnpackException");
    } catch (UnpackException failed) {
      Throwable err = failed.getCause();
      assertTrue(err instanceof MissingObjectException);
      MissingObjectException moe = (MissingObjectException) err;
      assertEquals(b, moe.getObjectId());
    }

    final PacketLineIn r = asPacketLineIn(outBuf);
    String master = r.readString();
    int nul = master.indexOf('\0');
    assertTrue("has capability list", nul > 0);
    assertEquals(B.name() + ' ' + R_MASTER, master.substring(0, nul));
    assertSame(PacketLineIn.END, r.readString());

    assertEquals("unpack error Missing blob " + b.name(), r.readString());
    assertEquals("ng refs/heads/s n/a (unpacker error)", r.readString());
    assertSame(PacketLineIn.END, r.readString());
  }
  @Test
  public void testUsingUnknownBlobFails() throws Exception {
    // Try to use the 'n' blob that is not on the server.
    //
    TestRepository<Repository> s = new TestRepository<Repository>(src);
    RevBlob n = s.blob("n");
    RevCommit N = s.commit().parent(B).add("q", n).create();

    // But don't include it in the pack.
    //
    final TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(1024);
    packHeader(pack, 2);
    copy(pack, src.open(N));
    copy(pack, src.open(s.parseBody(N).getTree()));
    digest(pack);

    final TemporaryBuffer.Heap inBuf = new TemporaryBuffer.Heap(1024);
    final PacketLineOut inPckLine = new PacketLineOut(inBuf);
    inPckLine.writeString(
        ObjectId.zeroId().name()
            + ' '
            + N.name()
            + ' '
            + "refs/heads/s"
            + '\0'
            + BasePackPushConnection.CAPABILITY_REPORT_STATUS);
    inPckLine.end();
    pack.writeTo(inBuf, PM);

    final TemporaryBuffer.Heap outBuf = new TemporaryBuffer.Heap(1024);
    final ReceivePack rp = new ReceivePack(dst);
    rp.setCheckReceivedObjects(true);
    rp.setCheckReferencedObjectsAreReachable(true);
    rp.setAdvertiseRefsHook(new HidePrivateHook());
    try {
      receive(rp, inBuf, outBuf);
      fail("Expected UnpackException");
    } catch (UnpackException failed) {
      Throwable err = failed.getCause();
      assertTrue(err instanceof MissingObjectException);
      MissingObjectException moe = (MissingObjectException) err;
      assertEquals(n, moe.getObjectId());
    }

    final PacketLineIn r = asPacketLineIn(outBuf);
    String master = r.readString();
    int nul = master.indexOf('\0');
    assertTrue("has capability list", nul > 0);
    assertEquals(B.name() + ' ' + R_MASTER, master.substring(0, nul));
    assertSame(PacketLineIn.END, r.readString());

    assertEquals("unpack error Missing blob " + n.name(), r.readString());
    assertEquals("ng refs/heads/s n/a (unpacker error)", r.readString());
    assertSame(PacketLineIn.END, r.readString());
  }
Beispiel #3
0
 protected void assertRebase(TestRepository<?> testRepo, boolean contentMerge) throws IOException {
   Repository repo = testRepo.getRepository();
   RevCommit localHead = getHead(repo);
   RevCommit remoteHead = getRemoteHead();
   assert_()
       .withFailureMessage(String.format("%s not equal %s", localHead.name(), remoteHead.name()))
       .that(localHead.getId())
       .isNotEqualTo(remoteHead.getId());
   assertThat(remoteHead.getParentCount()).isEqualTo(1);
   if (!contentMerge) {
     assertThat(getLatestRemoteDiff()).isEqualTo(getLatestDiff(repo));
   }
   assertThat(remoteHead.getShortMessage()).isEqualTo(localHead.getShortMessage());
 }
Beispiel #4
0
  @Override
  public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {

    try {
      String localPath = args[0].getStringValue();
      if (!(localPath.endsWith("/"))) localPath += File.separator;

      //	        Repository localRepo = new FileRepository(localPath + ".git");
      //	        Git git = new Git(localRepo);

      Git git = Git.open(new Resource(localPath), FS);

      MemTreeBuilder builder = context.getDocumentBuilder();

      AttributesImpl attribs = new AttributesImpl();
      attribs.addAttribute(NAMESPACE_URI, "local-path", PREFIX + ":local-path", "CDATA", localPath);

      int nodeNr = builder.startElement(LOG_ELEMENT, attribs);

      for (RevCommit commit : git.log().call()) {
        //                commit.getParentCount();
        //                commit.getParents();

        attribs = new AttributesImpl();
        attribs.addAttribute(NAMESPACE_URI, "id", PREFIX + ":id", "CDATA", commit.name());

        attribs.addAttribute(
            NAMESPACE_URI,
            "time",
            PREFIX + ":time",
            "CDATA",
            String.valueOf(commit.getCommitTime()));

        builder.startElement(COMMIT_ELEMENT, attribs);

        PersonIdent authorIdent = commit.getAuthorIdent();
        builder.startElement(AUTHOR_ELEMENT, null);
        builder.startElement(AUTHOR_NAME_ELEMENT, null);
        builder.characters(authorIdent.getName());
        builder.endElement();
        builder.startElement(AUTHOR_EMAIL_ELEMENT, null);
        builder.characters(authorIdent.getEmailAddress());
        builder.endElement();
        builder.endElement();

        builder.startElement(MESSAGE_ELEMENT, null);
        builder.characters(commit.getFullMessage());
        builder.endElement();

        builder.endElement();
      }

      builder.endElement();

      return builder.getDocument().getNode(nodeNr);
    } catch (Throwable e) {
      throw new XPathException(this, Module.EXGIT001, e);
    }
  }
 private GitVersionInfo makeVersionInfo(RevCommit revCommit) {
   PersonIdent authorIdent = revCommit.getAuthorIdent();
   return new GitVersionInfo(
       revCommit.name(),
       authorIdent.getName(),
       authorIdent.getWhen(),
       revCommit.getShortMessage());
 }
Beispiel #6
0
  public void testAutoCommand() throws Exception {
    RevCommit parent = repo.commit().create();
    RevCommit master = repo.branch("refs/heads/master").commit().parent(parent).create();
    String hex = master.name();
    String hexBranch = hex.substring(0, 10);
    RevCommit hexCommit = repo.branch(hexBranch).commit().create();

    assertEquals(Type.LOG, getView("/repo/+/master").getType());
    assertEquals(Type.LOG, getView("/repo/+/" + hexBranch).getType());
    assertEquals(Type.REVISION, getView("/repo/+/" + hex).getType());
    assertEquals(Type.REVISION, getView("/repo/+/" + hex.substring(0, 7)).getType());
    assertEquals(Type.PATH, getView("/repo/+/master/").getType());
    assertEquals(Type.PATH, getView("/repo/+/" + hex + "/").getType());
    assertEquals(Type.DIFF, getView("/repo/+/master^..master").getType());
    assertEquals(Type.DIFF, getView("/repo/+/master^..master/").getType());
    assertEquals(Type.DIFF, getView("/repo/+/" + parent.name() + ".." + hex + "/").getType());
  }
  @Test
  public void testCreateBranchAtHiddenCommitFails() throws Exception {
    final TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(64);
    packHeader(pack, 0);
    digest(pack);

    final TemporaryBuffer.Heap inBuf = new TemporaryBuffer.Heap(256);
    final PacketLineOut inPckLine = new PacketLineOut(inBuf);
    inPckLine.writeString(
        ObjectId.zeroId().name()
            + ' '
            + P.name()
            + ' '
            + "refs/heads/s"
            + '\0'
            + BasePackPushConnection.CAPABILITY_REPORT_STATUS);
    inPckLine.end();
    pack.writeTo(inBuf, PM);

    final TemporaryBuffer.Heap outBuf = new TemporaryBuffer.Heap(1024);
    final ReceivePack rp = new ReceivePack(dst);
    rp.setCheckReceivedObjects(true);
    rp.setCheckReferencedObjectsAreReachable(true);
    rp.setAdvertiseRefsHook(new HidePrivateHook());
    try {
      receive(rp, inBuf, outBuf);
      fail("Expected UnpackException");
    } catch (UnpackException failed) {
      Throwable err = failed.getCause();
      assertTrue(err instanceof MissingObjectException);
      MissingObjectException moe = (MissingObjectException) err;
      assertEquals(P, moe.getObjectId());
    }

    final PacketLineIn r = asPacketLineIn(outBuf);
    String master = r.readString();
    int nul = master.indexOf('\0');
    assertTrue("has capability list", nul > 0);
    assertEquals(B.name() + ' ' + R_MASTER, master.substring(0, nul));
    assertSame(PacketLineIn.END, r.readString());

    assertEquals("unpack error Missing commit " + P.name(), r.readString());
    assertEquals("ng refs/heads/s n/a (unpacker error)", r.readString());
    assertSame(PacketLineIn.END, r.readString());
  }
Beispiel #8
0
 private Revision asRevision(final RevCommit commit) {
   final PersonIdent author = commit.getAuthorIdent();
   return new RevisionImpl(
       commit.name(),
       author.getName(),
       author.getEmailAddress(),
       author.getWhen(),
       commit.getFullMessage());
 }
  private void setSourceCommit(RevCommit commit) {
    sourceNameLabel.setText(commit.abbreviate(7).name());
    sourceIcon.setImage(UIIcons.getImage(resourceManager, UIIcons.CHANGESET));

    sourceRefName = commit.name();

    upstreamConfig = UpstreamConfig.NONE;
    checkPage();
  }
  public Object execute(ExecutionEvent event) throws ExecutionException {
    List<StashedCommitNode> nodes = getSelectedNodes(event);
    if (nodes.isEmpty()) return null;

    StashedCommitNode node = nodes.get(0);
    final Repository repo = node.getRepository();
    if (repo == null) return null;
    final int index = node.getIndex();
    if (index < 0) return null;
    final RevCommit commit = node.getObject();
    if (commit == null) return null;

    // Confirm deletion of selected tags
    final AtomicBoolean confirmed = new AtomicBoolean();
    final Shell shell = getActiveShell(event);
    shell
        .getDisplay()
        .syncExec(
            new Runnable() {

              public void run() {
                confirmed.set(
                    MessageDialog.openConfirm(
                        shell,
                        UIText.StashDropCommand_confirmTitle,
                        MessageFormat.format(
                            UIText.StashDropCommand_confirmMessage, Integer.toString(index))));
              }
            });
    if (!confirmed.get()) return null;

    final StashDropOperation op = new StashDropOperation(repo, index);
    Job job =
        new Job(MessageFormat.format(UIText.StashDropCommand_jobTitle, commit.name())) {
          @Override
          protected IStatus run(IProgressMonitor monitor) {
            try {
              op.execute(monitor);
            } catch (CoreException e) {
              Activator.logError(
                  MessageFormat.format(UIText.StashDropCommand_dropFailed, commit.name()), e);
            }
            return Status.OK_STATUS;
          }

          @Override
          public boolean belongsTo(Object family) {
            if (JobFamilies.STASH.equals(family)) return true;
            return super.belongsTo(family);
          }
        };
    job.setUser(true);
    job.setRule(op.getSchedulingRule());
    job.schedule();
    return null;
  }
Beispiel #11
0
 protected Config readConfig(String fileName) throws IOException, ConfigInvalidException {
   Config rc = new Config();
   String text = readUTF8(fileName);
   if (!text.isEmpty()) {
     try {
       rc.fromText(text);
     } catch (ConfigInvalidException err) {
       throw new ConfigInvalidException(
           "Invalid config file " + fileName + " in commit " + revision.name(), err);
     }
   }
   return rc;
 }
Beispiel #12
0
  /**
   * Create an iterator to walk the merge base of two commits.
   *
   * @param aIdx index of the first commit in {@link #sourceObjects}.
   * @param bIdx index of the second commit in {@link #sourceObjects}.
   * @return the new iterator
   * @throws IncorrectObjectTypeException one of the input objects is not a commit.
   * @throws IOException objects are missing or multiple merge bases were found.
   */
  protected AbstractTreeIterator mergeBase(final int aIdx, final int bIdx) throws IOException {
    if (sourceCommits[aIdx] == null)
      throw new IncorrectObjectTypeException(sourceObjects[aIdx], Constants.TYPE_COMMIT);
    if (sourceCommits[bIdx] == null)
      throw new IncorrectObjectTypeException(sourceObjects[bIdx], Constants.TYPE_COMMIT);

    walk.reset();
    walk.setRevFilter(RevFilter.MERGE_BASE);
    walk.markStart(sourceCommits[aIdx]);
    walk.markStart(sourceCommits[bIdx]);
    final RevCommit base = walk.next();
    if (base == null) return new EmptyTreeIterator();
    final RevCommit base2 = walk.next();
    if (base2 != null) {
      throw new IOException(
          MessageFormat.format(
              JGitText.get().multipleMergeBasesFor,
              sourceCommits[aIdx].name(),
              sourceCommits[bIdx].name(),
              base.name(),
              base2.name()));
    }
    return openTree(base.getTree());
  }
Beispiel #13
0
  private String abbreviate(RevCommit commit) throws IOException {
    String r = abbreviatedCommits.get(commit);
    if (r != null) return r;

    if (showBlankBoundary && commit.getParentCount() == 0) commit = null;

    if (commit == null) {
      int len = showLongRevision ? OBJECT_ID_STRING_LENGTH : (abbrev + 1);
      StringBuilder b = new StringBuilder(len);
      for (int i = 0; i < len; i++) b.append(' ');
      r = b.toString();

    } else if (!root && commit.getParentCount() == 0) {
      if (showLongRevision)
        r = "^" + commit.name().substring(0, OBJECT_ID_STRING_LENGTH - 1); // $NON-NLS-1$
      else r = "^" + reader.abbreviate(commit, abbrev).name(); // $NON-NLS-1$
    } else {
      if (showLongRevision) r = commit.name();
      else r = reader.abbreviate(commit, abbrev + 1).name();
    }

    abbreviatedCommits.put(commit, r);
    return r;
  }
  @Test
  public void testSelectionOrderingWithChains() throws Exception {
    /*-
     * Create a history like this, where 'N' is the number of seconds from
     * the first commit in the branch:
     *
     *      ---o---o---o        commits b3,b5,b7
     *     /            \
     * o--o--o---o---o---o--o   commits m0,m1,m2,m4,m6,m8,m9
     */
    BranchBuilder bb = tr.branch("refs/heads/main");
    RevCommit m0 = addCommit(bb, "m0");
    RevCommit m1 = addCommit(bb, "m1", m0);
    RevCommit m2 = addCommit(bb, "m2", m1);
    RevCommit b3 = addCommit(bb, "b3", m1);
    RevCommit m4 = addCommit(bb, "m4", m2);
    RevCommit b5 = addCommit(bb, "m5", b3);
    RevCommit m6 = addCommit(bb, "m6", m4);
    RevCommit b7 = addCommit(bb, "m7", b5);
    RevCommit m8 = addCommit(bb, "m8", m6, b7);
    RevCommit m9 = addCommit(bb, "m9", m8);

    List<RevCommit> commits = Arrays.asList(m0, m1, m2, b3, m4, b5, m6, b7, m8, m9);
    PackWriterBitmapPreparer preparer = newPeparer(m9, commits);
    List<BitmapCommit> selection = new ArrayList<>(preparer.selectCommits(commits.size()));

    // Verify that the output is ordered by the separate "chains"
    String[] expected = {
      m0.name(), m1.name(), m2.name(), m4.name(), m6.name(), m8.name(), m9.name(), b3.name(),
      b5.name(), b7.name()
    };
    assertEquals(expected.length, selection.size());
    for (int i = 0; i < expected.length; i++) {
      assertEquals("Entry " + i, expected[i], selection.get(i).getName());
    }
  }
  protected ChangeInserter newChange(
      TestRepository<Repo> repo,
      @Nullable RevCommit commit,
      @Nullable String key,
      @Nullable Integer owner,
      @Nullable String branch)
      throws Exception {
    if (commit == null) {
      commit = repo.parseBody(repo.commit().message("message").create());
    }
    Account.Id ownerId = owner != null ? new Account.Id(owner) : userId;
    branch = MoreObjects.firstNonNull(branch, "refs/heads/master");
    if (!branch.startsWith("refs/heads/")) {
      branch = "refs/heads/" + branch;
    }
    Project.NameKey project =
        new Project.NameKey(repo.getRepository().getDescription().getRepositoryName());

    Change.Id id = new Change.Id(db.nextChangeId());
    if (key == null) {
      key =
          "I"
              + Hashing.sha1()
                  .newHasher()
                  .putInt(id.get())
                  .putString(project.get(), UTF_8)
                  .putString(commit.name(), UTF_8)
                  .putInt(ownerId.get())
                  .putString(branch, UTF_8)
                  .hash()
                  .toString();
    }

    Change change =
        new Change(
            new Change.Key(key),
            id,
            ownerId,
            new Branch.NameKey(project, branch),
            TimeUtil.nowTs());
    IdentifiedUser user = userFactory.create(Providers.of(db), ownerId);
    return changeFactory.create(projectControlFactory.controlFor(project, user), change, commit);
  }
Beispiel #16
0
 // format the output like in --pretty="%H<#>%aN<#>%at<#>%cN<#>%ct<#>%s
 private String printCommit(RevCommit c) {
   String out = "";
   PersonIdent author = c.getAuthorIdent();
   PersonIdent committer = c.getCommitterIdent();
   // long commitTime = (long)c.getCommitTime() == committer.getWhen().getTime() / 1000 (in
   // seconds)
   out +=
       ""
           + c.name()
           + GitWorks.log_sep
           + author.getName()
           + GitWorks.log_sep
           + author.getWhen().getTime()
           + GitWorks.log_sep
           + committer.getName()
           + GitWorks.log_sep
           + committer.getWhen().getTime()
           + GitWorks.log_sep
           + c.getShortMessage(); // c.getFullMessage(); c.getShortMessage();
   return out;
 }
  /**
   * @param newRefName
   * @param checkoutNewBranch
   * @param monitor
   * @throws CoreException
   * @throws IOException
   */
  public void createBranch(String newRefName, boolean checkoutNewBranch, IProgressMonitor monitor)
      throws CoreException, IOException {
    monitor.beginTask(UIText.CreateBranchPage_CreatingBranchMessage, IProgressMonitor.UNKNOWN);

    final CreateLocalBranchOperation cbop;

    if (myBaseCommit != null && this.sourceRefName.equals(myBaseCommit.name()))
      cbop = new CreateLocalBranchOperation(myRepository, newRefName, myBaseCommit);
    else
      cbop =
          new CreateLocalBranchOperation(
              myRepository, newRefName, myRepository.getRef(this.sourceRefName), upstreamConfig);

    cbop.execute(monitor);

    if (checkoutNewBranch) {
      if (monitor.isCanceled()) return;
      monitor.beginTask(UIText.CreateBranchPage_CheckingOutMessage, IProgressMonitor.UNKNOWN);
      BranchOperationUI.checkout(myRepository, Constants.R_HEADS + newRefName).run(monitor);
    }
  }
Beispiel #18
0
  public Object execute(ExecutionEvent event) throws ExecutionException {
    final RepositoryTreeNode node = getSelectedNodes(event).get(0);

    if (node.getType() == RepositoryTreeNodeType.ADDITIONALREF) {
      Ref ref = (Ref) node.getObject();
      try {
        RevCommit baseCommit =
            new RevWalk(node.getRepository()).parseCommit(ref.getLeaf().getObjectId());
        WizardDialog dlg =
            new WizardDialog(
                getShell(event), new CreateBranchWizard(node.getRepository(), baseCommit.name()));
        dlg.setHelpAvailable(false);
        dlg.open();
      } catch (IOException e) {
        Activator.handleError(e.getMessage(), e, true);
      }
      return null;
    }
    String base = null;
    if (node.getObject() instanceof Ref) base = ((Ref) node.getObject()).getName();
    new WizardDialog(getShell(event), new CreateBranchWizard(node.getRepository(), base)).open();
    return null;
  }
  @Override
  public void execute() throws BuildException {
    if (_property == null) {
      throw new BuildException("Property attribute is required", getLocation());
    }

    if (_path == null) {
      throw new BuildException("Path attribute is required", getLocation());
    }

    File gitDir = PathUtil.getGitDir(_gitDir, getProject(), getLocation());

    String relativePath = PathUtil.toRelativePath(gitDir, _path);

    if (_useCache) {
      String hash = _hashes.get(relativePath);

      if (hash != null) {
        Project currentProject = getProject();

        currentProject.setNewProperty(_property, hash);

        return;
      }
    }

    try (Repository repository = RepositoryCache.open(FileKey.exact(gitDir, FS.DETECTED))) {

      RevWalk revWalk = new RevWalk(repository);

      revWalk.setRetainBody(false);

      revWalk.markStart(revWalk.parseCommit(repository.resolve(Constants.HEAD)));

      if (_ignoreFileName == null) {
        revWalk.setRevFilter(MaxCountRevFilter.create(1));
      } else {
        revWalk.setRevFilter(MaxCountRevFilter.create(2));
      }

      revWalk.setTreeFilter(
          AndTreeFilter.create(PathFilter.create(relativePath), TreeFilter.ANY_DIFF));

      RevCommit revCommit = revWalk.next();

      if (revCommit == null) {
        throw new IllegalStateException("Unable to find any commit under " + _path);
      }

      if (hasIgnoreFile(repository, revCommit, relativePath)) {
        RevCommit secondRevCommit = revWalk.next();

        if (secondRevCommit != null) {
          revCommit = secondRevCommit;
        }
      }

      Project currentProject = getProject();

      String hash = revCommit.name();

      currentProject.setNewProperty(_property, hash);

      if (_useCache) {
        _hashes.put(relativePath, hash);
      }

      revWalk.dispose();
    } catch (Exception e) {
      throw new BuildException("Unable to get head hash for path " + _path, e);
    }
  }
Beispiel #20
0
  public static CherryPickResult cherryPickNoMerge(final Git git, Ref src)
      throws GitAPIException, CantMergeCommitWithZeroParentsException {
    // Does the same as the original git-cherryPick
    // except commiting after running merger
    Repository repo = git.getRepository();

    RevCommit newHead = null;
    List<Ref> cherryPickedRefs = new LinkedList<Ref>();

    RevWalk revWalk = new RevWalk(repo);
    try {
      // get the head commit
      Ref headRef = repo.getRef(Constants.HEAD);
      if (headRef == null)
        throw new NoHeadException(JGitText.get().commitOnRepoWithoutHEADCurrentlyNotSupported);
      RevCommit headCommit = revWalk.parseCommit(headRef.getObjectId());

      newHead = headCommit;

      // get the commit to be cherry-picked
      // handle annotated tags
      ObjectId srcObjectId = src.getPeeledObjectId();
      if (srcObjectId == null) srcObjectId = src.getObjectId();
      RevCommit srcCommit = revWalk.parseCommit(srcObjectId);

      // get the parent of the commit to cherry-pick
      if (srcCommit.getParentCount() == 0)
        throw new CantMergeCommitWithZeroParentsException(
            "Commit with zero parents cannot be merged");

      if (srcCommit.getParentCount() > 1)
        throw new MultipleParentsNotAllowedException(
            MessageFormat.format(
                JGitText.get().canOnlyCherryPickCommitsWithOneParent,
                srcCommit.name(),
                Integer.valueOf(srcCommit.getParentCount())));

      RevCommit srcParent = srcCommit.getParent(0);
      revWalk.parseHeaders(srcParent);

      ResolveMerger merger = (ResolveMerger) MergeStrategy.RESOLVE.newMerger(repo);
      merger.setWorkingTreeIterator(new FileTreeIterator(repo));
      merger.setBase(srcParent.getTree());
      if (merger.merge(headCommit, srcCommit)) {
        DirCacheCheckout dco =
            new DirCacheCheckout(
                repo, headCommit.getTree(), repo.lockDirCache(), merger.getResultTreeId());
        dco.setFailOnConflict(true);
        dco.checkout();

        cherryPickedRefs.add(src);
      } else {
        if (merger.failed()) return new CherryPickResult(merger.getFailingPaths());

        // there are merge conflicts
        String message =
            new MergeMessageFormatter()
                .formatWithConflicts(srcCommit.getFullMessage(), merger.getUnmergedPaths());

        repo.writeCherryPickHead(srcCommit.getId());
        repo.writeMergeCommitMsg(message);

        return CherryPickResult.CONFLICT;
      }
    } catch (IOException e) {
      throw new JGitInternalException(
          MessageFormat.format(JGitText.get().exceptionCaughtDuringExecutionOfCherryPickCommand, e),
          e);
    } finally {
      revWalk.release();
    }

    return new CherryPickResult(newHead, cherryPickedRefs);
  }
Beispiel #21
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();
  }
  private void checkout(RevCommit commit, IProgressMonitor monitor) throws CoreException {
    monitor.setTaskName(UIText.FetchGerritChangePage_CheckingOutTaskName);
    BranchOperationUI.checkout(repository, commit.name()).run(monitor);

    monitor.worked(1);
  }
  public CommitDiffPage(PageParameters params) {
    super(params);

    Repository r = getRepository();

    final RevCommit commit = getCommit();

    final List<String> parents = new ArrayList<String>();
    if (commit.getParentCount() > 0) {
      for (RevCommit parent : commit.getParents()) {
        parents.add(parent.name());
      }
    }

    // commit page links
    if (parents.size() == 0) {
      add(new Label("parentLink", getString("gb.none")));
    } else {
      add(
          new LinkPanel(
              "parentLink",
              null,
              parents.get(0).substring(0, 8),
              CommitDiffPage.class,
              newCommitParameter(parents.get(0))));
    }
    add(
        new BookmarkablePageLink<Void>(
            "patchLink",
            PatchPage.class,
            WicketUtils.newObjectParameter(repositoryName, objectId)));
    add(
        new BookmarkablePageLink<Void>(
            "commitLink",
            CommitPage.class,
            WicketUtils.newObjectParameter(repositoryName, objectId)));

    add(new CommitHeaderPanel("commitHeader", repositoryName, commit));

    final List<String> imageExtensions = app().settings().getStrings(Keys.web.imageExtensions);
    final ImageDiffHandler handler =
        new ImageDiffHandler(
            this,
            repositoryName,
            parents.isEmpty() ? null : parents.get(0),
            commit.getName(),
            imageExtensions);
    final DiffOutput diff = DiffUtils.getCommitDiff(r, commit, DiffOutputType.HTML, handler);
    if (handler.getImgDiffCount() > 0) {
      addBottomScript("scripts/imgdiff.js"); // Tiny support script for image diffs
    }

    // add commit diffstat
    int insertions = 0;
    int deletions = 0;
    for (PathChangeModel pcm : diff.stat.paths) {
      insertions += pcm.insertions;
      deletions += pcm.deletions;
    }
    add(new DiffStatPanel("diffStat", insertions, deletions));

    addFullText("fullMessage", commit.getFullMessage());

    // git notes
    List<GitNote> notes = JGitUtils.getNotesOnCommit(r, commit);
    ListDataProvider<GitNote> notesDp = new ListDataProvider<GitNote>(notes);
    DataView<GitNote> notesView =
        new DataView<GitNote>("notes", notesDp) {
          private static final long serialVersionUID = 1L;

          @Override
          public void populateItem(final Item<GitNote> item) {
            GitNote entry = item.getModelObject();
            item.add(new RefsPanel("refName", repositoryName, Arrays.asList(entry.notesRef)));
            item.add(
                createPersonPanel(
                    "authorName", entry.notesRef.getAuthorIdent(), Constants.SearchType.AUTHOR));
            item.add(new GravatarImage("noteAuthorAvatar", entry.notesRef.getAuthorIdent()));
            item.add(
                WicketUtils.createTimestampLabel(
                    "authorDate",
                    entry.notesRef.getAuthorIdent().getWhen(),
                    getTimeZone(),
                    getTimeUtils()));
            item.add(
                new Label(
                        "noteContent",
                        bugtraqProcessor()
                            .processPlainCommitMessage(
                                getRepository(), repositoryName, entry.content))
                    .setEscapeModelStrings(false));
          }
        };
    add(notesView.setVisible(notes.size() > 0));

    // changed paths list
    add(new CommitLegendPanel("commitLegend", diff.stat.paths));
    ListDataProvider<PathChangeModel> pathsDp =
        new ListDataProvider<PathChangeModel>(diff.stat.paths);
    DataView<PathChangeModel> pathsView =
        new DataView<PathChangeModel>("changedPath", pathsDp) {
          private static final long serialVersionUID = 1L;
          int counter;

          @Override
          public void populateItem(final Item<PathChangeModel> item) {
            final PathChangeModel entry = item.getModelObject();
            Label changeType = new Label("changeType", "");
            WicketUtils.setChangeTypeCssClass(changeType, entry.changeType);
            setChangeTypeTooltip(changeType, entry.changeType);
            item.add(changeType);
            item.add(new DiffStatPanel("diffStat", entry.insertions, entry.deletions, true));

            boolean hasSubmodule = false;
            String submodulePath = null;
            if (entry.isTree()) {
              // tree
              item.add(
                  new LinkPanel(
                      "pathName",
                      null,
                      entry.path,
                      TreePage.class,
                      WicketUtils.newPathParameter(repositoryName, entry.commitId, entry.path)));
            } else if (entry.isSubmodule()) {
              // submodule
              String submoduleId = entry.objectId;
              SubmoduleModel submodule = getSubmodule(entry.path);
              submodulePath = submodule.gitblitPath;
              hasSubmodule = submodule.hasSubmodule;

              // add relative link
              item.add(
                  new LinkPanel(
                      "pathName",
                      "list",
                      entry.path + " @ " + getShortObjectId(submoduleId),
                      "#n" + entry.objectId));
            } else {
              // add relative link
              item.add(new LinkPanel("pathName", "list", entry.path, "#n" + entry.objectId));
            }

            // quick links
            if (entry.isSubmodule()) {
              item.add(new ExternalLink("raw", "").setEnabled(false));
              // submodule
              item.add(new ExternalLink("patch", "").setEnabled(false));
              item.add(
                  new BookmarkablePageLink<Void>(
                          "view",
                          CommitPage.class,
                          WicketUtils.newObjectParameter(submodulePath, entry.objectId))
                      .setEnabled(hasSubmodule));
              item.add(new ExternalLink("blame", "").setEnabled(false));
              item.add(
                  new BookmarkablePageLink<Void>(
                          "history",
                          HistoryPage.class,
                          WicketUtils.newPathParameter(repositoryName, entry.commitId, entry.path))
                      .setEnabled(!entry.changeType.equals(ChangeType.ADD)));
            } else {
              // tree or blob
              item.add(
                  new BookmarkablePageLink<Void>(
                          "patch",
                          PatchPage.class,
                          WicketUtils.newPathParameter(repositoryName, entry.commitId, entry.path))
                      .setEnabled(
                          !entry.changeType.equals(ChangeType.ADD)
                              && !entry.changeType.equals(ChangeType.DELETE)));
              item.add(
                  new BookmarkablePageLink<Void>(
                          "view",
                          BlobPage.class,
                          WicketUtils.newPathParameter(repositoryName, entry.commitId, entry.path))
                      .setEnabled(!entry.changeType.equals(ChangeType.DELETE)));
              String rawUrl =
                  RawServlet.asLink(getContextUrl(), repositoryName, entry.commitId, entry.path);
              item.add(
                  new ExternalLink("raw", rawUrl)
                      .setEnabled(!entry.changeType.equals(ChangeType.DELETE)));
              item.add(
                  new BookmarkablePageLink<Void>(
                          "blame",
                          BlamePage.class,
                          WicketUtils.newPathParameter(repositoryName, entry.commitId, entry.path))
                      .setEnabled(
                          !entry.changeType.equals(ChangeType.ADD)
                              && !entry.changeType.equals(ChangeType.DELETE)));
              item.add(
                  new BookmarkablePageLink<Void>(
                          "history",
                          HistoryPage.class,
                          WicketUtils.newPathParameter(repositoryName, entry.commitId, entry.path))
                      .setEnabled(!entry.changeType.equals(ChangeType.ADD)));
            }

            WicketUtils.setAlternatingBackground(item, counter);
            counter++;
          }
        };
    add(pathsView);
    add(new Label("diffText", diff.content).setEscapeModelStrings(false));
  }