From c44495fa2f6ac0b06dc974d1b6626cf52380ea2c Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Tue, 24 Aug 2010 15:50:36 -0700 Subject: [PATCH] Complete an abbreviation when formatting a patch If we are given a DiffEntry header that already has abbreviated ObjectIds on it, we may still be able to resolve those locally and output the difference. Try to do that through the new resolve API on ObjectReader. Change-Id: I0766aa5444b7b8fff73620290f8c9f54adc0be96 Signed-off-by: Shawn O. Pearce --- .../org/eclipse/jgit/JGitText.properties | 1 + .../src/org/eclipse/jgit/JGitText.java | 1 + .../org/eclipse/jgit/diff/DiffFormatter.java | 47 ++++++++-- .../jgit/errors/AmbiguousObjectException.java | 88 +++++++++++++++++++ .../jgit/errors/MissingObjectException.java | 16 ++++ 5 files changed, 144 insertions(+), 9 deletions(-) create mode 100644 org.eclipse.jgit/src/org/eclipse/jgit/errors/AmbiguousObjectException.java diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties index 58adf332d3..b6cfd84b1e 100644 --- a/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties +++ b/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties @@ -11,6 +11,7 @@ advertisementCameBefore=advertisement of {0}^{} came before {1} advertisementOfCameBefore=advertisement of {0}^{} came before {1} amazonS3ActionFailed={0} of '{1}' failed: {2} {3} amazonS3ActionFailedGivingUp={0} of '{1}' failed: Giving up after {2} attempts. +ambiguousObjectAbbreviation=Object abbreviation {0} is ambiguous anExceptionOccurredWhileTryingToAddTheIdOfHEAD=An exception occurred while trying to add the Id of HEAD anSSHSessionHasBeenAlreadyCreated=An SSH session has been already created atLeastOnePathIsRequired=At least one path is required. diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java index f7eea3fe9f..800984c4b7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java @@ -71,6 +71,7 @@ public class JGitText extends TranslationBundle { /***/ public String advertisementOfCameBefore; /***/ public String amazonS3ActionFailed; /***/ public String amazonS3ActionFailedGivingUp; + /***/ public String ambiguousObjectAbbreviation; /***/ public String anExceptionOccurredWhileTryingToAddTheIdOfHEAD; /***/ public String anSSHSessionHasBeenAlreadyCreated; /***/ public String atLeastOnePathIsRequired; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java index c80202ad1c..6f761d0366 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java @@ -51,15 +51,18 @@ import static org.eclipse.jgit.lib.FileMode.GITLINK; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.util.Collection; import java.util.List; import org.eclipse.jgit.JGitText; +import org.eclipse.jgit.errors.AmbiguousObjectException; import org.eclipse.jgit.errors.CorruptObjectException; import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.lib.AbbreviatedObjectId; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.CoreConfig; import org.eclipse.jgit.lib.FileMode; +import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectLoader; import org.eclipse.jgit.lib.ObjectReader; import org.eclipse.jgit.lib.Repository; @@ -216,8 +219,18 @@ public class DiffFormatter { if (ent.getOldMode() == GITLINK || ent.getNewMode() == GITLINK) { writeGitLinkDiffText(out, ent); } else { - byte[] aRaw = open(ent.getOldMode(), ent.getOldId()); - byte[] bRaw = open(ent.getNewMode(), ent.getNewId()); + if (db == null) + throw new IllegalStateException( + JGitText.get().repositoryIsRequired); + + ObjectReader reader = db.newObjectReader(); + byte[] aRaw, bRaw; + try { + aRaw = open(reader, ent.getOldMode(), ent.getOldId()); + bRaw = open(reader, ent.getNewMode(), ent.getNewId()); + } finally { + reader.release(); + } if (RawText.isBinary(aRaw) || RawText.isBinary(bRaw)) { out.write(encodeASCII("Binary files differ\n")); @@ -344,18 +357,25 @@ public class DiffFormatter { return ('"' + name + '"').equals(q) ? name : q; } - private byte[] open(FileMode mode, AbbreviatedObjectId id) - throws IOException { + private byte[] open(ObjectReader reader, FileMode mode, + AbbreviatedObjectId id) throws IOException { if (mode == FileMode.MISSING) return new byte[] {}; if (mode.getObjectType() != Constants.OBJ_BLOB) return new byte[] {}; - if (db == null) - throw new IllegalStateException(JGitText.get().repositoryIsRequired); + if (!id.isComplete()) { + Collection ids = reader.resolve(id); + if (ids.size() == 1) + id = AbbreviatedObjectId.fromObjectId(ids.iterator().next()); + else if (ids.size() == 0) + throw new MissingObjectException(id, Constants.OBJ_BLOB); + else + throw new AmbiguousObjectException(id, ids); + } - ObjectLoader ldr = db.open(id.toObjectId()); + ObjectLoader ldr = reader.open(id.toObjectId()); return ldr.getCachedBytes(bigFileThreshold); } @@ -596,8 +616,17 @@ public class DiffFormatter { editList = new EditList(); type = PatchType.UNIFIED; } else { - byte[] aRaw = open(ent.getOldMode(), ent.getOldId()); - byte[] bRaw = open(ent.getNewMode(), ent.getNewId()); + if (db == null) + throw new IllegalStateException( + JGitText.get().repositoryIsRequired); + ObjectReader reader = db.newObjectReader(); + byte[] aRaw, bRaw; + try { + aRaw = open(reader, ent.getOldMode(), ent.getOldId()); + bRaw = open(reader, ent.getNewMode(), ent.getNewId()); + } finally { + reader.release(); + } if (RawText.isBinary(aRaw) || RawText.isBinary(bRaw)) { buf.write(encodeASCII("Binary files differ\n")); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/errors/AmbiguousObjectException.java b/org.eclipse.jgit/src/org/eclipse/jgit/errors/AmbiguousObjectException.java new file mode 100644 index 0000000000..0c59ae2891 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/errors/AmbiguousObjectException.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2010, Google Inc. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.errors; + +import java.io.IOException; +import java.text.MessageFormat; +import java.util.Collection; + +import org.eclipse.jgit.JGitText; +import org.eclipse.jgit.lib.AbbreviatedObjectId; +import org.eclipse.jgit.lib.ObjectId; + +/** An {@link AbbreviatedObjectId} cannot be extended. */ +public class AmbiguousObjectException extends IOException { + private static final long serialVersionUID = 1L; + + private final AbbreviatedObjectId missing; + + private final Collection candidates; + + /** + * Construct a MissingObjectException for the specified object id. Expected + * type is reported to simplify tracking down the problem. + * + * @param id + * SHA-1 + * @param candidates + * the candidate matches returned by the ObjectReader. + */ + public AmbiguousObjectException(final AbbreviatedObjectId id, + final Collection candidates) { + super(MessageFormat.format(JGitText.get().ambiguousObjectAbbreviation, + id.name())); + this.missing = id; + this.candidates = candidates; + } + + /** @return the AbbreviatedObjectId that has more than one result. */ + public AbbreviatedObjectId getAbbreviatedObjectId() { + return missing; + } + + /** @return the matching candidates (or at least a subset of them). */ + public Collection getCandidates() { + return candidates; + } +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/errors/MissingObjectException.java b/org.eclipse.jgit/src/org/eclipse/jgit/errors/MissingObjectException.java index 1807a6cfc5..f95e8e2e63 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/errors/MissingObjectException.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/errors/MissingObjectException.java @@ -50,6 +50,7 @@ import java.io.IOException; import java.text.MessageFormat; import org.eclipse.jgit.JGitText; +import org.eclipse.jgit.lib.AbbreviatedObjectId; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; @@ -84,6 +85,21 @@ public class MissingObjectException extends IOException { this(id, Constants.typeString(type)); } + /** + * Construct a MissingObjectException for the specified object id. Expected + * type is reported to simplify tracking down the problem. + * + * @param id + * SHA-1 + * @param type + * object type + */ + public MissingObjectException(final AbbreviatedObjectId id, final int type) { + super(MessageFormat.format(JGitText.get().missingObject, Constants + .typeString(type), id.name())); + missing = null; + } + /** @return the ObjectId that was not found. */ public ObjectId getObjectId() { return missing; -- 2.39.5