break;
case FAST_FORWARD:
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());
break;
case CHECKOUT_CONFLICT:
if (all) {
Map<String, Ref> allRefs = db.getRefDatabase().getRefs(ALL);
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 {
if (verify && commits.size() > 1) {
cannotStoreObjects=cannot store objects
cannotResolveUniquelyAbbrevObjectId=Could not resolve uniquely the abbreviated object ID
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.
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.
transportExceptionMissingAssumed=Missing assumed {0}
transportExceptionReadRef=read {0}
transportNeedsRepository=Transport needs repository
+transportProvidedRefWithNoObjectId=Transport provided ref {0} with no object id
transportProtoAmazonS3=Amazon S3
transportProtoBundleFile=Git Bundle File
transportProtoFTP=FTP
}
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.Constants;
import org.eclipse.jgit.lib.NullProgressMonitor;
+import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ProgressMonitor;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefUpdate;
}
if (head == null || head.getObjectId() == null)
- return; // throw exception?
+ return; // TODO throw exception?
if (head.getName().startsWith(Constants.R_HEADS)) {
final RefUpdate newHead = clonedRepo.updateRef(Constants.HEAD);
private Ref findBranchToCheckout(FetchResult result) {
final Ref idHEAD = result.getAdvertisedRef(Constants.HEAD);
- if (idHEAD == null)
+ ObjectId headId = idHEAD != null ? idHEAD.getObjectId() : null;
+ if (headId == null) {
return null;
+ }
Ref master = result.getAdvertisedRef(Constants.R_HEADS
+ Constants.MASTER);
- if (master != null && master.getObjectId().equals(idHEAD.getObjectId()))
+ ObjectId objectId = master != null ? master.getObjectId() : null;
+ if (headId.equals(objectId)) {
return master;
+ }
Ref foundBranch = null;
for (final Ref r : result.getAdvertisedRefs()) {
final String n = r.getName();
if (!n.startsWith(Constants.R_HEADS))
continue;
- if (r.getObjectId().equals(idHEAD.getObjectId())) {
+ if (headId.equals(r.getObjectId())) {
foundBranch = r;
break;
}
lastStepWasForward = newHead != null;
if (!lastStepWasForward) {
ObjectId headId = getHead().getObjectId();
+ // getHead() checks for null
+ assert headId != null;
if (!AnyObjectId.equals(headId, newParents.get(0)))
checkoutCommit(headId.getName(), newParents.get(0));
return;
ObjectId headId = getHead().getObjectId();
+ // getHead() checks for null
+ assert headId != null;
String head = headId.getName();
String currentCommits = rebaseState.readFile(CURRENT_COMMIT);
for (String current : currentCommits.split("\n")) //$NON-NLS-1$
Ref head = getHead();
- String headName = getHeadName(head);
ObjectId headId = head.getObjectId();
- if (headId == null)
+ if (headId == null) {
throw new RefNotFoundException(MessageFormat.format(
JGitText.get().refNotResolved, Constants.HEAD));
+ }
+ String headName = getHeadName(head);
RevCommit headCommit = walk.lookupCommit(headId);
RevCommit upstream = walk.lookupCommit(upstreamCommit.getId());
private static String getHeadName(Ref head) {
String headName;
- if (head.isSymbolic())
+ if (head.isSymbolic()) {
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;
}
/***/ public String cannotStoreObjects;
/***/ public String cannotResolveUniquelyAbbrevObjectId;
/***/ public String cannotUnloadAModifiedTree;
+ /***/ public String cannotUpdateUnbornBranch;
/***/ public String cannotWorkWithOtherStagesThanZeroRightNow;
/***/ public String cannotWriteObjectsPath;
/***/ public String canOnlyCherryPickCommitsWithOneParent;
/***/ public String transportProtoSFTP;
/***/ public String transportProtoSSH;
/***/ public String transportProtoTest;
+ /***/ public String transportProvidedRefWithNoObjectId;
/***/ public String transportSSHRetryInterrupt;
/***/ public String treeEntryAlreadyExists;
/***/ public String treeFilterMarkerTooManyFilters;
reject(cmds);
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.Map;
import java.util.Map.Entry;
+import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;
return false;
return r1.getTarget().getName().equals(r2.getTarget().getName());
} else {
- if (r2.isSymbolic())
+ if (r2.isSymbolic()) {
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.AtomicReference;
+import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.errors.InvalidObjectIdException;
import org.eclipse.jgit.errors.LockFailedException;
import org.eclipse.jgit.errors.MissingObjectException;
*/
private Ref peeledPackedRef(Ref f)
throws MissingObjectException, IOException {
- if (f.getStorage().isPacked() && f.isPeeled())
+ if (f.getStorage().isPacked() && f.isPeeled()) {
return f;
- if (!f.isPeeled())
+ }
+ if (!f.isPeeled()) {
f = peel(f);
- if (f.getPeeledObjectId() != null)
+ }
+ ObjectId peeledObjectId = f.getPeeledObjectId();
+ if (peeledObjectId != null) {
return new ObjectIdRef.PeeledTag(PACKED, f.getName(),
- f.getObjectId(), f.getPeeledObjectId());
- else
+ f.getObjectId(), peeledObjectId);
+ } else {
return new ObjectIdRef.PeeledNonTag(PACKED, f.getName(),
f.getObjectId());
+ }
}
void log(final RefUpdate update, final String msg, final boolean deref)
try {
id = ObjectId.fromString(buf, 0);
if (ref != null && !ref.isSymbolic()
- && ref.getTarget().getObjectId().equals(id)) {
+ && id.equals(ref.getTarget().getObjectId())) {
assert(currentSnapshot != null);
currentSnapshot.setClean(otherSnapshot);
return ref;
implements LooseRef {
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);
this.snapShot = snapshot;
}
implements LooseRef {
private final FileSnapshot snapShot;
- LooseNonTag(FileSnapshot snapshot, String refName, ObjectId id) {
+ LooseNonTag(FileSnapshot snapshot, @NonNull String refName,
+ @NonNull ObjectId id) {
super(LOOSE, refName, id);
this.snapShot = snapshot;
}
implements LooseRef {
private FileSnapshot snapShot;
- LooseUnpeeled(FileSnapshot snapShot, String refName, ObjectId id) {
+ LooseUnpeeled(FileSnapshot snapShot, @NonNull String refName,
+ @NonNull ObjectId id) {
super(LOOSE, refName, id);
this.snapShot = 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) {
- if (newLeaf.getPeeledObjectId() != null)
+ ObjectId peeledObjectId = newLeaf.getPeeledObjectId();
+ ObjectId objectId = getObjectId();
+ if (peeledObjectId != null) {
return new LoosePeeledTag(snapShot, getName(),
- getObjectId(), newLeaf.getPeeledObjectId());
- else
+ objectId, peeledObjectId);
+ } else {
return new LooseNonTag(snapShot, getName(),
- getObjectId());
+ objectId);
+ }
}
}
LooseRef {
private final FileSnapshot snapShot;
- LooseSymbolicRef(FileSnapshot snapshot, String refName, Ref target) {
+ LooseSymbolicRef(FileSnapshot snapshot, @NonNull String refName,
+ @NonNull Ref target) {
super(refName, target);
this.snapShot = snapshot;
}
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}. */
public abstract class ObjectIdRef implements Ref {
/** Any reference whose peeled value is not yet known. */
* @param name
* name of this ref.
* @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);
}
+ @Nullable
public ObjectId getPeeledObjectId() {
return null;
}
* @param p
* 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);
peeledObjectId = p;
}
+ @NonNull
public ObjectId getPeeledObjectId() {
return peeledObjectId;
}
* @param name
* name of this ref.
* @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);
}
+ @Nullable
public ObjectId getPeeledObjectId() {
return null;
}
* @param name
* name of this ref.
* @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.storage = st;
this.objectId = id;
}
+ @NonNull
public String getName() {
return name;
}
return false;
}
+ @NonNull
public Ref getLeaf() {
return this;
}
+ @NonNull
public Ref getTarget() {
return this;
}
+ @Nullable
public ObjectId getObjectId() {
return objectId;
}
+ @NonNull
public Storage getStorage() {
return storage;
}
+ @NonNull
@Override
public String toString() {
StringBuilder r = new StringBuilder();
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.
* <p>
*
* @return name of this ref.
*/
+ @NonNull
public String getName();
/**
*
* @return the reference that actually stores the ObjectId value.
*/
+ @NonNull
public abstract Ref getLeaf();
/**
*
* @return the target reference, or {@code this}.
*/
+ @NonNull
public abstract Ref getTarget();
/**
* 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();
/**
* 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
- * 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();
/**
*
* @return type of ref.
*/
+ @NonNull
public abstract Storage getStorage();
}
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(r.getName());
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(r.getName());
w.write("^{}\n"); //$NON-NLS-1$
if (r.getStorage() != Ref.Storage.PACKED)
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(r.getName());
w.write('\n');
- if (r.getPeeledObjectId() != null) {
+ ObjectId peeledObjectId = r.getPeeledObjectId();
+ if (peeledObjectId != null) {
w.write('^');
- r.getPeeledObjectId().copyTo(tmp, w);
+ peeledObjectId.copyTo(tmp, w);
w.write('\n');
}
}
@Nullable
public String getFullBranch() throws IOException {
Ref head = getRef(Constants.HEAD);
- if (head == null)
+ if (head == null) {
return null;
- if (head.isSymbolic())
+ }
+ if (head.isSymbolic()) {
return head.getTarget().getName();
- if (head.getObjectId() != null)
- return head.getObjectId().name();
+ }
+ ObjectId objectId = head.getObjectId();
+ if (objectId != null) {
+ return objectId.name();
+ }
return null;
}
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}.
* <p>
* @param target
* 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.target = target;
}
+ @NonNull
public String getName() {
return name;
}
return true;
}
+ @NonNull
public Ref getLeaf() {
Ref dst = getTarget();
while (dst.isSymbolic())
return dst;
}
+ @NonNull
public Ref getTarget() {
return target;
}
+ @Nullable
public ObjectId getObjectId() {
return getLeaf().getObjectId();
}
+ @NonNull
public Storage getStorage() {
return Storage.LOOSE;
}
+ @Nullable
public ObjectId getPeeledObjectId() {
return getLeaf().getPeeledObjectId();
}
import java.util.List;
import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.util.ChangeIdUtil;
List<String> commits = new ArrayList<String>();
List<String> others = new ArrayList<String>();
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$
+ "'"); //$NON-NLS-1$
-
- else if (ref.getName().startsWith(Constants.R_REMOTES))
+ } else if (ref.getName().startsWith(Constants.R_REMOTES)) {
remoteBranches.add("'" //$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$
-
- 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>();
final PacketLineOut p = statelessRPC ? pckState : pckOut;
boolean first = true;
for (final Ref r : want) {
+ ObjectId objectId = r.getObjectId();
+ if (objectId == null) {
+ continue;
+ }
try {
- if (walk.parseAny(r.getObjectId()).has(REACHABLE)) {
+ if (walk.parseAny(objectId).has(REACHABLE)) {
// We already have this object. Asking for it is
// not a very good idea.
//
final StringBuilder line = new StringBuilder(46);
line.append("want "); //$NON-NLS-1$
- line.append(r.getObjectId().name());
+ line.append(objectId.name());
if (first) {
line.append(enableCapabilities());
first = false;
final StringBuilder sb = new StringBuilder();
ObjectId oldId = rru.getExpectedOldObjectId();
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(' ');
}
}
- 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) {
cmd.setResult(Result.REJECTED_OTHER_REASON, JGitText.get().noSuchRef);
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
// object id we advertised.
//
private void expandFetchTags() throws TransportException {
final Map<String, Ref> haveRefs = localRefs();
for (final Ref r : conn.getRefs()) {
- if (!isTag(r))
+ if (!isTag(r)) {
+ continue;
+ }
+ ObjectId id = r.getObjectId();
+ if (id == null) {
continue;
+ }
final Ref local = haveRefs.get(r.getName());
- if (local == null || !r.getObjectId().equals(local.getObjectId()))
+ if (local == null || !id.equals(local.getObjectId())) {
wantTag(r);
+ }
}
}
private void want(final Ref src, final RefSpec spec)
throws TransportException {
final ObjectId newId = src.getObjectId();
+ if (newId == null) {
+ throw new NullPointerException(MessageFormat.format(
+ JGitText.get().transportProvidedRefWithNoObjectId,
+ src.getName()));
+ }
if (spec.getDestination() != null) {
final TrackingRefUpdate tru = createUpdate(spec, newId);
if (newId.equals(tru.getOldObjectId()))
final Map<String, RemoteRefUpdate> result = new HashMap<String, RemoteRefUpdate>();
for (final RemoteRefUpdate rru : toPush.values()) {
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.isDelete()) {
final HashSet<ObjectId> inWorkQueue = new HashSet<ObjectId>();
for (final Ref r : want) {
final ObjectId id = r.getObjectId();
+ if (id == null) {
+ throw new NullPointerException(MessageFormat.format(
+ JGitText.get().transportProvidedRefWithNoObjectId, r.getName()));
+ }
try {
final RevObject obj = revWalk.parseAny(id);
if (obj.has(COMPLETE))