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 recvCommands() throws IOException { for (; ; ) { String line; try { line = pckIn.readStringRaw(); } catch (EOFException eof) { if (commands.isEmpty()) return; throw eof; } if (line == PacketLineIn.END) break; if (commands.isEmpty()) { final int nul = line.indexOf('\0'); if (nul >= 0) { for (String c : line.substring(nul + 1).split(" ")) enabledCapablities.add(c); line = line.substring(0, nul); } } if (line.length() < 83) { final String m = JGitText.get().errorInvalidProtocolWantedOldNewRef; sendError(m); throw new PackProtocolException(m); } final ObjectId oldId = ObjectId.fromString(line.substring(0, 40)); final ObjectId newId = ObjectId.fromString(line.substring(41, 81)); final String name = line.substring(82); final ReceiveCommand cmd = new ReceiveCommand(oldId, newId, name); if (name.equals(Constants.HEAD)) { cmd.setResult(Result.REJECTED_CURRENT_BRANCH); } else { cmd.setRef(refs.get(cmd.getRefName())); } commands.add(cmd); } }
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 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()); } }