private List<ReceiveCommand> filterCommands(final Result want) { final List<ReceiveCommand> r = new ArrayList<ReceiveCommand>(commands.size()); for (final ReceiveCommand cmd : commands) { if (cmd.getResult() == want) r.add(cmd); } return r; }
private void validateCommands() { for (final ReceiveCommand cmd : commands) { final Ref ref = cmd.getRef(); if (cmd.getResult() != Result.NOT_ATTEMPTED) continue; if (cmd.getType() == ReceiveCommand.Type.DELETE && !isAllowDeletes()) { // Deletes are not supported on this repository. // cmd.setResult(Result.REJECTED_NODELETE); continue; } if (cmd.getType() == ReceiveCommand.Type.CREATE) { if (!isAllowCreates()) { cmd.setResult(Result.REJECTED_NOCREATE); continue; } if (ref != null && !isAllowNonFastForwards()) { // Creation over an existing ref is certainly not going // to be a fast-forward update. We can reject it early. // cmd.setResult(Result.REJECTED_NONFASTFORWARD); continue; } if (ref != null) { // A well behaved client shouldn't have sent us a // create command for a ref we advertised to it. // cmd.setResult( Result.REJECTED_OTHER_REASON, MessageFormat.format(JGitText.get().refAlreadyExists, ref)); continue; } } 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.UPDATE) { if (ref == null) { // The ref must have been advertised in order to be updated. // cmd.setResult(Result.REJECTED_OTHER_REASON, JGitText.get().noSuchRef); continue; } if (!ref.getObjectId().equals(cmd.getOldId())) { // A properly functioning client will send the same // object id we advertised. // cmd.setResult(Result.REJECTED_OTHER_REASON, JGitText.get().invalidOldIdSent); continue; } // Is this possibly a non-fast-forward style update? // RevObject oldObj, newObj; try { oldObj = walk.parseAny(cmd.getOldId()); } catch (IOException e) { cmd.setResult(Result.REJECTED_MISSING_OBJECT, cmd.getOldId().name()); continue; } try { newObj = walk.parseAny(cmd.getNewId()); } catch (IOException e) { cmd.setResult(Result.REJECTED_MISSING_OBJECT, cmd.getNewId().name()); continue; } if (oldObj instanceof RevCommit && newObj instanceof RevCommit) { try { if (!walk.isMergedInto((RevCommit) oldObj, (RevCommit) newObj)) { cmd.setType(ReceiveCommand.Type.UPDATE_NONFASTFORWARD); } } catch (MissingObjectException e) { cmd.setResult(Result.REJECTED_MISSING_OBJECT, e.getMessage()); } catch (IOException e) { cmd.setResult(Result.REJECTED_OTHER_REASON); } } else { cmd.setType(ReceiveCommand.Type.UPDATE_NONFASTFORWARD); } } if (!cmd.getRefName().startsWith(Constants.R_REFS) || !Repository.isValidRefName(cmd.getRefName())) { cmd.setResult(Result.REJECTED_OTHER_REASON, JGitText.get().funnyRefname); } } }
private void checkConnectivity() throws IOException { ObjectIdSubclassMap<ObjectId> baseObjects = null; ObjectIdSubclassMap<ObjectId> providedObjects = null; if (checkReferencedIsReachable) { baseObjects = parser.getBaseObjectIds(); providedObjects = parser.getNewObjectIds(); } parser = null; final ObjectWalk ow = new ObjectWalk(db); ow.setRetainBody(false); if (checkReferencedIsReachable) { ow.sort(RevSort.TOPO); if (!baseObjects.isEmpty()) ow.sort(RevSort.BOUNDARY, true); } for (final ReceiveCommand cmd : commands) { if (cmd.getResult() != Result.NOT_ATTEMPTED) continue; if (cmd.getType() == ReceiveCommand.Type.DELETE) continue; ow.markStart(ow.parseAny(cmd.getNewId())); } for (final ObjectId have : advertisedHaves) { RevObject o = ow.parseAny(have); ow.markUninteresting(o); if (checkReferencedIsReachable && !baseObjects.isEmpty()) { o = ow.peel(o); if (o instanceof RevCommit) o = ((RevCommit) o).getTree(); if (o instanceof RevTree) ow.markUninteresting(o); } } RevCommit c; while ((c = ow.next()) != null) { if (checkReferencedIsReachable // && !c.has(RevFlag.UNINTERESTING) // && !providedObjects.contains(c)) throw new MissingObjectException(c, Constants.TYPE_COMMIT); } RevObject o; while ((o = ow.nextObject()) != null) { if (o.has(RevFlag.UNINTERESTING)) continue; if (checkReferencedIsReachable) { if (providedObjects.contains(o)) continue; else throw new MissingObjectException(o, o.getType()); } if (o instanceof RevBlob && !db.hasObject(o)) throw new MissingObjectException(o, Constants.TYPE_BLOB); } if (checkReferencedIsReachable) { for (ObjectId id : baseObjects) { o = ow.parseAny(id); if (!o.has(RevFlag.UNINTERESTING)) throw new MissingObjectException(o, o.getType()); } } }
private void sendStatusReport(final boolean forClient, final Reporter out) throws IOException { if (unpackError != null) { out.sendString("unpack error " + unpackError.getMessage()); if (forClient) { for (final ReceiveCommand cmd : commands) { out.sendString("ng " + cmd.getRefName() + " n/a (unpacker error)"); } } return; } if (forClient) out.sendString("unpack ok"); for (final ReceiveCommand cmd : commands) { if (cmd.getResult() == Result.OK) { if (forClient) out.sendString("ok " + cmd.getRefName()); continue; } final StringBuilder r = new StringBuilder(); r.append("ng "); r.append(cmd.getRefName()); r.append(" "); switch (cmd.getResult()) { case NOT_ATTEMPTED: r.append("server bug; ref not processed"); break; case REJECTED_NOCREATE: r.append("creation prohibited"); break; case REJECTED_NODELETE: r.append("deletion prohibited"); break; case REJECTED_NONFASTFORWARD: r.append("non-fast forward"); break; case REJECTED_CURRENT_BRANCH: r.append("branch is currently checked out"); break; case REJECTED_MISSING_OBJECT: if (cmd.getMessage() == null) r.append("missing object(s)"); else if (cmd.getMessage().length() == Constants.OBJECT_ID_STRING_LENGTH) r.append("object " + cmd.getMessage() + " missing"); else r.append(cmd.getMessage()); break; case REJECTED_OTHER_REASON: if (cmd.getMessage() == null) r.append("unspecified reason"); else r.append(cmd.getMessage()); break; case LOCK_FAILURE: r.append("failed to lock"); break; case OK: // We shouldn't have reached this case (see 'ok' case above). continue; } out.sendString(r.toString()); } }