This change fixes all compiler errors in JGit and replaces possible NPE's with either appropriate exceptions, avoiding multiple "Nullable return" method calls or early returning from the method. Change-Id: I24c8a600ec962d61d5f40abf73eac4203e115240 Signed-off-by: Andrey Loskutov <loskutov@gmx.de>tags/v4.2.0.201601211800-r
break; | break; | ||||
case FAST_FORWARD: | case FAST_FORWARD: | ||||
ObjectId oldHeadId = oldHead.getObjectId(); | ObjectId oldHeadId = oldHead.getObjectId(); | ||||
outw.println(MessageFormat.format(CLIText.get().updating, oldHeadId | |||||
.abbreviate(7).name(), result.getNewHead().abbreviate(7) | |||||
.name())); | |||||
if (oldHeadId != null) { | |||||
String oldId = oldHeadId.abbreviate(7).name(); | |||||
String newId = result.getNewHead().abbreviate(7).name(); | |||||
outw.println(MessageFormat.format(CLIText.get().updating, oldId, | |||||
newId)); | |||||
} | |||||
outw.println(result.getMergeStatus().toString()); | outw.println(result.getMergeStatus().toString()); | ||||
break; | break; | ||||
case CHECKOUT_CONFLICT: | case CHECKOUT_CONFLICT: |
if (all) { | if (all) { | ||||
Map<String, Ref> allRefs = db.getRefDatabase().getRefs(ALL); | Map<String, Ref> allRefs = db.getRefDatabase().getRefs(ALL); | ||||
for (final Ref r : allRefs.values()) { | for (final Ref r : allRefs.values()) { | ||||
outw.println(r.getObjectId().name()); | |||||
ObjectId objectId = r.getObjectId(); | |||||
// getRefs skips dangling symrefs, so objectId should never be | |||||
// null. | |||||
if (objectId == null) { | |||||
throw new NullPointerException(); | |||||
} | |||||
outw.println(objectId.name()); | |||||
} | } | ||||
} else { | } else { | ||||
if (verify && commits.size() > 1) { | if (verify && commits.size() > 1) { |
cannotStoreObjects=cannot store objects | cannotStoreObjects=cannot store objects | ||||
cannotResolveUniquelyAbbrevObjectId=Could not resolve uniquely the abbreviated object ID | cannotResolveUniquelyAbbrevObjectId=Could not resolve uniquely the abbreviated object ID | ||||
cannotUnloadAModifiedTree=Cannot unload a modified tree. | cannotUnloadAModifiedTree=Cannot unload a modified tree. | ||||
cannotUpdateUnbornBranch=Cannot update unborn branch | |||||
cannotWorkWithOtherStagesThanZeroRightNow=Cannot work with other stages than zero right now. Won't write corrupt index. | cannotWorkWithOtherStagesThanZeroRightNow=Cannot work with other stages than zero right now. Won't write corrupt index. | ||||
cannotWriteObjectsPath=Cannot write {0}/{1}: {2} | cannotWriteObjectsPath=Cannot write {0}/{1}: {2} | ||||
canOnlyCherryPickCommitsWithOneParent=Cannot cherry-pick commit ''{0}'' because it has {1} parents, only commits with exactly one parent are supported. | canOnlyCherryPickCommitsWithOneParent=Cannot cherry-pick commit ''{0}'' because it has {1} parents, only commits with exactly one parent are supported. | ||||
transportExceptionMissingAssumed=Missing assumed {0} | transportExceptionMissingAssumed=Missing assumed {0} | ||||
transportExceptionReadRef=read {0} | transportExceptionReadRef=read {0} | ||||
transportNeedsRepository=Transport needs repository | transportNeedsRepository=Transport needs repository | ||||
transportProvidedRefWithNoObjectId=Transport provided ref {0} with no object id | |||||
transportProtoAmazonS3=Amazon S3 | transportProtoAmazonS3=Amazon S3 | ||||
transportProtoBundleFile=Git Bundle File | transportProtoBundleFile=Git Bundle File | ||||
transportProtoFTP=FTP | transportProtoFTP=FTP |
} | } | ||||
private String getShortBranchName(Ref headRef) { | private String getShortBranchName(Ref headRef) { | ||||
if (headRef.getTarget().getName().equals(headRef.getName())) | |||||
return headRef.getTarget().getObjectId().getName(); | |||||
return Repository.shortenRefName(headRef.getTarget().getName()); | |||||
if (headRef.isSymbolic()) { | |||||
return Repository.shortenRefName(headRef.getTarget().getName()); | |||||
} | |||||
// Detached HEAD. Every non-symbolic ref in the ref database has an | |||||
// object id, so this cannot be null. | |||||
ObjectId id = headRef.getObjectId(); | |||||
if (id == null) { | |||||
throw new NullPointerException(); | |||||
} | |||||
return id.getName(); | |||||
} | } | ||||
/** | /** |
import org.eclipse.jgit.lib.ConfigConstants; | import org.eclipse.jgit.lib.ConfigConstants; | ||||
import org.eclipse.jgit.lib.Constants; | import org.eclipse.jgit.lib.Constants; | ||||
import org.eclipse.jgit.lib.NullProgressMonitor; | import org.eclipse.jgit.lib.NullProgressMonitor; | ||||
import org.eclipse.jgit.lib.ObjectId; | |||||
import org.eclipse.jgit.lib.ProgressMonitor; | import org.eclipse.jgit.lib.ProgressMonitor; | ||||
import org.eclipse.jgit.lib.Ref; | import org.eclipse.jgit.lib.Ref; | ||||
import org.eclipse.jgit.lib.RefUpdate; | import org.eclipse.jgit.lib.RefUpdate; | ||||
} | } | ||||
if (head == null || head.getObjectId() == null) | if (head == null || head.getObjectId() == null) | ||||
return; // throw exception? | |||||
return; // TODO throw exception? | |||||
if (head.getName().startsWith(Constants.R_HEADS)) { | if (head.getName().startsWith(Constants.R_HEADS)) { | ||||
final RefUpdate newHead = clonedRepo.updateRef(Constants.HEAD); | final RefUpdate newHead = clonedRepo.updateRef(Constants.HEAD); | ||||
private Ref findBranchToCheckout(FetchResult result) { | private Ref findBranchToCheckout(FetchResult result) { | ||||
final Ref idHEAD = result.getAdvertisedRef(Constants.HEAD); | final Ref idHEAD = result.getAdvertisedRef(Constants.HEAD); | ||||
if (idHEAD == null) | |||||
ObjectId headId = idHEAD != null ? idHEAD.getObjectId() : null; | |||||
if (headId == null) { | |||||
return null; | return null; | ||||
} | |||||
Ref master = result.getAdvertisedRef(Constants.R_HEADS | Ref master = result.getAdvertisedRef(Constants.R_HEADS | ||||
+ Constants.MASTER); | + Constants.MASTER); | ||||
if (master != null && master.getObjectId().equals(idHEAD.getObjectId())) | |||||
ObjectId objectId = master != null ? master.getObjectId() : null; | |||||
if (headId.equals(objectId)) { | |||||
return master; | return master; | ||||
} | |||||
Ref foundBranch = null; | Ref foundBranch = null; | ||||
for (final Ref r : result.getAdvertisedRefs()) { | for (final Ref r : result.getAdvertisedRefs()) { | ||||
final String n = r.getName(); | final String n = r.getName(); | ||||
if (!n.startsWith(Constants.R_HEADS)) | if (!n.startsWith(Constants.R_HEADS)) | ||||
continue; | continue; | ||||
if (r.getObjectId().equals(idHEAD.getObjectId())) { | |||||
if (headId.equals(r.getObjectId())) { | |||||
foundBranch = r; | foundBranch = r; | ||||
break; | break; | ||||
} | } |
lastStepWasForward = newHead != null; | lastStepWasForward = newHead != null; | ||||
if (!lastStepWasForward) { | if (!lastStepWasForward) { | ||||
ObjectId headId = getHead().getObjectId(); | ObjectId headId = getHead().getObjectId(); | ||||
// getHead() checks for null | |||||
assert headId != null; | |||||
if (!AnyObjectId.equals(headId, newParents.get(0))) | if (!AnyObjectId.equals(headId, newParents.get(0))) | ||||
checkoutCommit(headId.getName(), newParents.get(0)); | checkoutCommit(headId.getName(), newParents.get(0)); | ||||
return; | return; | ||||
ObjectId headId = getHead().getObjectId(); | ObjectId headId = getHead().getObjectId(); | ||||
// getHead() checks for null | |||||
assert headId != null; | |||||
String head = headId.getName(); | String head = headId.getName(); | ||||
String currentCommits = rebaseState.readFile(CURRENT_COMMIT); | String currentCommits = rebaseState.readFile(CURRENT_COMMIT); | ||||
for (String current : currentCommits.split("\n")) //$NON-NLS-1$ | for (String current : currentCommits.split("\n")) //$NON-NLS-1$ | ||||
Ref head = getHead(); | Ref head = getHead(); | ||||
String headName = getHeadName(head); | |||||
ObjectId headId = head.getObjectId(); | ObjectId headId = head.getObjectId(); | ||||
if (headId == null) | |||||
if (headId == null) { | |||||
throw new RefNotFoundException(MessageFormat.format( | throw new RefNotFoundException(MessageFormat.format( | ||||
JGitText.get().refNotResolved, Constants.HEAD)); | JGitText.get().refNotResolved, Constants.HEAD)); | ||||
} | |||||
String headName = getHeadName(head); | |||||
RevCommit headCommit = walk.lookupCommit(headId); | RevCommit headCommit = walk.lookupCommit(headId); | ||||
RevCommit upstream = walk.lookupCommit(upstreamCommit.getId()); | RevCommit upstream = walk.lookupCommit(upstreamCommit.getId()); | ||||
private static String getHeadName(Ref head) { | private static String getHeadName(Ref head) { | ||||
String headName; | String headName; | ||||
if (head.isSymbolic()) | |||||
if (head.isSymbolic()) { | |||||
headName = head.getTarget().getName(); | headName = head.getTarget().getName(); | ||||
else | |||||
headName = head.getObjectId().getName(); | |||||
} else { | |||||
ObjectId headId = head.getObjectId(); | |||||
// the callers are checking this already | |||||
assert headId != null; | |||||
headName = headId.getName(); | |||||
} | |||||
return headName; | return headName; | ||||
} | } | ||||
/***/ public String cannotStoreObjects; | /***/ public String cannotStoreObjects; | ||||
/***/ public String cannotResolveUniquelyAbbrevObjectId; | /***/ public String cannotResolveUniquelyAbbrevObjectId; | ||||
/***/ public String cannotUnloadAModifiedTree; | /***/ public String cannotUnloadAModifiedTree; | ||||
/***/ public String cannotUpdateUnbornBranch; | |||||
/***/ public String cannotWorkWithOtherStagesThanZeroRightNow; | /***/ public String cannotWorkWithOtherStagesThanZeroRightNow; | ||||
/***/ public String cannotWriteObjectsPath; | /***/ public String cannotWriteObjectsPath; | ||||
/***/ public String canOnlyCherryPickCommitsWithOneParent; | /***/ public String canOnlyCherryPickCommitsWithOneParent; | ||||
/***/ public String transportProtoSFTP; | /***/ public String transportProtoSFTP; | ||||
/***/ public String transportProtoSSH; | /***/ public String transportProtoSSH; | ||||
/***/ public String transportProtoTest; | /***/ public String transportProtoTest; | ||||
/***/ public String transportProvidedRefWithNoObjectId; | |||||
/***/ public String transportSSHRetryInterrupt; | /***/ public String transportSSHRetryInterrupt; | ||||
/***/ public String treeEntryAlreadyExists; | /***/ public String treeEntryAlreadyExists; | ||||
/***/ public String treeFilterMarkerTooManyFilters; | /***/ public String treeFilterMarkerTooManyFilters; |
reject(cmds); | reject(cmds); | ||||
return; | return; | ||||
} | } | ||||
} else if (r.isSymbolic() || r.getObjectId() == null | |||||
|| !r.getObjectId().equals(c.getOldId())) { | |||||
c.setResult(ReceiveCommand.Result.LOCK_FAILURE); | |||||
reject(cmds); | |||||
return; | |||||
} else { | |||||
ObjectId objectId = r.getObjectId(); | |||||
if (r.isSymbolic() || objectId == null | |||||
|| !objectId.equals(c.getOldId())) { | |||||
c.setResult(ReceiveCommand.Result.LOCK_FAILURE); | |||||
reject(cmds); | |||||
return; | |||||
} | |||||
} | } | ||||
} | } | ||||
import java.util.List; | import java.util.List; | ||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.Map.Entry; | import java.util.Map.Entry; | ||||
import java.util.Objects; | |||||
import java.util.Set; | import java.util.Set; | ||||
import java.util.TreeMap; | import java.util.TreeMap; | ||||
return false; | return false; | ||||
return r1.getTarget().getName().equals(r2.getTarget().getName()); | return r1.getTarget().getName().equals(r2.getTarget().getName()); | ||||
} else { | } else { | ||||
if (r2.isSymbolic()) | |||||
if (r2.isSymbolic()) { | |||||
return false; | return false; | ||||
return r1.getObjectId().equals(r2.getObjectId()); | |||||
} | |||||
return Objects.equals(r1.getObjectId(), r2.getObjectId()); | |||||
} | } | ||||
} | } | ||||
import java.util.concurrent.atomic.AtomicInteger; | import java.util.concurrent.atomic.AtomicInteger; | ||||
import java.util.concurrent.atomic.AtomicReference; | import java.util.concurrent.atomic.AtomicReference; | ||||
import org.eclipse.jgit.annotations.NonNull; | |||||
import org.eclipse.jgit.errors.InvalidObjectIdException; | import org.eclipse.jgit.errors.InvalidObjectIdException; | ||||
import org.eclipse.jgit.errors.LockFailedException; | import org.eclipse.jgit.errors.LockFailedException; | ||||
import org.eclipse.jgit.errors.MissingObjectException; | import org.eclipse.jgit.errors.MissingObjectException; | ||||
*/ | */ | ||||
private Ref peeledPackedRef(Ref f) | private Ref peeledPackedRef(Ref f) | ||||
throws MissingObjectException, IOException { | throws MissingObjectException, IOException { | ||||
if (f.getStorage().isPacked() && f.isPeeled()) | |||||
if (f.getStorage().isPacked() && f.isPeeled()) { | |||||
return f; | return f; | ||||
if (!f.isPeeled()) | |||||
} | |||||
if (!f.isPeeled()) { | |||||
f = peel(f); | f = peel(f); | ||||
if (f.getPeeledObjectId() != null) | |||||
} | |||||
ObjectId peeledObjectId = f.getPeeledObjectId(); | |||||
if (peeledObjectId != null) { | |||||
return new ObjectIdRef.PeeledTag(PACKED, f.getName(), | return new ObjectIdRef.PeeledTag(PACKED, f.getName(), | ||||
f.getObjectId(), f.getPeeledObjectId()); | |||||
else | |||||
f.getObjectId(), peeledObjectId); | |||||
} else { | |||||
return new ObjectIdRef.PeeledNonTag(PACKED, f.getName(), | return new ObjectIdRef.PeeledNonTag(PACKED, f.getName(), | ||||
f.getObjectId()); | f.getObjectId()); | ||||
} | |||||
} | } | ||||
void log(final RefUpdate update, final String msg, final boolean deref) | void log(final RefUpdate update, final String msg, final boolean deref) | ||||
try { | try { | ||||
id = ObjectId.fromString(buf, 0); | id = ObjectId.fromString(buf, 0); | ||||
if (ref != null && !ref.isSymbolic() | if (ref != null && !ref.isSymbolic() | ||||
&& ref.getTarget().getObjectId().equals(id)) { | |||||
&& id.equals(ref.getTarget().getObjectId())) { | |||||
assert(currentSnapshot != null); | assert(currentSnapshot != null); | ||||
currentSnapshot.setClean(otherSnapshot); | currentSnapshot.setClean(otherSnapshot); | ||||
return ref; | return ref; | ||||
implements LooseRef { | implements LooseRef { | ||||
private final FileSnapshot snapShot; | private final FileSnapshot snapShot; | ||||
LoosePeeledTag(FileSnapshot snapshot, String refName, ObjectId id, | |||||
ObjectId p) { | |||||
LoosePeeledTag(FileSnapshot snapshot, @NonNull String refName, | |||||
@NonNull ObjectId id, @NonNull ObjectId p) { | |||||
super(LOOSE, refName, id, p); | super(LOOSE, refName, id, p); | ||||
this.snapShot = snapshot; | this.snapShot = snapshot; | ||||
} | } | ||||
implements LooseRef { | implements LooseRef { | ||||
private final FileSnapshot snapShot; | private final FileSnapshot snapShot; | ||||
LooseNonTag(FileSnapshot snapshot, String refName, ObjectId id) { | |||||
LooseNonTag(FileSnapshot snapshot, @NonNull String refName, | |||||
@NonNull ObjectId id) { | |||||
super(LOOSE, refName, id); | super(LOOSE, refName, id); | ||||
this.snapShot = snapshot; | this.snapShot = snapshot; | ||||
} | } | ||||
implements LooseRef { | implements LooseRef { | ||||
private FileSnapshot snapShot; | private FileSnapshot snapShot; | ||||
LooseUnpeeled(FileSnapshot snapShot, String refName, ObjectId id) { | |||||
LooseUnpeeled(FileSnapshot snapShot, @NonNull String refName, | |||||
@NonNull ObjectId id) { | |||||
super(LOOSE, refName, id); | super(LOOSE, refName, id); | ||||
this.snapShot = snapShot; | this.snapShot = snapShot; | ||||
} | } | ||||
return snapShot; | return snapShot; | ||||
} | } | ||||
@NonNull | |||||
@Override | |||||
public ObjectId getObjectId() { | |||||
ObjectId id = super.getObjectId(); | |||||
assert id != null; // checked in constructor | |||||
return id; | |||||
} | |||||
public LooseRef peel(ObjectIdRef newLeaf) { | public LooseRef peel(ObjectIdRef newLeaf) { | ||||
if (newLeaf.getPeeledObjectId() != null) | |||||
ObjectId peeledObjectId = newLeaf.getPeeledObjectId(); | |||||
ObjectId objectId = getObjectId(); | |||||
if (peeledObjectId != null) { | |||||
return new LoosePeeledTag(snapShot, getName(), | return new LoosePeeledTag(snapShot, getName(), | ||||
getObjectId(), newLeaf.getPeeledObjectId()); | |||||
else | |||||
objectId, peeledObjectId); | |||||
} else { | |||||
return new LooseNonTag(snapShot, getName(), | return new LooseNonTag(snapShot, getName(), | ||||
getObjectId()); | |||||
objectId); | |||||
} | |||||
} | } | ||||
} | } | ||||
LooseRef { | LooseRef { | ||||
private final FileSnapshot snapShot; | private final FileSnapshot snapShot; | ||||
LooseSymbolicRef(FileSnapshot snapshot, String refName, Ref target) { | |||||
LooseSymbolicRef(FileSnapshot snapshot, @NonNull String refName, | |||||
@NonNull Ref target) { | |||||
super(refName, target); | super(refName, target); | ||||
this.snapShot = snapshot; | this.snapShot = snapshot; | ||||
} | } |
package org.eclipse.jgit.lib; | package org.eclipse.jgit.lib; | ||||
import org.eclipse.jgit.annotations.NonNull; | |||||
import org.eclipse.jgit.annotations.Nullable; | |||||
/** A {@link Ref} that points directly at an {@link ObjectId}. */ | /** A {@link Ref} that points directly at an {@link ObjectId}. */ | ||||
public abstract class ObjectIdRef implements Ref { | public abstract class ObjectIdRef implements Ref { | ||||
/** Any reference whose peeled value is not yet known. */ | /** Any reference whose peeled value is not yet known. */ | ||||
* @param name | * @param name | ||||
* name of this ref. | * name of this ref. | ||||
* @param id | * @param id | ||||
* current value of the ref. May be null to indicate a ref | |||||
* that does not exist yet. | |||||
* current value of the ref. May be {@code null} to indicate | |||||
* a ref that does not exist yet. | |||||
*/ | */ | ||||
public Unpeeled(Storage st, String name, ObjectId id) { | |||||
public Unpeeled(@NonNull Storage st, @NonNull String name, | |||||
@Nullable ObjectId id) { | |||||
super(st, name, id); | super(st, name, id); | ||||
} | } | ||||
@Nullable | |||||
public ObjectId getPeeledObjectId() { | public ObjectId getPeeledObjectId() { | ||||
return null; | return null; | ||||
} | } | ||||
* @param p | * @param p | ||||
* the first non-tag object that tag {@code id} points to. | * the first non-tag object that tag {@code id} points to. | ||||
*/ | */ | ||||
public PeeledTag(Storage st, String name, ObjectId id, ObjectId p) { | |||||
public PeeledTag(@NonNull Storage st, @NonNull String name, | |||||
@Nullable ObjectId id, @NonNull ObjectId p) { | |||||
super(st, name, id); | super(st, name, id); | ||||
peeledObjectId = p; | peeledObjectId = p; | ||||
} | } | ||||
@NonNull | |||||
public ObjectId getPeeledObjectId() { | public ObjectId getPeeledObjectId() { | ||||
return peeledObjectId; | return peeledObjectId; | ||||
} | } | ||||
* @param name | * @param name | ||||
* name of this ref. | * name of this ref. | ||||
* @param id | * @param id | ||||
* current value of the ref. May be null to indicate a ref | |||||
* that does not exist yet. | |||||
* current value of the ref. May be {@code null} to indicate | |||||
* a ref that does not exist yet. | |||||
*/ | */ | ||||
public PeeledNonTag(Storage st, String name, ObjectId id) { | |||||
public PeeledNonTag(@NonNull Storage st, @NonNull String name, | |||||
@Nullable ObjectId id) { | |||||
super(st, name, id); | super(st, name, id); | ||||
} | } | ||||
@Nullable | |||||
public ObjectId getPeeledObjectId() { | public ObjectId getPeeledObjectId() { | ||||
return null; | return null; | ||||
} | } | ||||
* @param name | * @param name | ||||
* name of this ref. | * name of this ref. | ||||
* @param id | * @param id | ||||
* current value of the ref. May be null to indicate a ref that | |||||
* does not exist yet. | |||||
* current value of the ref. May be {@code null} to indicate a | |||||
* ref that does not exist yet. | |||||
*/ | */ | ||||
protected ObjectIdRef(Storage st, String name, ObjectId id) { | |||||
protected ObjectIdRef(@NonNull Storage st, @NonNull String name, | |||||
@Nullable ObjectId id) { | |||||
this.name = name; | this.name = name; | ||||
this.storage = st; | this.storage = st; | ||||
this.objectId = id; | this.objectId = id; | ||||
} | } | ||||
@NonNull | |||||
public String getName() { | public String getName() { | ||||
return name; | return name; | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
@NonNull | |||||
public Ref getLeaf() { | public Ref getLeaf() { | ||||
return this; | return this; | ||||
} | } | ||||
@NonNull | |||||
public Ref getTarget() { | public Ref getTarget() { | ||||
return this; | return this; | ||||
} | } | ||||
@Nullable | |||||
public ObjectId getObjectId() { | public ObjectId getObjectId() { | ||||
return objectId; | return objectId; | ||||
} | } | ||||
@NonNull | |||||
public Storage getStorage() { | public Storage getStorage() { | ||||
return storage; | return storage; | ||||
} | } | ||||
@NonNull | |||||
@Override | @Override | ||||
public String toString() { | public String toString() { | ||||
StringBuilder r = new StringBuilder(); | StringBuilder r = new StringBuilder(); |
package org.eclipse.jgit.lib; | package org.eclipse.jgit.lib; | ||||
import org.eclipse.jgit.annotations.NonNull; | |||||
import org.eclipse.jgit.annotations.Nullable; | |||||
/** | /** | ||||
* Pairing of a name and the {@link ObjectId} it currently has. | * Pairing of a name and the {@link ObjectId} it currently has. | ||||
* <p> | * <p> | ||||
* | * | ||||
* @return name of this ref. | * @return name of this ref. | ||||
*/ | */ | ||||
@NonNull | |||||
public String getName(); | public String getName(); | ||||
/** | /** | ||||
* | * | ||||
* @return the reference that actually stores the ObjectId value. | * @return the reference that actually stores the ObjectId value. | ||||
*/ | */ | ||||
@NonNull | |||||
public abstract Ref getLeaf(); | public abstract Ref getLeaf(); | ||||
/** | /** | ||||
* | * | ||||
* @return the target reference, or {@code this}. | * @return the target reference, or {@code this}. | ||||
*/ | */ | ||||
@NonNull | |||||
public abstract Ref getTarget(); | public abstract Ref getTarget(); | ||||
/** | /** | ||||
* Cached value of this ref. | * Cached value of this ref. | ||||
* | * | ||||
* @return the value of this ref at the last time we read it. | |||||
* @return the value of this ref at the last time we read it. May be | |||||
* {@code null} to indicate a ref that does not exist yet or a | |||||
* symbolic ref pointing to an unborn branch. | |||||
*/ | */ | ||||
@Nullable | |||||
public abstract ObjectId getObjectId(); | public abstract ObjectId getObjectId(); | ||||
/** | /** | ||||
* Cached value of <code>ref^{}</code> (the ref peeled to commit). | * Cached value of <code>ref^{}</code> (the ref peeled to commit). | ||||
* | * | ||||
* @return if this ref is an annotated tag the id of the commit (or tree or | * @return if this ref is an annotated tag the id of the commit (or tree or | ||||
* blob) that the annotated tag refers to; null if this ref does not | |||||
* refer to an annotated tag. | |||||
* blob) that the annotated tag refers to; {@code null} if this ref | |||||
* does not refer to an annotated tag. | |||||
*/ | */ | ||||
@Nullable | |||||
public abstract ObjectId getPeeledObjectId(); | public abstract ObjectId getPeeledObjectId(); | ||||
/** | /** | ||||
* | * | ||||
* @return type of ref. | * @return type of ref. | ||||
*/ | */ | ||||
@NonNull | |||||
public abstract Storage getStorage(); | public abstract Storage getStorage(); | ||||
} | } |
continue; | continue; | ||||
} | } | ||||
r.getObjectId().copyTo(tmp, w); | |||||
ObjectId objectId = r.getObjectId(); | |||||
if (objectId == null) { | |||||
// Symrefs to unborn branches aren't advertised in the info/refs | |||||
// file. | |||||
continue; | |||||
} | |||||
objectId.copyTo(tmp, w); | |||||
w.write('\t'); | w.write('\t'); | ||||
w.write(r.getName()); | w.write(r.getName()); | ||||
w.write('\n'); | w.write('\n'); | ||||
if (r.getPeeledObjectId() != null) { | |||||
r.getPeeledObjectId().copyTo(tmp, w); | |||||
ObjectId peeledObjectId = r.getPeeledObjectId(); | |||||
if (peeledObjectId != null) { | |||||
peeledObjectId.copyTo(tmp, w); | |||||
w.write('\t'); | w.write('\t'); | ||||
w.write(r.getName()); | w.write(r.getName()); | ||||
w.write("^{}\n"); //$NON-NLS-1$ | w.write("^{}\n"); //$NON-NLS-1$ | ||||
if (r.getStorage() != Ref.Storage.PACKED) | if (r.getStorage() != Ref.Storage.PACKED) | ||||
continue; | continue; | ||||
r.getObjectId().copyTo(tmp, w); | |||||
ObjectId objectId = r.getObjectId(); | |||||
if (objectId == null) { | |||||
// A packed ref cannot be a symref, let alone a symref | |||||
// to an unborn branch. | |||||
throw new NullPointerException(); | |||||
} | |||||
objectId.copyTo(tmp, w); | |||||
w.write(' '); | w.write(' '); | ||||
w.write(r.getName()); | w.write(r.getName()); | ||||
w.write('\n'); | w.write('\n'); | ||||
if (r.getPeeledObjectId() != null) { | |||||
ObjectId peeledObjectId = r.getPeeledObjectId(); | |||||
if (peeledObjectId != null) { | |||||
w.write('^'); | w.write('^'); | ||||
r.getPeeledObjectId().copyTo(tmp, w); | |||||
peeledObjectId.copyTo(tmp, w); | |||||
w.write('\n'); | w.write('\n'); | ||||
} | } | ||||
} | } |
@Nullable | @Nullable | ||||
public String getFullBranch() throws IOException { | public String getFullBranch() throws IOException { | ||||
Ref head = getRef(Constants.HEAD); | Ref head = getRef(Constants.HEAD); | ||||
if (head == null) | |||||
if (head == null) { | |||||
return null; | return null; | ||||
if (head.isSymbolic()) | |||||
} | |||||
if (head.isSymbolic()) { | |||||
return head.getTarget().getName(); | return head.getTarget().getName(); | ||||
if (head.getObjectId() != null) | |||||
return head.getObjectId().name(); | |||||
} | |||||
ObjectId objectId = head.getObjectId(); | |||||
if (objectId != null) { | |||||
return objectId.name(); | |||||
} | |||||
return null; | return null; | ||||
} | } | ||||
package org.eclipse.jgit.lib; | package org.eclipse.jgit.lib; | ||||
import org.eclipse.jgit.annotations.NonNull; | |||||
import org.eclipse.jgit.annotations.Nullable; | |||||
/** | /** | ||||
* A reference that indirectly points at another {@link Ref}. | * A reference that indirectly points at another {@link Ref}. | ||||
* <p> | * <p> | ||||
* @param target | * @param target | ||||
* the ref we reference and derive our value from. | * the ref we reference and derive our value from. | ||||
*/ | */ | ||||
public SymbolicRef(String refName, Ref target) { | |||||
public SymbolicRef(@NonNull String refName, @NonNull Ref target) { | |||||
this.name = refName; | this.name = refName; | ||||
this.target = target; | this.target = target; | ||||
} | } | ||||
@NonNull | |||||
public String getName() { | public String getName() { | ||||
return name; | return name; | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
@NonNull | |||||
public Ref getLeaf() { | public Ref getLeaf() { | ||||
Ref dst = getTarget(); | Ref dst = getTarget(); | ||||
while (dst.isSymbolic()) | while (dst.isSymbolic()) | ||||
return dst; | return dst; | ||||
} | } | ||||
@NonNull | |||||
public Ref getTarget() { | public Ref getTarget() { | ||||
return target; | return target; | ||||
} | } | ||||
@Nullable | |||||
public ObjectId getObjectId() { | public ObjectId getObjectId() { | ||||
return getLeaf().getObjectId(); | return getLeaf().getObjectId(); | ||||
} | } | ||||
@NonNull | |||||
public Storage getStorage() { | public Storage getStorage() { | ||||
return Storage.LOOSE; | return Storage.LOOSE; | ||||
} | } | ||||
@Nullable | |||||
public ObjectId getPeeledObjectId() { | public ObjectId getPeeledObjectId() { | ||||
return getLeaf().getPeeledObjectId(); | return getLeaf().getPeeledObjectId(); | ||||
} | } |
import java.util.List; | import java.util.List; | ||||
import org.eclipse.jgit.lib.Constants; | import org.eclipse.jgit.lib.Constants; | ||||
import org.eclipse.jgit.lib.ObjectId; | |||||
import org.eclipse.jgit.lib.Ref; | import org.eclipse.jgit.lib.Ref; | ||||
import org.eclipse.jgit.lib.Repository; | import org.eclipse.jgit.lib.Repository; | ||||
import org.eclipse.jgit.util.ChangeIdUtil; | import org.eclipse.jgit.util.ChangeIdUtil; | ||||
List<String> commits = new ArrayList<String>(); | List<String> commits = new ArrayList<String>(); | ||||
List<String> others = new ArrayList<String>(); | List<String> others = new ArrayList<String>(); | ||||
for (Ref ref : refsToMerge) { | for (Ref ref : refsToMerge) { | ||||
if (ref.getName().startsWith(Constants.R_HEADS)) | |||||
if (ref.getName().startsWith(Constants.R_HEADS)) { | |||||
branches.add("'" + Repository.shortenRefName(ref.getName()) //$NON-NLS-1$ | branches.add("'" + Repository.shortenRefName(ref.getName()) //$NON-NLS-1$ | ||||
+ "'"); //$NON-NLS-1$ | + "'"); //$NON-NLS-1$ | ||||
else if (ref.getName().startsWith(Constants.R_REMOTES)) | |||||
} else if (ref.getName().startsWith(Constants.R_REMOTES)) { | |||||
remoteBranches.add("'" //$NON-NLS-1$ | remoteBranches.add("'" //$NON-NLS-1$ | ||||
+ Repository.shortenRefName(ref.getName()) + "'"); //$NON-NLS-1$ | + Repository.shortenRefName(ref.getName()) + "'"); //$NON-NLS-1$ | ||||
else if (ref.getName().startsWith(Constants.R_TAGS)) | |||||
} else if (ref.getName().startsWith(Constants.R_TAGS)) { | |||||
tags.add("'" + Repository.shortenRefName(ref.getName()) + "'"); //$NON-NLS-1$ //$NON-NLS-2$ | tags.add("'" + Repository.shortenRefName(ref.getName()) + "'"); //$NON-NLS-1$ //$NON-NLS-2$ | ||||
else if (ref.getName().equals(ref.getObjectId().getName())) | |||||
commits.add("'" + ref.getName() + "'"); //$NON-NLS-1$ //$NON-NLS-2$ | |||||
else | |||||
others.add(ref.getName()); | |||||
} else { | |||||
ObjectId objectId = ref.getObjectId(); | |||||
if (objectId != null && ref.getName().equals(objectId.getName())) { | |||||
commits.add("'" + ref.getName() + "'"); //$NON-NLS-1$ //$NON-NLS-2$ | |||||
} else { | |||||
others.add(ref.getName()); | |||||
} | |||||
} | |||||
} | } | ||||
List<String> listings = new ArrayList<String>(); | List<String> listings = new ArrayList<String>(); |
final PacketLineOut p = statelessRPC ? pckState : pckOut; | final PacketLineOut p = statelessRPC ? pckState : pckOut; | ||||
boolean first = true; | boolean first = true; | ||||
for (final Ref r : want) { | for (final Ref r : want) { | ||||
ObjectId objectId = r.getObjectId(); | |||||
if (objectId == null) { | |||||
continue; | |||||
} | |||||
try { | try { | ||||
if (walk.parseAny(r.getObjectId()).has(REACHABLE)) { | |||||
if (walk.parseAny(objectId).has(REACHABLE)) { | |||||
// We already have this object. Asking for it is | // We already have this object. Asking for it is | ||||
// not a very good idea. | // not a very good idea. | ||||
// | // | ||||
final StringBuilder line = new StringBuilder(46); | final StringBuilder line = new StringBuilder(46); | ||||
line.append("want "); //$NON-NLS-1$ | line.append("want "); //$NON-NLS-1$ | ||||
line.append(r.getObjectId().name()); | |||||
line.append(objectId.name()); | |||||
if (first) { | if (first) { | ||||
line.append(enableCapabilities()); | line.append(enableCapabilities()); | ||||
first = false; | first = false; |
final StringBuilder sb = new StringBuilder(); | final StringBuilder sb = new StringBuilder(); | ||||
ObjectId oldId = rru.getExpectedOldObjectId(); | ObjectId oldId = rru.getExpectedOldObjectId(); | ||||
if (oldId == null) { | if (oldId == null) { | ||||
Ref adv = getRef(rru.getRemoteName()); | |||||
oldId = adv != null ? adv.getObjectId() : ObjectId.zeroId(); | |||||
final Ref advertised = getRef(rru.getRemoteName()); | |||||
oldId = advertised != null ? advertised.getObjectId() : null; | |||||
if (oldId == null) { | |||||
oldId = ObjectId.zeroId(); | |||||
} | |||||
} | } | ||||
sb.append(oldId.name()); | sb.append(oldId.name()); | ||||
sb.append(' '); | sb.append(' '); |
} | } | ||||
} | } | ||||
if (cmd.getType() == ReceiveCommand.Type.DELETE && ref != null | |||||
&& !ObjectId.zeroId().equals(cmd.getOldId()) | |||||
&& !ref.getObjectId().equals(cmd.getOldId())) { | |||||
// Delete commands can be sent with the old id matching our | |||||
// advertised value, *OR* with the old id being 0{40}. Any | |||||
// other requested old id is invalid. | |||||
// | |||||
cmd.setResult(Result.REJECTED_OTHER_REASON, | |||||
JGitText.get().invalidOldIdSent); | |||||
continue; | |||||
if (cmd.getType() == ReceiveCommand.Type.DELETE && ref != null) { | |||||
ObjectId id = ref.getObjectId(); | |||||
if (id == null) { | |||||
id = ObjectId.zeroId(); | |||||
} | |||||
if (!ObjectId.zeroId().equals(cmd.getOldId()) | |||||
&& !id.equals(cmd.getOldId())) { | |||||
// Delete commands can be sent with the old id matching our | |||||
// advertised value, *OR* with the old id being 0{40}. Any | |||||
// other requested old id is invalid. | |||||
// | |||||
cmd.setResult(Result.REJECTED_OTHER_REASON, | |||||
JGitText.get().invalidOldIdSent); | |||||
continue; | |||||
} | |||||
} | } | ||||
if (cmd.getType() == ReceiveCommand.Type.UPDATE) { | if (cmd.getType() == ReceiveCommand.Type.UPDATE) { | ||||
cmd.setResult(Result.REJECTED_OTHER_REASON, JGitText.get().noSuchRef); | cmd.setResult(Result.REJECTED_OTHER_REASON, JGitText.get().noSuchRef); | ||||
continue; | continue; | ||||
} | } | ||||
ObjectId id = ref.getObjectId(); | |||||
if (id == null) { | |||||
// We cannot update unborn branch | |||||
cmd.setResult(Result.REJECTED_OTHER_REASON, | |||||
JGitText.get().cannotUpdateUnbornBranch); | |||||
continue; | |||||
} | |||||
if (!ref.getObjectId().equals(cmd.getOldId())) { | |||||
if (!id.equals(cmd.getOldId())) { | |||||
// A properly functioning client will send the same | // A properly functioning client will send the same | ||||
// object id we advertised. | // object id we advertised. | ||||
// | // |
private void expandFetchTags() throws TransportException { | private void expandFetchTags() throws TransportException { | ||||
final Map<String, Ref> haveRefs = localRefs(); | final Map<String, Ref> haveRefs = localRefs(); | ||||
for (final Ref r : conn.getRefs()) { | for (final Ref r : conn.getRefs()) { | ||||
if (!isTag(r)) | |||||
if (!isTag(r)) { | |||||
continue; | |||||
} | |||||
ObjectId id = r.getObjectId(); | |||||
if (id == null) { | |||||
continue; | continue; | ||||
} | |||||
final Ref local = haveRefs.get(r.getName()); | final Ref local = haveRefs.get(r.getName()); | ||||
if (local == null || !r.getObjectId().equals(local.getObjectId())) | |||||
if (local == null || !id.equals(local.getObjectId())) { | |||||
wantTag(r); | wantTag(r); | ||||
} | |||||
} | } | ||||
} | } | ||||
private void want(final Ref src, final RefSpec spec) | private void want(final Ref src, final RefSpec spec) | ||||
throws TransportException { | throws TransportException { | ||||
final ObjectId newId = src.getObjectId(); | final ObjectId newId = src.getObjectId(); | ||||
if (newId == null) { | |||||
throw new NullPointerException(MessageFormat.format( | |||||
JGitText.get().transportProvidedRefWithNoObjectId, | |||||
src.getName())); | |||||
} | |||||
if (spec.getDestination() != null) { | if (spec.getDestination() != null) { | ||||
final TrackingRefUpdate tru = createUpdate(spec, newId); | final TrackingRefUpdate tru = createUpdate(spec, newId); | ||||
if (newId.equals(tru.getOldObjectId())) | if (newId.equals(tru.getOldObjectId())) |
final Map<String, RemoteRefUpdate> result = new HashMap<String, RemoteRefUpdate>(); | final Map<String, RemoteRefUpdate> result = new HashMap<String, RemoteRefUpdate>(); | ||||
for (final RemoteRefUpdate rru : toPush.values()) { | for (final RemoteRefUpdate rru : toPush.values()) { | ||||
final Ref advertisedRef = connection.getRef(rru.getRemoteName()); | final Ref advertisedRef = connection.getRef(rru.getRemoteName()); | ||||
final ObjectId advertisedOld = (advertisedRef == null ? ObjectId | |||||
.zeroId() : advertisedRef.getObjectId()); | |||||
ObjectId advertisedOld = null; | |||||
if (advertisedRef != null) { | |||||
advertisedOld = advertisedRef.getObjectId(); | |||||
} | |||||
if (advertisedOld == null) { | |||||
advertisedOld = ObjectId.zeroId(); | |||||
} | |||||
if (rru.getNewObjectId().equals(advertisedOld)) { | if (rru.getNewObjectId().equals(advertisedOld)) { | ||||
if (rru.isDelete()) { | if (rru.isDelete()) { |
final HashSet<ObjectId> inWorkQueue = new HashSet<ObjectId>(); | final HashSet<ObjectId> inWorkQueue = new HashSet<ObjectId>(); | ||||
for (final Ref r : want) { | for (final Ref r : want) { | ||||
final ObjectId id = r.getObjectId(); | final ObjectId id = r.getObjectId(); | ||||
if (id == null) { | |||||
throw new NullPointerException(MessageFormat.format( | |||||
JGitText.get().transportProvidedRefWithNoObjectId, r.getName())); | |||||
} | |||||
try { | try { | ||||
final RevObject obj = revWalk.parseAny(id); | final RevObject obj = revWalk.parseAny(id); | ||||
if (obj.has(COMPLETE)) | if (obj.has(COMPLETE)) |