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 <spearce@spearce.org>
This commit is contained in:
Shawn O. Pearce 2010-08-24 15:50:36 -07:00
parent 127a5f95e1
commit c44495fa2f
5 changed files with 144 additions and 9 deletions

View File

@ -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.

View File

@ -71,6 +71,7 @@ public static JGitText get() {
/***/ public String advertisementOfCameBefore;
/***/ public String amazonS3ActionFailed;
/***/ public String amazonS3ActionFailedGivingUp;
/***/ public String ambiguousObjectAbbreviation;
/***/ public String anExceptionOccurredWhileTryingToAddTheIdOfHEAD;
/***/ public String anSSHSessionHasBeenAlreadyCreated;
/***/ public String atLeastOnePathIsRequired;

View File

@ -51,15 +51,18 @@
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 void format(DiffEntry ent) throws IOException {
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 @@ private static String quotePath(String name) {
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<ObjectId> 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 FileHeader createFileHeader(DiffEntry ent) throws IOException,
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"));

View File

@ -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<ObjectId> 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<ObjectId> 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<ObjectId> getCandidates() {
return candidates;
}
}

View File

@ -50,6 +50,7 @@
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 MissingObjectException(final ObjectId id, final int type) {
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;