private void execute(final ReceiveCommand cmd) { try { final RefUpdate ru = db.updateRef(cmd.getRefName()); ru.setRefLogIdent(getRefLogIdent()); switch (cmd.getType()) { case DELETE: if (!ObjectId.zeroId().equals(cmd.getOldId())) { // We can only do a CAS style delete if the client // didn't bork its delete request by sending the // wrong zero id rather than the advertised one. // ru.setExpectedOldObjectId(cmd.getOldId()); } ru.setForceUpdate(true); status(cmd, ru.delete(walk)); break; case CREATE: case UPDATE: case UPDATE_NONFASTFORWARD: ru.setForceUpdate(isAllowNonFastForwards()); ru.setExpectedOldObjectId(cmd.getOldId()); ru.setNewObjectId(cmd.getNewId()); ru.setRefLogMessage("push", true); status(cmd, ru.update(walk)); break; } } catch (IOException err) { cmd.setResult( Result.REJECTED_OTHER_REASON, MessageFormat.format(JGitText.get().lockError, err.getMessage())); } }
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 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 boolean needPack() { for (final ReceiveCommand cmd : commands) { if (cmd.getType() != ReceiveCommand.Type.DELETE) return true; } return false; }