예제 #1
0
  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()));
    }
  }
예제 #2
0
  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);
    }
  }
예제 #3
0
  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);
      }
    }
  }
예제 #4
0
  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());
    }
  }